← docs
docs · v0.1

Agentic Planner — Three Sub-Agents over Markdown

v0.1 · last updated 2026-07draft

DRAFT — pending Harsh's verification.

This page documents the architecture of a personal productivity system the author runs on Claude Code: a planner where Skills are the procedures and markdown files are the database. It is the same move the build-triage and code-search pages describe — codify an expert's implicit procedure into something a model executes deterministically — applied to one's own work instead of to a CI system. No personal task contents, people, or dates from the live data appear here; only the structure.

1. The thesis: skills as procedures, markdown as the database

Most productivity tools store your work in a proprietary database and put the procedure for working with it in your head — or in a UI you can't version, inspect, or replay. The planner inverts both halves:

The model supplies only the reasoning glue between file reads and writes — deciding which skill fires next, given what the last one returned. Swap the model and the procedures survive; swap the procedures and the model has nothing to run. The skill files are the part worth keeping.

This is the same layering as the build-triage system's "tools give capability, the skill gives judgment" — except here the "tool" surface is the filesystem itself, and the "API" is the shape of the markdown.

2. Three sub-agents, one shared conventions reference

The system is organized as three sub-agents, each a distinct concern with its own context file under .claude/agents/:

Sub-agentConcernOwns
PlannerStrategicProject decomposition, effort estimation, routing
SchedulerTacticalTime allocation, capacity, calendar, daily plans
ReviewerOperationalExecution tracking, sync, reporting, cleanup
flowchart TD
  router["CLAUDE.md (router)\nwhich agent owns this /command?"]
  planner["Planner\nstrategic"]
  scheduler["Scheduler\ntactical"]
  reviewer["Reviewer\noperational"]
  conventions["planner-conventions\nshared reference, loaded by ALL agents"]

  router --> planner
  router --> scheduler
  router --> reviewer
  planner --> conventions
  scheduler --> conventions
  reviewer --> conventions

All three agents load a single shared reference, planner-conventions, before acting. It is the contract every agent honors so they don't drift apart: the project section format, the task-sync rule, the scheduling blocks, the cleanup policy, and a "context sufficiency" rule (a project's ### Context must be enough to pick the work up cold). One reference, loaded by all three, is what makes them interoperable sub-agents rather than three independent scripts.

3. The thin-router CLAUDE.md pattern

CLAUDE.md is deliberately thin. It does not contain procedures — it routes. A small command-pattern table maps each /skill-name to the agent that owns it:

Command patternAgent
/plan-project, /add-task, /process-inboxPlanner
/view, /plan-week, /plan-day, /rescheduleScheduler
/review-day, /sprint-cleanup, /statusReviewer

Routing is a single dispatch decision; the procedure lives in the skill, not in the router. Keeping the router thin means the router rarely needs to change when a skill's internals do — the same separation as a reverse proxy versus the services behind it.

Some commands are multi-agent workflows — the router chains agents rather than calling one:

The router also defines a model-tier policy that is the most transferable idea here for anyone building multi-agent systems. Daily and tactical skills — /view, /plan-day, /review-day, /reschedule, /process-inbox — are executor-grade: run them on a cheap model, because the deterministic scanners carry the math and the judgment is light. The high-stakes skills — /plan-week and /plan-project — are frontier-grade: run them on the best model, because portfolio-level decomposition and estimation are where judgment matters most.

flowchart LR
  executorReason["deterministic scanners carry the math\njudgment is light"] --> executor["executor-grade · cheap model\n/view · /plan-day · /review-day\n/reschedule · /process-inbox"]
  frontierReason["portfolio decomposition\nestimation · slips = judgment"] --> frontier["frontier-grade · best model\n/plan-week · /plan-project"]

Above the three sub-agents sits an advisor tier — a frontier-judgment agent called only at escalation points: a Slip Protocol displacement, a contested backlog call, over-capacity arbitration, or an adapt trade-off. The advisor receives a distilled brief, returns a recommendation, and never edits files. It is judgment-on-demand, quarantined from write access — the model-tier instinct pushed one rung further: keep the expensive reasoning out of the hot path and out of the data path.

Reusable pattern: route thin, store the procedure in the skill, and assign models by cost tier — cheap models for tactical execution, frontier models for judgment, and an advisory tier that recommends but never writes. The router is the cheapest file to maintain; make it do only routing.

CLAUDE.md also declares a small set of global rules that override individual skills: the task-sync invariant, the Sunday-only cleanup policy, the "due dates are computed, not invented" rule, and backlog isolation (each detailed in §4). Global rules are the cross-cutting constraints the router enforces so the three agents can't violate them independently.

4. The data model: sprint, inbox, backlog, three themes

All personal data lives in data/, which is gitignored. A data-template/ directory ships the empty skeleton; after cloning you run cp -r data-template data to get the expected structure with empty files. The template makes the system separable: data/ can be symlinked to an external private repo or a synced folder, so the procedures (committed, public) and the personal data (gitignored, private) never share a history.

data/
  weekly-sprint.md          # current week — daily task assignments
  inbox.md                  # incoming instructions to route
  backlog.md                # parked projects — planning sessions only
  personal/
    projects.md   recurring.md   habits.md
  work/
    projects.md   recurring.md
  wealth-finances/
    projects.md   recurring.md

