832375f2ac
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.
325 lines
14 KiB
Markdown
325 lines
14 KiB
Markdown
# 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
|
||
- `<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, 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`).
|