From 14ac4ae7c36b3253709c1ec99db23fe8995615cf Mon Sep 17 00:00:00 2001 From: Brummel Date: Mon, 11 May 2026 12:27:04 +0200 Subject: [PATCH] plan: pr.1 plan-recon subagent --- .../2026-05-11-pr.1-plan-recon-subagent.md | 598 ++++++++++++++++++ 1 file changed, 598 insertions(+) create mode 100644 docs/plans/2026-05-11-pr.1-plan-recon-subagent.md diff --git a/docs/plans/2026-05-11-pr.1-plan-recon-subagent.md b/docs/plans/2026-05-11-pr.1-plan-recon-subagent.md new file mode 100644 index 0000000..8ee68d6 --- /dev/null +++ b/docs/plans/2026-05-11-pr.1-plan-recon-subagent.md @@ -0,0 +1,598 @@ +# Iteration pr.1 — Plan-recon Subagent — Implementation Plan + +> **Parent spec:** `docs/specs/2026-05-11-plan-recon-subagent.md` +> +> **For agentic workers:** REQUIRED SUB-SKILL: use `skills/implement` +> to run this plan. Steps use `- [ ]` checkboxes for tracking. + +**Goal:** Introduce a new read-only subagent `ailang-plan-recon` that +the `planner` skill dispatches at Step 2 (file-structure mapping), +moving the read-heavy code-recon out of Boss context. `brainstorm` +gets a one-paragraph note allowing ad-hoc dispatch of the same agent +when entering unfamiliar code territory; it does NOT receive a +dedicated agent. + +**Architecture:** Five sites change. One new agent file, one new +symlink, three SKILL/README edits. No language code touched; no +benchmark impact expected. This is a skill-system iteration in the +spirit of `or.1` (orchestrator-refactor): the recon agent goes live +the next time `planner` runs after this lands. THIS plan was written +in pre-recon mode — Boss did the file-mapping in-context — a +bootstrap necessity since the recon agent does not yet exist while +creating it. + +**Tech Stack:** Markdown only. No Rust, no LLVM, no bench changes. + +--- + +## Files this plan creates or modifies + +- Create: `skills/planner/agents/ailang-plan-recon.md` — new agent + file, full body specified verbatim in Task 1. +- Create: `.claude/agents/planner` — symlink to + `../../skills/planner/agents` (mirrors existing pattern for the + other four agent-bearing skills). +- Modify: `skills/planner/SKILL.md` — replace Step 2 body, replace + Cross-references "No private agents" line with the new agent entry. +- Modify: `skills/brainstorm/SKILL.md` — extend Cross-references + "No private agents" line with the ad-hoc-dispatch note. +- Modify: `skills/README.md` — add agent roster row at top of table + (planner is upstream of implement in the pipeline); add symlink + listing entry in the Discovery block. + +--- + +## Task pr.1.1: New agent file `ailang-plan-recon.md` + +**Files:** +- Create: `skills/planner/agents/ailang-plan-recon.md` + +- [ ] **Step 1: Confirm target directory exists** + +Run: `ls -d skills/planner/agents 2>/dev/null || mkdir -p skills/planner/agents` +Expected: directory exists or is created. No output (or `mkdir` silent +success). + +- [ ] **Step 2: RED check — agent file must not exist yet** + +Run: `test ! -e skills/planner/agents/ailang-plan-recon.md && echo RED` +Expected: prints `RED` (the file does not yet exist). + +- [ ] **Step 3: Write the agent file verbatim** + +Write the following content to +`skills/planner/agents/ailang-plan-recon.md`: + +````markdown +--- +name: ailang-plan-recon +description: Read-only code-and-doc-recon agent for plan writing. Dispatched by planner at Step 2 (file-structure mapping) and ad-hoc by brainstorm when entering unfamiliar code territory. Names paths, lines, functions, and cross-references; does NOT propose tasks or fixes. +tools: Read, Glob, Grep, Bash +--- + +# ailang-plan-recon + +> **Violating the letter of these rules is violating the spirit.** + +You are the **plan-recon agent** for the AILang project at +`/home/brummel/dev/ailang`. You are dispatched by `skills/planner` at +Step 2 of every iteration plan, and ad-hoc by `skills/brainstorm` when +a milestone enters code territory the Boss has not recently read. +**You do not write tasks. You do not propose fixes. You produce a +file-map.** + +## What this role is for + +When the Boss writes a plan from a spec, the costly phase is mapping +the spec onto the existing codebase: which files will be created, +which modified, at which line ranges, naming which functions and +cross-references. This read-heavy phase typically dwarfs the +spec-read and the task-write together, and it collapses cleanly into +a small structured summary. That is your job: do the reads, return +the summary, leave the design judgement to the Boss. + +The temptation is to also draft the tasks. Do not. The Boss owns +decomposition; your authority ends at naming where work lands. + +## Standing reading list + +1. `CLAUDE.md` — orchestrator framing. +2. `docs/DESIGN.md` — invariants the iteration must preserve. Skim + the sections the carrier flags or that the spec touches; do not + skim sections you know the spec does not touch. +3. `docs/journals/INDEX.md` and the latest entries — what just + shipped, so the file-map does not double-count fresh work. +4. `skills/planner/SKILL.md` — the role the recon serves. Do NOT + open files under `docs/plans/`; plan files are output downstream + of recon, never input. + +## Carrier contract — what the controller hands you + +| Field | Content | +|-------|---------| +| `spec_path` | Path to `docs/specs/.md` (mandatory) | +| `iteration_scope` | Which sections of the spec this dispatch covers (mandatory) | +| `focus_hint` | Optional: orchestrator may flag a specific subsystem or symbol to prioritise | + +If `spec_path` does not resolve or `iteration_scope` is empty, return +`BLOCKED` with a one-line reason. + +## The 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. +``` + +Your tools include `Read, Glob, Grep, Bash` — but `Bash` is for +read-only inspection (`git log`, `git grep`, `git diff`); never to +fix or write. + +## The Process + +1. Read the carrier. Confirm `spec_path` resolves and + `iteration_scope` is non-empty. If either fails, return `BLOCKED`. +2. Read the spec in full. Note every reference to a path, type, + function, or invariant. +3. Read the standing list in order: CLAUDE.md → DESIGN.md (relevant + sections) → `docs/journals/INDEX.md` + latest → + `skills/planner/SKILL.md`. +4. For each path or symbol the spec references, run `git grep` or + `Glob`+`Read` to anchor it to exact line numbers in the current + tree. Record: + - existing files to modify, with line ranges + - relevant function or type names with line numbers + - cross-references the iteration touches (especially the + lockstep-invariant pairs documented in `ailang-architect`'s + reading list) +5. For each path or symbol the spec implies must exist but does not + in the current tree, record it under "Anchors not yet present". + Absence is signal; do not invent. +6. Apply the priority filter: spec sections in `iteration_scope` get + full coverage; sections out-of-scope get a one-line acknowledgement + only. +7. Compose the output block (≤1500 tokens) in the format below. +8. If anything is ambiguous, return `DONE_WITH_CONCERNS` (concern + inline) or `NEEDS_CONTEXT` (cannot proceed without clarification). + +## Output format + +```markdown +## Files + +### Create +- `` — + +### Modify +- `:` — + - relevant function: `` at `:` + - cross-reference: `:` (lockstep partner) + +### Anchors not yet present +- `` — + +## Cross-references + +Any lockstep-invariant pairs likely touched. Walk the pairs in +`ailang-architect`'s "Lockstep invariants" table 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` (one-line reason) +``` + +## Status protocol + +| Status | Meaning | +|--------|---------| +| `DONE` | File-map covers every in-scope spec section. No ambiguity. | +| `DONE_WITH_CONCERNS` | File-map produced; concerns are non-blocking observations (e.g. "this section implies a refactor of an out-of-scope file"). | +| `NEEDS_CONTEXT` | Carrier is missing information you need (e.g. `iteration_scope` names a section the spec does not contain). | +| `BLOCKED` | Cannot proceed (carrier malformed, spec unreadable, infra failure). | + +## Common Rationalisations + +| Excuse | Reality | +|--------|---------| +| "While I'm here, let me sketch what Task 1 would look like" | That is plan writing. Stop at the file-map; the Boss decomposes. | +| "I'll suggest the fix in the cross-references column" | A suggestion biases the Boss's design space. Name the site, not the fix. | +| "Spec is ambiguous on point X, I'll pick the obvious reading" | Return `NEEDS_CONTEXT`. The Boss decides. | +| "Code search returns nothing for X, so X isn't in scope" | List X under "Anchors not yet present". Absence is signal. | +| "Line numbers will shift before the plan executes, so I'll be vague" | The Boss needs the current line numbers to anchor the plan. Drift between recon and plan execution is the Boss's problem, not yours. | + +## 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 sections that the spec touches +- About to return a file-map without line ranges +- About to invent a line number you did not verify +- About to use `Bash` to write or edit anything +```` + +- [ ] **Step 4: GREEN check — agent file exists with required anchors** + +Run: +```bash +test -f skills/planner/agents/ailang-plan-recon.md && \ + grep -q "^name: ailang-plan-recon$" skills/planner/agents/ailang-plan-recon.md && \ + grep -q "^tools: Read, Glob, Grep, Bash$" skills/planner/agents/ailang-plan-recon.md && \ + grep -q "NO PLAN WRITING. NO TASK DECOMPOSITION. NO STEP TEXT." skills/planner/agents/ailang-plan-recon.md && \ + echo GREEN +``` +Expected: prints `GREEN`. + +- [ ] **Step 5: Commit** + +```bash +git add skills/planner/agents/ailang-plan-recon.md +git commit -m "iter pr.1.1: new agent ailang-plan-recon" +``` + +--- + +## Task pr.1.2: Symlink `.claude/agents/planner` + +**Files:** +- Create: `.claude/agents/planner` (symlink to `../../skills/planner/agents`) + +- [ ] **Step 1: RED check — symlink must not exist yet** + +Run: `test ! -e .claude/agents/planner && echo RED` +Expected: prints `RED`. + +- [ ] **Step 2: Create the symlink (relative, matches existing form)** + +Run from the repo root: +```bash +ln -s ../../skills/planner/agents .claude/agents/planner +``` +Expected: no output. (`ls -la .claude/agents/` would show the new +symlink afterwards.) + +- [ ] **Step 3: GREEN check — symlink resolves to target directory** + +Run: +```bash +test -L .claude/agents/planner && \ + test "$(readlink .claude/agents/planner)" = "../../skills/planner/agents" && \ + test -f .claude/agents/planner/ailang-plan-recon.md && \ + echo GREEN +``` +Expected: prints `GREEN`. + +- [ ] **Step 4: Commit** + +```bash +git add .claude/agents/planner +git commit -m "iter pr.1.2: symlink .claude/agents/planner" +``` + +--- + +## Task pr.1.3: Modify `skills/planner/SKILL.md` + +**Files:** +- Modify: `skills/planner/SKILL.md` — replace Step 2 body; replace + Cross-references "No private agents" line. + +- [ ] **Step 1: RED check — old Step 2 prose still present, new + prose absent** + +Run: +```bash +grep -q "Before defining tasks, list every file" skills/planner/SKILL.md && \ + grep -q "No private agents" skills/planner/SKILL.md && \ + ! grep -q "Dispatch \`ailang-plan-recon\`" skills/planner/SKILL.md && \ + echo RED +``` +Expected: prints `RED`. + +- [ ] **Step 2: Replace Step 2 body** + +Find the block (Step 2 header through the end of the closing +sentence "Files that change independently get separate tasks."): + +```markdown +### Step 2 — Map file structure + +Before defining tasks, list every file the iteration will create or +modify, and what each one is responsible for. This is where +decomposition decisions are locked in. + +```markdown +**Files this plan creates or modifies:** + +- Create: `crates/ailang-codegen/src/.rs` — +- Modify: `crates/ailang-check/src/typeclass.rs` — adds + +- Test: `crates/ail/tests/e2e.rs` — adds +``` + +Files that change together stay in the same task. Files that change +independently get separate tasks. +``` + +Replace with (preserving the surrounding `### Step 3` heading +untouched): + +```markdown +### 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. + +Dispatch carrier: + +| Field | Content | +|-------|---------| +| `spec_path` | path to the parent spec | +| `iteration_scope` | which sections of the spec this iteration covers | +| `focus_hint` | optional — subsystem or symbol to prioritise | + +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 plan's "Files this plan creates or modifies" section keeps the +same shape: + +```markdown +**Files this plan creates or modifies:** + +- Create: `` — +- Modify: `:` +- Test: `` — +``` + +Files that change together stay in the same task. Files that change +independently get separate tasks. +``` + +- [ ] **Step 3: Replace Cross-references "No private agents" line** + +Find the block: + +```markdown +## Cross-references + +- **Input source:** `skills/brainstorm/SKILL.md` — produces the + spec this skill consumes. +- **Output target:** `skills/implement/SKILL.md` — runs the plan + task-by-task. +- **No private agents.** This skill is dialogue-driven (orchestrator + + spec). +``` + +Replace with: + +```markdown +## Cross-references + +- **Input source:** `skills/brainstorm/SKILL.md` — produces the + spec this skill consumes. +- **Output target:** `skills/implement/SKILL.md` — runs the plan + task-by-task. +- **Agents dispatched:** + - `skills/planner/agents/ailang-plan-recon.md` — Step 2, + file-structure mapping (read-only). Mandatory; the Boss does + NOT do recon in-context. +``` + +- [ ] **Step 4: GREEN check** + +Run: +```bash +! grep -q "Before defining tasks, list every file" skills/planner/SKILL.md && \ + ! grep -q "No private agents" skills/planner/SKILL.md && \ + grep -q "Dispatch \`ailang-plan-recon\`" skills/planner/SKILL.md && \ + grep -q "Mandatory; the Boss does" skills/planner/SKILL.md && \ + echo GREEN +``` +Expected: prints `GREEN`. + +- [ ] **Step 5: Commit** + +```bash +git add skills/planner/SKILL.md +git commit -m "iter pr.1.3: planner Step 2 dispatches ailang-plan-recon" +``` + +--- + +## Task pr.1.4: Modify `skills/brainstorm/SKILL.md` + +**Files:** +- Modify: `skills/brainstorm/SKILL.md` — extend Cross-references "No + private agents" line. + +- [ ] **Step 1: RED check** + +Run: +```bash +grep -q "No private agents.\*\*\* This skill is dialogue-driven\." skills/brainstorm/SKILL.md && \ + ! grep -q "ad-hoc dispatch" skills/brainstorm/SKILL.md && \ + echo RED +``` +Expected: prints `RED`. + +- [ ] **Step 2: Extend the "No private agents" bullet** + +Find the block: + +```markdown +## Cross-references + +- **Project source:** `docs/DESIGN.md` "Feature-acceptance + criterion" — gate this skill applies during spec writing. +- **Output target:** `skills/planner/SKILL.md` — only valid next + skill. +- **No private agents.** This skill is dialogue-driven. +``` + +Replace with: + +```markdown +## Cross-references + +- **Project source:** `docs/DESIGN.md` "Feature-acceptance + criterion" — gate this skill applies during spec writing. +- **Output target:** `skills/planner/SKILL.md` — only valid next + skill. +- **No private agents.** This skill is dialogue-driven. The Boss + MAY ad-hoc dispatch `skills/planner/agents/ailang-plan-recon.md` + during Step 1 when the milestone enters code territory the Boss + has not recently read; this is opt-in and not part of the standard + process. Rationale: brainstorm's recon phase is interwoven with + the user Q&A — see `docs/specs/2026-05-11-plan-recon-subagent.md` + for the full reasoning. +``` + +- [ ] **Step 3: GREEN check** + +Run: +```bash +grep -q "ad-hoc dispatch" skills/brainstorm/SKILL.md && \ + grep -q "Rationale: brainstorm's recon phase is interwoven" skills/brainstorm/SKILL.md && \ + echo GREEN +``` +Expected: prints `GREEN`. + +- [ ] **Step 4: Commit** + +```bash +git add skills/brainstorm/SKILL.md +git commit -m "iter pr.1.4: brainstorm allows ad-hoc plan-recon dispatch" +``` + +--- + +## Task pr.1.5: Modify `skills/README.md` + +**Files:** +- Modify: `skills/README.md` — insert agent roster row; extend the + `.claude/agents/` Discovery listing. + +- [ ] **Step 1: RED check** + +Run: +```bash +! grep -q "ailang-plan-recon" skills/README.md && \ + ! grep -q "\.claude/agents/planner" skills/README.md && \ + echo RED +``` +Expected: prints `RED`. + +- [ ] **Step 2: Insert agent roster row at top of table** + +Find the line: + +``` +| `ailang-implement-orchestrator` | `implement/agents/` | `implement` (the only agent with the `Agent` tool; runs the per-task loop) | +``` + +Replace with two lines (the new entry first, then the existing +implement-orchestrator line preserved): + +``` +| `ailang-plan-recon` | `planner/agents/` | `planner` (Step 2; read-only file-structure mapping); `brainstorm` (ad-hoc Step 1 in unfamiliar territory) | +| `ailang-implement-orchestrator` | `implement/agents/` | `implement` (the only agent with the `Agent` tool; runs the per-task loop) | +``` + +- [ ] **Step 3: Extend the `.claude/agents/` Discovery listing** + +Find the block: + +``` +.claude/agents/implement -> skills/implement/agents +.claude/agents/audit -> skills/audit/agents +.claude/agents/fieldtest -> skills/fieldtest/agents +.claude/agents/debug -> skills/debug/agents +``` + +Replace with (insert the planner line at top, matching pipeline +order — planner is upstream of implement): + +``` +.claude/agents/planner -> skills/planner/agents +.claude/agents/implement -> skills/implement/agents +.claude/agents/audit -> skills/audit/agents +.claude/agents/fieldtest -> skills/fieldtest/agents +.claude/agents/debug -> skills/debug/agents +``` + +- [ ] **Step 4: GREEN check** + +Run: +```bash +grep -q "^| \`ailang-plan-recon\`" skills/README.md && \ + grep -q "^.claude/agents/planner" skills/README.md && \ + echo GREEN +``` +Expected: prints `GREEN`. + +- [ ] **Step 5: Commit** + +```bash +git add skills/README.md +git commit -m "iter pr.1.5: roster + discovery entries for ailang-plan-recon" +``` + +--- + +## Post-task checks (for the orchestrator-agent end-report) + +- [ ] All five tasks committed. +- [ ] `cargo build --workspace --release` passes (sanity — should be + unaffected, this iter touches no Rust). +- [ ] `bench/check.py`, `bench/compile_check.py`, `bench/cross_lang.py` + return exit code 0 (audit step; not strictly required at end of + iter, but trivial and a useful smoke). +- [ ] Per-iter journal `docs/journals/2026-05-11-iter-pr.1.md` written + with the iter-or.1 template (Summary / Per-task subjects / Concerns + / Known debt / Blocked detail / Commits / Stats / Audit close). +- [ ] `docs/journals/INDEX.md` gets a new pointer line. + +--- + +## Verification ladder (deferred — checked off when applicable) + +These are the spec's acceptance-criteria items that cannot be +verified within this iter itself. They get checked off in the iter +journal as conditions arise: + +1. **First real planner dispatch** uses `ailang-plan-recon`; the + file-map names every path the plan ends up creating or modifying. +2. **Token-budget delta** at end of session: visible reduction + compared with previous planner sessions (`ct.1`, `ct.4`, `or.1`). +3. **Plan-quality preservation**: the first plan written with the + agent passes `implement` spec-review on Task 1 without + `non_compliant` on stale paths. +4. **BLOCKED handling exercise**: when a recon dispatch organically + blocks, the Boss handles via carrier-clarification. +5. **Ad-hoc brainstorm dispatch**: first brainstorm in unfamiliar + territory after this lands tries the ad-hoc path. + +--- + +## Out of scope (mirrors spec) + +- Brainstorm dedicated subagents (rationale: dialog-driven, recon + interwoven with Q&A). +- Plan-writer subagent (rationale: decomposition IS the design work). +- Plan-reviewer subagent (rationale: today's inline self-review + + downstream implement spec-review is sufficient gate). +- Modifying `CLAUDE.md` — none of this iter's changes update the + orchestrator framing; the recon agent is one more agent under the + existing skill system, not a new layer.