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

325 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
```markdown
## 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` (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 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`).