Three life themes. Projects and recurring tasks are partitioned into three themes — the partition is structural, not cosmetic, because the scheduler balances capacity across themes rather than letting one dominate:

ThemeScope
personalTrips, errands, side projects, vehicle maintenance, events
workEngineering projects, migrations, tooling, meetings
wealth-financesTaxes, investments, insurance, estate planning, banking

Project format. Each project is an H2 section in its theme's projects.md with a fixed shape — Status, Priority, Timeline, Context, Tasks, Notes. The ### Context field is mandatory and must be self-contained enough to resume the work cold; the shared conventions reference enforces this. Timelines are typed: (fixed) dates are externally imposed and never move; (derived) dates are computed by the planner from effort and portfolio capacity, and move only via the Slip Protocol.

Weekly sprint. weekly-sprint.md holds the current week, organized by day into time blocks:

BlockWindowPurpose
Morning7:30a–9:30aHabits only (gym, reading)
Day10:30a–4:30pCore tasks (max 6 per day, not counting habits)
Evening6:00p–8:00pBuffer / spillover (starts empty)
Night9:00p–9:30pLight tasks (emails, drawing)

Weekends collapse to a single Day block with no time structure. Protected gaps — transitions and free time — are never scheduled.

Inbox routing. inbox.md collects incoming instructions; /process-inbox routes each item to the correct project, recurring, or habit file (and is the only skill that routes a notes channel into planner files). The inbox is the single ingest point so the rest of the system only ever reads structured files.

Backlog isolation. Inactive projects don't linger in theme files — they are parked to backlog.md with no timeline and a Review-by date. Day-to-day skills never read the backlog; only planning sessions (/plan-week index scan, /sprint-cleanup review) and fallback lookups touch it. Isolating parked work keeps active project files clean and stops stale timelines from polluting capacity calculations.

Key rules enforced across the data model:

  1. Task sync — marking a task complete in the sprint immediately updates the same task in the corresponding projects.md. Both stay in sync at all times.
  2. Sunday-only cleanup — completed tasks are removed only during /sprint-cleanup, never ad-hoc.
  3. 6-task limit — max six core tasks per day, excluding habits.
  4. Computed due dates — no externally imposed date yields a (derived) timeline from capacity; slips follow the Slip Protocol (hold the date, then move with a forward-impact check on upcoming sprints — never a reflexive "+1 week").

5. Skills catalog

Skills are invoked as /skill-name [arguments]. The catalog, grouped by the agent that owns each:

Planner agent (strategic)

SkillPurpose
/plan-projectBreak down a project into atomic tasks, estimate effort, schedule into the sprint, adapt mid-execution
/add-taskQuick-add a task to a project and optionally to the sprint
/process-inboxRoute inbox items to the correct project/recurring/habit files

Scheduler agent (tactical)

SkillPurpose
/viewRead-only sprint display — today, a specific day, or the full week
/plan-weekFull weekly sprint planning with capacity validation and theme balancing
/plan-dayPlan or replan a specific day
/rescheduleMove a task between days with cascade awareness

Reviewer agent (operational)

SkillPurpose
/review-dayDaily review with drift detection, smart carry-overs, status/overdue/deadline queries
/sprint-cleanupSunday cleanup — sync verification, weekly report, remove completed, git commit

Shared reference

ReferencePurpose
planner-conventionsProject format, sync rules, scheduling blocks, cleanup policy, context sufficiency

Three skills are worth a closer look because they carry the system's load-bearing judgment:

Reusable pattern: keep the skill thin and put the parameters (block windows, effort sizes, capacity) in a sibling reference file the skill loads. The skill is the procedure; the reference is the policy. You can retune the policy without touching the procedure.

6. What it demonstrates — turning judgment into re-runnable procedures

The planner is the cleanest instance of the pattern this whole site exists to show: an expert's judgment, encoded as procedures a model can re-run deterministically. The judgment lives in the skill files and the reference files — the signal→action logic of which task next given the last result, the T-shirt effort taxonomy, the Slip Protocol, the capacity-balanced allocation — not in the model's weights and not in a one-off prompt. The model supplies the glue; the procedures are the asset.

Three things make it re-runnable rather than a clever one-off:

The same architecture that triages a build failure or searches 120 repos is here pointed at the author's own week — and it works for the same reason: procedures over prompts, structured state over free text, and a model tiered by the cost of its judgment.

Honest gaps and source discrepancies

A few discrepancies between the two source documents are flagged here for Harsh to reconcile before this page leaves draft:

Sources

This page was distilled from the planner repository's README.md and CLAUDE.md, plus the directory listing of its .claude/skills/ folder (names only). No skill-definition files, reference files (scheduling-rules.md, effort-guide.md, planner-conventions/SKILL.md), agent-context files, or anything under data/ were opened — so every claim above traces to the two documents and the folder names. No personal task contents, people's names, or dates from the live data appear; only the structure. One personal email address in CLAUDE.md was deliberately omitted (a known discrepancy to resolve before publishing).