Agentic Planner — Three Sub-Agents over Markdown
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 database is a set of plain markdown files in a
data/directory: a weekly sprint, themed project lists, a recurring-tasks register, a habits file, an inbox, and a backlog. Nothing else. The state of your work is human-readable text you candiff,git log, and edit by hand. - The procedures are Claude Skills
— structured markdown runbooks that tell the model how to plan, schedule,
review, and adapt your work. You invoke them with
/skill-nameslash commands. A skill is a version-controlled procedure, not a prompt you retype.
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-agent | Concern | Owns |
|---|---|---|
| Planner | Strategic | Project decomposition, effort estimation, routing |
| Scheduler | Tactical | Time allocation, capacity, calendar, daily plans |
| Reviewer | Operational | Execution 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
- Planner — strategic decomposition and estimation. Breaks a project into
atomic tasks, estimates effort (T-shirt sized), and schedules tasks into the
sprint. Also handles quick task adds and inbox routing. Its context file
(
planner-context.md) carries the project-thinking, decomposition, and estimation lens. - Scheduler — capacity and time allocation. Builds the weekly sprint with
capacity validation and theme balancing, plans or replans individual days,
and moves tasks between days with cascade awareness. Its context file
(
scheduler-context.md) carries the time-allocation, capacity, and calendar lens. - Reviewer — execution tracking and sync. Runs daily reviews with drift
detection and smart carry-overs, answers status/overdue/deadline queries, and
performs the Sunday cleanup that syncs state, drops completed work, and
commits. Its context file (
reviewer-context.md) carries the execution-tracking, sync, and reporting lens.
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 pattern | Agent |
|---|---|
/plan-project, /add-task, /process-inbox | Planner |
/view, /plan-week, /plan-day, /reschedule | Scheduler |
/review-day, /sprint-cleanup, /status | Reviewer |
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:
/plan-week→ Planner scans projects → Scheduler builds the week./process-inbox→ Planner routes items → Scheduler (only if a sprint update is needed)./add-taskwith the sprint flag → Planner adds to the project → Scheduler adds to the sprint.
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:
| Theme | Scope |
|---|---|
personal | Trips, errands, side projects, vehicle maintenance, events |
work | Engineering projects, migrations, tooling, meetings |
wealth-finances | Taxes, 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:
| Block | Window | Purpose |
|---|---|---|
| Morning | 7:30a–9:30a | Habits only (gym, reading) |
| Day | 10:30a–4:30p | Core tasks (max 6 per day, not counting habits) |
| Evening | 6:00p–8:00p | Buffer / spillover (starts empty) |
| Night | 9:00p–9:30p | Light 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:
- 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. - Sunday-only cleanup — completed tasks are removed only during
/sprint-cleanup, never ad-hoc. - 6-task limit — max six core tasks per day, excluding habits.
- 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)
| Skill | Purpose |
|---|---|
/plan-project | Break down a project into atomic tasks, estimate effort, schedule into the sprint, adapt mid-execution |
/add-task | Quick-add a task to a project and optionally to the sprint |
/process-inbox | Route inbox items to the correct project/recurring/habit files |
Scheduler agent (tactical)
| Skill | Purpose |
|---|---|
/view | Read-only sprint display — today, a specific day, or the full week |
/plan-week | Full weekly sprint planning with capacity validation and theme balancing |
/plan-day | Plan or replan a specific day |
/reschedule | Move a task between days with cascade awareness |
Reviewer agent (operational)
| Skill | Purpose |
|---|---|
/review-day | Daily review with drift detection, smart carry-overs, status/overdue/deadline queries |
/sprint-cleanup | Sunday cleanup — sync verification, weekly report, remove completed, git commit |
Shared reference
| Reference | Purpose |
|---|---|
planner-conventions | Project 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:
-
/view— the read-only window into the sprint. It displays today, a specific day, or the full week. Because it only reads, it is the cheapest skill to run and the one called most often; it is also the skill that makes the system legible — the database is always one slash command away from a structured view, never a manual file-open. -
/plan-week— the weekly planning skill. It runs as a multi-agent workflow (Planner scans projects → Scheduler builds the week) and is backed by ascheduling-rules.mdreference that encodes the scheduling primitives: time blocks, energy types, and capacity. It validates capacity and balances themes, so a week's plan is the output of a constrained allocation, not a wish list. Its rules are parameterized — the block windows and the six-task limit live in the reference, not hardcoded in the skill. -
/plan-project— the project-planning skill, backed by aneffort-guide.mdreference for T-shirt-sized effort estimation:[XS]15 min,[S]30 min,[M]1 hr,[L]2 hr,[XL]4 hr+ (must decompose). Uncertain estimates carry a?suffix ([M?]). Daily capacity is roughly six hours. The T-shirt sizes make estimation composable — a day is a budget of six hours filled with sized tasks — and the?marker makes calibration honest: uncertainty is a first-class field, not hidden in prose.
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 database is plain markdown, so every state is inspectable,
diffable, and editable by hand — the model is never the only writer, and a
bad run is a
git revert, not a corrupted database. - The procedures are version-controlled skills, so a better decomposition or estimation heuristic is a commit, not a retraining.
- The model-tier policy matches cost to stakes, so the cheap tactical work stays cheap and the expensive judgment is spent only where it earns its keep — and the advisor tier quarantines the most expensive reasoning away from the write path.
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:
- Skills count. The skills directory contains 13 skill folders, but the
README documents 10. The three present-but-undocumented are
drift-guardian,validate-planner, andwealth-intelligence. The CLAUDE.md model policy references/drift-guardianas a daily/tactical (executor-grade) skill, so it is in active use but absent from the README's catalog and file tree. /statusrouting. CLAUDE.md routes/statusto the Reviewer agent, but nostatusskill exists in the directory and the README's Reviewer table lists only/review-dayand/sprint-cleanup. It may be an alias, a removed skill, or a planned one — confirm.- No usage data. Neither source records how long the system has been in
use, how many sprints have been planned, or any measure of planning
accuracy or carry-over drift. A metrics-backed version of this story would
need those pulled from the live
data/history; they are not in the source material, and nothing here invents them.
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).