From c680c91f5b17ffda2a90b76c67e2a1d9701621d4 Mon Sep 17 00:00:00 2001 From: Brummel Date: Mon, 11 May 2026 12:12:17 +0200 Subject: [PATCH] spec: plan-recon subagent for planner --- docs/specs/2026-05-11-plan-recon-subagent.md | 324 +++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 docs/specs/2026-05-11-plan-recon-subagent.md diff --git a/docs/specs/2026-05-11-plan-recon-subagent.md b/docs/specs/2026-05-11-plan-recon-subagent.md new file mode 100644 index 0000000..d7d86b4 --- /dev/null +++ b/docs/specs/2026-05-11-plan-recon-subagent.md @@ -0,0 +1,324 @@ +# Plan-recon subagent — Design Spec + +**Date:** 2026-05-11 +**Status:** Draft — awaiting user spec review +**Authors:** Brummel (orchestrator) + Claude + +## Goal + +Reduce Boss-context cost in the `planner` skill by moving the +read-heavy file-structure-mapping phase out of the Boss and into a +dedicated read-only subagent. Leave design judgement (task +decomposition, step granularity, cross-task consistency) in the +Boss. Brainstorm remains dialog-driven and gets no dedicated agent; +it can dispatch the same recon agent ad-hoc when needed. + +The orchestrator-refactor milestone (`or.1`, 2026-05-11) showed that +splitting the per-task review loop into a sub-context pays back in +Boss-token budget. The same principle applies here, but more +narrowly: only the recon phase is delegated, because that is the +only phase whose output collapses cleanly into a small structured +summary. + +## Architecture + +Today, both `brainstorm` and `planner` run entirely in the Boss +context. Reading the per-skill SKILL.md files makes the breakdown +explicit: + +- `brainstorm` is dialog-driven across nine steps. Steps 1 (project + context), 6 (write spec), and 7 (self-review) carry Read/Write + volume; everything else is user Q&A or trivial. +- `planner` is dialog-light but read- and write-heavy. Step 2 (file + structure mapping) and Step 3 (write tasks) carry the volume. + +Of those phases, only one has the right shape for a subagent: + +| Phase | Why it does (not) delegate | +|---|---| +| brainstorm Step 1 — project context | Read volume is moderate; what is relevant becomes clear only mid-dialogue. A subagent dispatched once-and-for-all operates on a partial picture and re-reads what the Boss must read anyway to lead Q&A. | +| brainstorm Step 6 — write spec | Spec writing is dialog kondensation. The Boss has the live conversation; handing it to a subagent means handing over the transcript, not saving tokens. | +| planner Step 2 — file structure mapping | Read-heavy (5–15k Boss tokens on a typical milestone), produces a compact structured summary (~500 tokens). High delegation ratio. Decomposition-independent: the Boss can run Steps 3–8 on the recon's output. | +| planner Step 3 — write tasks | Task decomposition IS the design work. Not delegable; the Boss must hold the cross-task picture to keep types, paths, and step granularity consistent. | + +This spec ships one new subagent — `ailang-plan-recon` — and one +SKILL.md edit (`planner` Step 2). Nothing about `brainstorm` ships. + +## Components + +### `skills/planner/agents/ailang-plan-recon.md` (NEW) + +Read-only code-and-doc-recon agent. The agent's job is: take the +parent spec and an iteration scope, walk the codebase, and return a +file-map that names every existing path, line range, function, and +type the iteration will touch, plus any anchors that DO NOT yet +exist but the spec implies. + +| Field | Value | +|---|---| +| Tools | `Read, Glob, Grep, Bash` (Bash for read-only inspection — `git log`, `git grep`; never to edit) | +| Dispatched by | `planner` (primary); `brainstorm` ad-hoc when a milestone enters unfamiliar code territory | +| Carrier | `spec_path` (mandatory), `iteration_scope` (mandatory — which sections of the spec this dispatch covers), `focus_hint` (optional — e.g. "trace ctor lookup", "find all `Pattern::Lit` sites") | +| Output | Structured Markdown block, ≤1500 tokens (see "Output format" below) | +| Status protocol | `DONE` / `DONE_WITH_CONCERNS` / `NEEDS_CONTEXT` / `BLOCKED` | + +#### Iron Law + +``` +NO PLAN WRITING. NO TASK DECOMPOSITION. NO STEP TEXT. +NAMES PATHS, LINES, FUNCTIONS, AND ANCHORS — NOT THE FIX. +NO EDITS. NOT TO CODE, NOT TO DOCS. +``` + +The boundary mirrors `ailang-architect`: the agent diagnoses where +work lands, the controller decides what to do with it. + +#### Standing reading list + +1. `CLAUDE.md` — orchestrator framing. +2. `docs/DESIGN.md` — invariants the iteration must preserve. +3. `docs/journals/INDEX.md` and the latest entries — what just + shipped, so the recon doesn't double-count fresh work. +4. `skills/planner/SKILL.md` — the role the recon serves. + +The agent does NOT open `docs/plans/`; plan files are the +*output* downstream of recon, not its input. + +#### Output format + +```markdown +## Files + +### Create +- `` — + +### Modify +- `:` — + - relevant function: `` at `:` + - cross-reference: `:` (lockstep partner) + +### Anchors not yet present +- `` — + +## Cross-references + +Any lockstep-invariant pairs (e.g. `Pattern::Lit::*` typecheck ↔ +pre-desugar walker) that the iteration is likely to touch. Walk +the pairs listed in `ailang-architect`'s reading list as a starting +point. + +## Open questions + +Things the spec implies but the code state cannot answer alone — +flag for Boss judgement, do not invent an answer. + +## Status + +`DONE` | `DONE_WITH_CONCERNS` | `NEEDS_CONTEXT` | `BLOCKED` (with one-line reason) +``` + +#### Common Rationalisations + +| Excuse | Reality | +|---|---| +| "While I'm here, let me sketch what the task would look like" | That is plan writing. Stop at the file-map; the Boss decomposes. | +| "I'll just suggest the fix in the cross-references" | A suggestion biases the Boss's design space. Name the site, not the fix. | +| "The spec is ambiguous on this point, I'll pick the obvious reading" | `NEEDS_CONTEXT` with a one-line carrier-clarification request. The Boss decides. | +| "Code search returns nothing for X, so X isn't in scope" | List X under "Anchors not yet present" with a one-line note. Absence is signal. | + +#### Red Flags — STOP + +- About to write a numbered task list +- About to suggest a fix in the cross-references column +- About to skip reading DESIGN.md because "I know that part" +- About to return a file-map without line ranges +- About to invent a line number you did not verify + +### `skills/planner/SKILL.md` (MODIFIED) + +Step 2 is replaced. The new Step 2 reads: + +> ### Step 2 — Map file structure +> +> Dispatch `ailang-plan-recon` with the spec path and iteration +> scope. Read the returned file-map. Lift the relevant entries +> into the plan's "Files this plan creates or modifies" section; +> the Boss may add or amend entries that recon missed. +> +> Recon does NOT decide decomposition. Two recon dispatches per +> planner run is unusual but legitimate (e.g. one for the main spec +> sections, one with a sharper `focus_hint` for a tricky subsystem). +> Three or more is a smell — re-read the spec; the iteration scope +> is probably too broad. + +The rest of the SKILL.md (Steps 1, 3–6, Iron Law, Handoff Contract, +Common Rationalisations) is unchanged in scope, but the "No private +agents" line in Cross-references is replaced with a one-line +reference to the new agent. + +### `skills/brainstorm/SKILL.md` (MODIFIED, one paragraph) + +A note in the "Cross-references" section: although `brainstorm` +itself has no private agents, the Boss may ad-hoc dispatch +`ailang-plan-recon` during Step 1 (project context) when the +milestone enters code territory the Boss has not recently read. +This is opt-in, not part of the standard process, and is documented +under "Cross-references" rather than as a step. + +### `skills/README.md` (MODIFIED) + +One new row in the agent roster: + +``` +| ailang-plan-recon | planner/agents/ | planner (primary); brainstorm (ad-hoc) | +``` + +The "Agents do not call other agents — one named exception" line +remains: ad-hoc dispatch from `brainstorm` is the Boss dispatching +the agent, not an agent calling another agent. + +### `.claude/agents/planner` (NEW symlink) + +``` +.claude/agents/planner -> skills/planner/agents +``` + +Mirrors the existing `.claude/agents/{implement,audit,fieldtest,debug}` +pattern. Required so `subagent_type: ailang-plan-recon` resolves +during dispatch. + +## Data flow + +``` +planner Step 1: Boss reads spec + | + v +planner Step 2: Boss dispatches ailang-plan-recon + with { spec_path, iteration_scope, focus_hint? } + | + v (file-map, <=1500 tokens) +planner Step 2: Boss lifts file-map into plan's + "Files this plan creates or modifies" + section, augments if needed + | + v +planner Steps 3-8: unchanged (task writing, header, + self-review, commit, handoff) +``` + +For ad-hoc dispatch from `brainstorm`, the Boss reads the file-map +into the Q&A flow but never writes a plan; the file-map informs +the design dialog and is discarded at hand-off to `planner`. + +## Error handling + +The agent's BLOCKED conditions: + +| Condition | Carrier-level resolution | +|---|---| +| `spec_path` does not resolve | Boss fixes the path and re-dispatches. | +| `iteration_scope` is ambiguous (names a section the spec doesn't have) | Boss reframes the carrier with a precise section reference. | +| Code search returns zero candidates for a feature the spec describes | Recon returns `DONE_WITH_CONCERNS` with the absence flagged under "Anchors not yet present". Boss decides: (a) spec gap → bounce to `brainstorm`, or (b) feature is genuinely new and the spec is correct. | +| Required reading list is unreadable (DESIGN.md missing) | Recon returns `infra_blocked`. Boss fixes the working directory. | + +The Boss never papers over a `BLOCKED`/`NEEDS_CONTEXT` recon by +hand-coding the file-map. That collapses the discipline. + +## Testing strategy + +This is a skill-system change, not a language change, so testing is +the verification-ladder pattern used by the `or.1` orchestrator-agent +spec: the first dispatches in real use are the test. + +1. **First planner dispatch.** A next-iter planner run (e.g. one of + the P2 roadmap items) is executed with the new agent in place. + Confirm: the file-map produced by recon names every path the + final plan ends up creating or modifying. +2. **Token-budget delta.** End-of-session Boss-context size compared + informally against the previous planner sessions (`ct.1`, `ct.4`, + `or.1`). Goal: visible reduction, not a precise number. +3. **Plan-quality preservation.** The plan that comes out of the + first dispatch passes `implement` spec-review on Task 1 without + raising a `non_compliant` on missing paths or stale line numbers. +4. **BLOCKED handling exercise.** When a recon dispatch organically + blocks (spec gap, ambiguous scope), the Boss handles it via + carrier-clarification rather than papering over. +5. **Ad-hoc brainstorm dispatch.** First brainstorm session in + unfamiliar territory after this lands tries the ad-hoc dispatch; + confirm the agent works untouched in that context. + +Steps 1–3 should land within the next 2–3 planner runs. Steps 4–5 +get checked off when those conditions arise organically. + +## Acceptance criteria + +- `skills/planner/agents/ailang-plan-recon.md` exists with the + template specified in **Components**. +- `skills/planner/SKILL.md` Step 2 dispatches the new agent. +- `skills/brainstorm/SKILL.md` Cross-references section names the + ad-hoc dispatch option. +- `skills/README.md` agent roster lists the new agent. +- `.claude/agents/planner` symlink exists. +- A real planner dispatch using the agent has run, and the + verification-ladder steps 1–3 are recorded in the iter journal. + +## Out of scope + +- **Brainstorm subagents.** Rationale: dialog-driven, recon is + interwoven with Q&A. Revisit only if the ad-hoc dispatch pattern + proves insufficient. +- **Plan-writer subagent.** Rationale: task decomposition is the + design work; delegating it would defeat the point of the planner + skill. The Boss writes tasks. +- **Plan-reviewer subagent.** Rationale: today's inline self-review + (Step 5 of `planner`) works. The implement-side spec-reviewer is + the downstream gate. Adding a third reviewer would be + defensive-programming for a problem we don't have. Revisit if a + shipped plan ever passes self-review but fails implement + spec-review on Task 1 paths. +- **Recon-writeup subagent for `brainstorm` Step 6.** Rationale: + Step 6 is dialog kondensation; the Boss has the live transcript. + +## Rationale: why brainstorm doesn't get its own dedicated agent + +Three substantive reasons, in order of weight: + +1. **Recon and dialogue are interwoven.** brainstorm Step 1 names + the project state in advance, but Step 2's Q&A reshapes which + parts of that state matter. A subagent dispatched at Step 1 + reads the surface; the Boss then has to re-read the parts the + user's answers focused on. Net: more total reads, not fewer. + +2. **The Boss must hold the project state to lead Q&A.** Even if a + subagent pre-digested DESIGN.md, the Boss cannot ask informed + follow-up questions without holding the same context. Delegation + here doubles the read budget rather than replacing it. + +3. **Spec writing is dialog kondensation.** Step 6 produces the + spec from the live dialogue. A subagent would need the full + transcript handed to it — the very token volume we are trying + to keep out of the Boss context. The Boss is the natural + condenser because the Boss is the dialogue partner. + +The asymmetry with `planner`: the planner has a phase where the +input (spec) is fixed and the output (file-map) is small and +structured. `brainstorm` has no such phase. The recon agent's +shape fits the former and not the latter. + +## Naming + home + +The agent lives at `skills/planner/agents/ailang-plan-recon.md` +because `planner` is the primary dispatcher. Ad-hoc dispatch from +`brainstorm` is the Boss's call, not a skill→agent transition; it +does NOT violate the "no orphan agents" rule, since `planner` is the +formal owner. + +The name `ailang-plan-recon` is preferred over `ailang-code-recon` +because: +- It anchors the agent to its primary skill, matching the rest of + the roster (`ailang-implementer`, `ailang-architect`, etc.). +- It signals "for a planner dispatch" — which informs the carrier + format and the output shape. +- "code-recon" would suggest a general-purpose code-reading utility + that other agents might call; that direction is explicitly out of + scope (see "Agents do not call other agents" in `skills/README.md`).