Files
AILang/docs/specs/0009-plan-recon-subagent.md
T
Brummel 832375f2ac convention: counter-prefix file naming across docs/specs/, docs/plans/, design/contracts/, design/models/
All 176 files in the four accumulating directories now use a
zero-padded 4-digit counter prefix that reflects creation order
(`NNNN-slug.md`). The counter is assigned per directory in strict
git-log creation order; ties broken alphabetically by original name.
The old `YYYY-MM-DD-` prefix on docs/specs/ and docs/plans/ files is
dropped — the date is recoverable from git log and the counter
carries the ordering.

A file's counter is stable for the life of the file: never reassigned,
never reused, never compacted. Deleted files retire their counter;
subsequent files do not fill the gap. This is the property that lets
cross-references stay literal — refs use the full filename including
the counter (`design/contracts/0007-honesty-rule.md`) so they grep
cleanly and resolve directly without a glob step.

313 cross-references updated across .md/.rs/.toml/.c/.json files
(test pins, include_str! paths, design-INDEX entries, baseline notes,
runtime C comments, inter-contract markdown links incl. bare basename
and `../models/foo.md` forms).

CLAUDE.md gets a new "File-naming convention" section spelling out
the rule and rationale. skills/brainstorm/SKILL.md and
skills/planner/SKILL.md updated so new spec/plan creation produces
counter-prefixed names from the start.

The full test suite (cargo test --workspace) passes.
2026-05-28 13:31:31 +02:00

14 KiB
Raw Blame History

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 (515k Boss tokens on a typical milestone), produces a compact structured summary (~500 tokens). High delegation ratio. Decomposition-independent: the Boss can run Steps 38 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

## Files

### Create
- `<path>` — <one-line responsibility>

### Modify
- `<path>:<line range>` — <one-line site description>
  - relevant function: `<fn name>` at `<path>:<line>`
  - cross-reference: `<other path>:<line>` (lockstep partner)

### Anchors not yet present
- `<path>` — <what the spec implies must be added but does not exist today>

## 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, 36, 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 -> 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 13 should land within the next 23 planner runs. Steps 45 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 13 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).