Files
AILang/docs/plans/0029-orchestrator-refactor.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

51 KiB
Raw Blame History

Orchestrator-Refactor — Implementation Plan

Parent spec: docs/specs/0008-implement-orchestrator-agent.md

For agentic workers: REQUIRED SUB-SKILL: use skills/implement to run this plan. Steps use - [ ] checkboxes for tracking.

Bootstrap note: this plan is executed with the pre-refactor /implement skill (Boss dispatches ailang-implementer directly). The ailang-implement-orchestrator agent introduced here goes live only on the next /implement run after this iteration lands. The Boss must NOT attempt to dispatch the new agent during this run.

Goal: ship the three coupled changes from the parent spec — Boss-context offload via a new ailang-implement-orchestrator agent, per-iter branch isolation, and per-iter journal files replacing the 14k-line monolith — without altering any worker agent's role or any language behaviour.

Architecture: seven discrete tasks in dependency order. Filesystem migration first (JOURNAL.md → journal-archive.md, new docs/journals/ subdir with INDEX.md). Then references are repointed in two waves (top-level docs, then skill/agent files) so the JOURNAL.md path disappears from active reading lists. Then the implementer and spec-reviewer carriers are switched from task_text to task_text_path so the new orchestrator can hand them a file. Then the new orchestrator agent is created. Then skills/implement/SKILL.md is rewritten to delegate both modes to the new agent. Finally the one-line exception note in skills/README.md. The verification ladder is a manual checklist at the end — no cargo test applies (skill/agent files are not Rust code).

Tech Stack: markdown files only; one git mv; no Rust or build changes.


Files this plan creates or modifies:

  • Rename: docs/JOURNAL.mddocs/journal-archive.md (Task 1)
  • Create: docs/journals/INDEX.md (Task 1)
  • Modify: CLAUDE.md (Task 2) — 4 sites under "Code layout" + "Roles"
    • "Done-state notifications"
  • Modify: docs/DESIGN.md (Task 2) — 1 site
  • Modify: docs/roadmap.md (Task 2) — 1 site
  • Modify: skills/README.md (Task 3 partial, Task 7 final) — 5 sites total split between the two tasks
  • Modify: skills/audit/SKILL.md (Task 3) — 9 sites (most are conceptual "JOURNAL ratify entry"-phrasing, not path refs; path refs only on lines 49)
  • Modify: skills/audit/agents/ailang-architect.md (Task 3) — 8 sites
  • Modify: skills/audit/agents/ailang-bencher.md (Task 3) — 4 sites
  • Modify: skills/audit/agents/ailang-docwriter.md (Task 3) — 4 sites
  • Modify: skills/brainstorm/SKILL.md (Task 3) — 1 path site + 2 conceptual sites
  • Modify: skills/debug/agents/ailang-debugger.md (Task 3) — 3 sites
  • Modify: skills/fieldtest/agents/ailang-fieldtester.md (Task 3) — 7 sites
  • Modify: skills/implement/agents/ailang-implementer.md (Task 3 for JOURNAL refs + Task 4 for carrier) — 3 JOURNAL sites + carrier rewrite of Step 1 / Carrier-contract block
  • Modify: skills/implement/agents/ailang-spec-reviewer.md (Task 4) — carrier rewrite, task_texttask_text_path
  • Modify: skills/implement/agents/ailang-tester.md (Task 3) — 2 sites
  • Create: skills/implement/agents/ailang-implement-orchestrator.md (Task 5)
  • Rewrite: skills/implement/SKILL.md (Task 6) — from ~210 lines to ~100 lines, structure per spec §"skills/implement/SKILL.md (rewritten)"
  • Modify: skills/README.md (Task 7) — exception sentence + agent roster row

Historical files in docs/plans/ and docs/specs/ and docs/WhatsNew.md are not rewritten — they are dated artifacts of past decisions and remain mutable only to the iteration that produced them.


Task 1: Filesystem migration — JOURNAL.md archived, new docs/journals/

Files:

  • Rename: docs/JOURNAL.mddocs/journal-archive.md

  • Modify: docs/journal-archive.md (header note)

  • Create: docs/journals/INDEX.md

  • Step 1: Verify clean working tree before destructive move

Run: git status --porcelain Expected: empty output (no staged or unstaged changes).

If non-empty, STOP and surface to the Boss — the task assumes a clean tree.

  • Step 2: Rename JOURNAL.md to journal-archive.md

Run: git mv docs/JOURNAL.md docs/journal-archive.md Expected: rename recorded in git status; file content identical modulo path.

  • Step 3: Prepend archived-status header to journal-archive.md

The first line of docs/journal-archive.md is currently # AILang JOURNAL. Insert a blockquote note immediately after it, followed by a blank line.

Exact insertion (after the existing H1 title, before whatever blank line or content follows):

# AILang JOURNAL

> **Status:** archived 2026-05-11. New iter journals live under
> `docs/journals/`. See `docs/journals/INDEX.md` for the
> chronological pointer list. This file remains the historical
> record for entries prior to that date.

If the existing line 1 is not # AILang JOURNAL, read the first 5 lines first and adjust the insertion anchor accordingly without removing existing content.

  • Step 4: Create docs/journals/INDEX.md

Write the file with this exact content:

# Journal index

> Chronological pointer list of per-iter journal files. Append-only.
> One line per iter, newest at the bottom. Filenames are relative to
> `docs/journals/`.

- pre-2026-05-11 — see `../journal-archive.md` for all prior history
  • Step 5: Verify the migration

Run: ls docs/journal-archive.md docs/journals/INDEX.md && head -10 docs/journal-archive.md Expected: both paths exist; the first ~5 visible lines of journal-archive.md show the archived-status blockquote.

  • Step 6: Commit
git add docs/journal-archive.md docs/journals/INDEX.md docs/JOURNAL.md
git commit -m "iter or.1.1: migrate JOURNAL.md to journal-archive.md + docs/journals/"

(docs/JOURNAL.md is included in git add to record the rename deletion alongside the new path; git mv already staged it but a re-add is a no-op safety.)


Task 2: Repoint references — top-level docs

Files:

  • Modify: CLAUDE.md (4 sites)

  • Modify: docs/DESIGN.md (1 site)

  • Modify: docs/roadmap.md (1 site)

  • Step 1: Patch CLAUDE.md — Code layout table (line 40)

Replace the line:

| `docs/` | Canonical specs and decisions log — `docs/DESIGN.md`, `docs/JOURNAL.md`, `docs/specs/` (per-milestone design specs), `docs/plans/` (per-iteration plans), `PROSE_ROUNDTRIP.md` |

with:

| `docs/` | Canonical specs and decisions log — `docs/DESIGN.md`, `docs/journals/` (per-iter journals + `INDEX.md`), `docs/journal-archive.md` (pre-2026-05-11 history), `docs/specs/` (per-milestone design specs), `docs/plans/` (per-iteration plans), `PROSE_ROUNDTRIP.md` |
  • Step 2: Patch CLAUDE.md — orchestrator role paragraph (line 66)

Find the line:

  invariants, and the contents of `docs/JOURNAL.md` and

Replace with:

  invariants, and the contents of `docs/journals/` and
  • Step 3: Patch CLAUDE.md — Done-state notifications paragraph (line 191)

Find the line:

   append-only — same chronological convention as `JOURNAL.md`).

Replace with:

   append-only — same chronological convention as the per-iter journals).
  • Step 4: Patch CLAUDE.md — "Roles of …" section header + body

Two related edits in the same region (currently lines 239262 in the pre-edit file).

(a) Section header (currently line 239):

## Roles of `docs/DESIGN.md`, `docs/JOURNAL.md`, `docs/roadmap.md`, `docs/specs/`, `docs/plans/`

Replace with:

## Roles of `docs/DESIGN.md`, `docs/journals/`, `docs/journal-archive.md`, `docs/roadmap.md`, `docs/specs/`, `docs/plans/`

(b) The **docs/JOURNAL.md** bullet (currently line 249 and the following paragraph that defines it). Replace the entire bullet (from - **\docs/JOURNAL.md`**` through the end of its paragraph) with two new bullets:

- **`docs/journals/<YYYY-MM-DD>-iter-<id>.md`** is the decisions
  log, one file per iter. Each file records *why* the iter moved
  the way it did — alternatives considered and rejected, lessons,
  rationale that does not belong in `docs/DESIGN.md`. Append-only
  per file; new files are appended via `docs/journals/INDEX.md`.
  `docs/journals/INDEX.md` is the chronological pointer list,
  Boss-maintained, one line per iter.

- **`docs/journal-archive.md`** is the archived monolithic
  decisions log for everything pre-2026-05-11. Content-frozen.
  Read it only when chasing long-tail history; do not append.
  • Step 5: Patch docs/DESIGN.md (line 49)

Find:

  `JOURNAL.md` (chronological decisions log),

Replace with:

  `docs/journals/` (per-iter decisions log; see `INDEX.md`) plus the archived `docs/journal-archive.md` for pre-2026-05-11 history,

(One line; do not reflow paragraph breaks.)

  • Step 6: Patch docs/roadmap.md (line 14)

Read the file at line 14 first to see the exact context.

Find:

  `docs/JOURNAL.md`).

Replace with:

  `docs/journals/`).
  • Step 7: Verify no JOURNAL.md path remains in top-level docs

Run: grep -n "JOURNAL.md" CLAUDE.md docs/DESIGN.md docs/roadmap.md Expected: empty output.

  • Step 8: Commit
git add CLAUDE.md docs/DESIGN.md docs/roadmap.md
git commit -m "iter or.1.2: repoint top-level docs to docs/journals/ + journal-archive.md"

Task 3: Repoint references — skill and agent files

Files (read all once, edit each, commit together):

  • Modify: skills/audit/SKILL.md
  • Modify: skills/audit/agents/ailang-architect.md
  • Modify: skills/audit/agents/ailang-bencher.md
  • Modify: skills/audit/agents/ailang-docwriter.md
  • Modify: skills/brainstorm/SKILL.md
  • Modify: skills/debug/agents/ailang-debugger.md
  • Modify: skills/fieldtest/agents/ailang-fieldtester.md
  • Modify: skills/implement/agents/ailang-implementer.md (JOURNAL refs only; carrier rewrite is Task 4)
  • Modify: skills/implement/agents/ailang-tester.md
  • Modify: skills/README.md (JOURNAL refs only; exception note is Task 7)

General replacement rule:

There are two kinds of JOURNAL reference in these files. Apply the rule per kind, NOT a blind global replace:

  1. Path references (docs/JOURNAL.md, `JOURNAL.md`, "the JOURNAL.md tail") — repoint to the new layout. The canonical phrasing is:

    • Standing-reading-list entries: docs/journals/INDEX.md + the latest 13 referenced files
    • Generic mentions of the log: docs/journals/
    • "tail of JOURNAL" → "latest entries linked from docs/journals/INDEX.md"
  2. Conceptual references that name a JOURNAL entry as a process artefact ("JOURNAL ratify entry", "JOURNAL the impasse", "no JOURNAL ticket") — these are about the act of journalling, not the path. Keep the word "JOURNAL" or "journal" as a process noun; do NOT add a path. Example: "JOURNAL ratify entry" stays as-is (a journal entry is now a per-iter file, but the concept "ratify entry" still names the same artefact in the new layout). Optionally clarify on first use per file with "(in the per-iter journal)" if the file talks about journalling at length.

The verification step at the bottom enumerates expected counts.

  • Step 1: skills/audit/SKILL.md

Line 49 has the only path reference:

For milestone <X>: read DESIGN.md, JOURNAL.md, the latest milestone

Replace with:

For milestone <X>: read DESIGN.md, `docs/journals/INDEX.md` and the latest 13 referenced files, the latest milestone

All other JOURNAL mentions in this file (lines 3, 20, 38, 83, 92, 95, 118, 127, 130) are conceptual references to the act of journalling and stay verbatim.

  • Step 2: skills/audit/agents/ailang-architect.md

(a) Line 33 (standing reading list):

3. `docs/JOURNAL.md` — the full log, with focus on the milestone you're

Replace with:

3. `docs/journals/INDEX.md` + the per-iter files for the milestone you're

(b) Line 100 (Iron Law):

NO EDITS. NOT TO CODE, NOT TO DESIGN.MD, NOT TO JOURNAL.MD.

Replace with:

NO EDITS. NOT TO CODE, NOT TO DESIGN.MD, NOT TO ANY JOURNAL FILE.

(c) Line 109 (Process Step 1):

1. Read the standing list, in this order: CLAUDE.md → DESIGN.md → JOURNAL

Replace with:

1. Read the standing list, in this order: CLAUDE.md → DESIGN.md → `docs/journals/INDEX.md` + the per-iter files

(d) Lines 60, 70, 71, 77, 155 — conceptual references ("JOURNAL ticket", "most recent JOURNAL entry", "JOURNAL citation", "JOURNAL truthfulness", "JOURNAL says…"). Keep as-is.

  • Step 3: skills/audit/agents/ailang-bencher.md

(a) Line 40 (standing reading list):

3. `docs/JOURNAL.md` — most recent entries are the current state of

Replace with:

3. `docs/journals/INDEX.md` + the latest 3 referenced files — current state of

(b) Line 43 ("any prior bench results recorded in JOURNAL"):

4. `bench/run.sh` and any prior bench results recorded in JOURNAL.

Replace with:

4. `bench/run.sh` and any prior bench results recorded in the per-iter journals.

(c) Line 53 (carrier-contract row "Pointer to existing JOURNAL bench entries"):

| `prior_data` | Pointer to existing JOURNAL bench entries that frame this question, or `none` |

Replace with:

| `prior_data` | Pointer to existing per-iter-journal bench entries that frame this question, or `none` |

(d) Line 148 ("DESIGN.md / JOURNAL.md edits"):

- DESIGN.md / JOURNAL.md edits. The orchestrator writes those based on

Replace with:

- DESIGN.md / journal edits. The orchestrator writes those based on
  • Step 4: skills/audit/agents/ailang-docwriter.md

(a) Line 35:

3. The most recent entries in `docs/JOURNAL.md` — to know which crates

Replace with:

3. The most recent entries linked from `docs/journals/INDEX.md` — to know which crates

(b) Line 80 ("DESIGN.md, JOURNAL.md, the ail CLI"):

- **Cross-repo references** (DESIGN.md, JOURNAL.md, the `ail` CLI

Replace with:

- **Cross-repo references** (DESIGN.md, journals, the `ail` CLI

(c) Line 90:

- No edits in `docs/`. The orchestrator owns DESIGN.md and JOURNAL.md.

Replace with:

- No edits in `docs/`. The orchestrator owns DESIGN.md and the journal files.

(d) Line 141:

- About to edit `docs/DESIGN.md` or `docs/JOURNAL.md`

Replace with:

- About to edit `docs/DESIGN.md` or any file under `docs/journals/` / `docs/journal-archive.md`
  • Step 5: skills/brainstorm/SKILL.md

(a) Line 59 (path reference in standing reading):

- Read the latest entries in `docs/JOURNAL.md` (most recent

Replace with:

- Read the latest entries linked from `docs/journals/INDEX.md` (most recent

(b) Lines 191, 194 — conceptual ("write a JOURNAL entry", "JOURNAL the impasse"). Keep as-is; these now refer to writing a per-iter journal, which is still called "a JOURNAL entry" in the discipline.

  • Step 6: skills/debug/agents/ailang-debugger.md

(a) Line 27 (standing reading list):

3. `docs/JOURNAL.md` — most recent entries; the last iteration may have

Replace with:

3. `docs/journals/INDEX.md` + the latest referenced file — the last iteration may have

(b) Line 128 — conceptual ("JOURNAL entry didn't flag"). Keep as-is.

(c) Line 155 ("DESIGN.md / JOURNAL.md edits"):

- DESIGN.md / JOURNAL.md edits.

Replace with:

- DESIGN.md / journal edits.
  • Step 7: skills/fieldtest/agents/ailang-fieldtester.md

(a) Line 44 (standing reading list):

3. `docs/JOURNAL.md` (most recent ~10 entries) — what shipped, what

Replace with:

3. `docs/journals/INDEX.md` and the latest ~5 referenced files — what shipped, what

(b) Line 62:

If `axis_hints` is empty, infer from JOURNAL tail and the milestone

Replace with:

If `axis_hints` is empty, infer from the latest per-iter journals and the milestone

(c) Line 95:

   JOURNAL + spec + `axis_hints`.

Replace with:

   latest per-iter journals + spec + `axis_hints`.

(d) Line 219 — conceptual ("separate JOURNAL entry's claim"). Replace "JOURNAL entry" with "journal entry" (lowercase) for clarity, no path:

  separate JOURNAL entry's claim is contradicted by what you saw,

Replace with:

  separate per-iter journal entry's claim is contradicted by what you saw,

(e) Line 221:

- `NEEDS_CONTEXT``axis_hints` empty AND JOURNAL/spec do not

Replace with:

- `NEEDS_CONTEXT``axis_hints` empty AND per-iter journals/spec do not

(f) Line 223 — same paragraph, conceptual ("JOURNAL entry was thin"):

  examples (rare; usually means the JOURNAL entry was thin).

Replace with:

  examples (rare; usually means the per-iter journal entry was thin).

(g) Line 251:

- Edits to `docs/DESIGN.md` or `docs/JOURNAL.md`. Spec gaps are

Replace with:

- Edits to `docs/DESIGN.md` or any journal file. Spec gaps are
  • Step 8: skills/implement/agents/ailang-implementer.md (JOURNAL refs only)

(a) Line 32 (standing reading list):

3. `docs/JOURNAL.md` — the most recent milestone-relevant entries. The latest

Replace with:

3. `docs/journals/INDEX.md` + the latest 13 milestone-relevant per-iter files. The latest

(b) Line 89 — conceptual ("flagged in the JOURNAL"). Keep as-is.

(c) Line 102 (Process Step 1):

1. Read the standing list (CLAUDE.md, DESIGN.md, JOURNAL.md tail).

Replace with:

1. Read the standing list (CLAUDE.md, DESIGN.md, latest per-iter journals).

Carrier-section edits (Step 1 of this agent's Process, plus the carrier contract block) are NOT done here — they belong to Task 4.

  • Step 9: skills/implement/agents/ailang-tester.md

(a) Line 27 (standing reading list):

2. `docs/JOURNAL.md` — most recent iteration entries; they tell you what

Replace with:

2. `docs/journals/INDEX.md` + the latest 13 referenced files — most recent iteration entries; they tell you what

(b) Line 78 ("Commit per existing JOURNAL style"):

5. Commit per existing JOURNAL style (`iter <X>.<n>: e2e for <feature>`).

Replace with:

5. Commit per existing journal style (`iter <X>.<n>: e2e for <feature>`).
  • Step 10: skills/README.md (JOURNAL refs only)

(a) Line 11:

`docs/JOURNAL.md` ("Skill system live") for the rationale.

Replace with:

`docs/journal-archive.md` ("Skill system live") for the rationale.

(b) Line 19 (table row, conceptual "JOURNAL entry"):

| [`implement`](implement/SKILL.md) | Plan exists | Code + tests + per-task commits + JOURNAL entry | Standard iteration path |

Replace with:

| [`implement`](implement/SKILL.md) | Plan exists | Code + tests + per-task commits + per-iter journal entry | Standard iteration path |

(c) Line 37 — conceptual ("ratify-> JOURNAL"). Keep "JOURNAL" as-is: this is a process arrow naming the act of recording.

(d) Line 81 (standing-reading-list paragraph in template description):

  DESIGN.md, JOURNAL.md tail, plus role-specific anchors).

Replace with:

  DESIGN.md, latest per-iter journals, plus role-specific anchors).

(e) Line 139:

  the question in `docs/JOURNAL.md` before adding the agent.

Replace with:

  the question via a per-iter journal entry before adding the agent.

(f) Line 145 (same paragraph as line 81 conceptually):

  of the agent's standing reading list (CLAUDE.md, DESIGN.md, JOURNAL.md

Replace with:

  of the agent's standing reading list (CLAUDE.md, DESIGN.md, latest per-iter journals

(g) Line 171:

   raise the question in `docs/JOURNAL.md` first.

Replace with:

   raise the question via a per-iter journal entry first.
  • Step 11: Verify

Run: grep -rln "JOURNAL.md" CLAUDE.md docs/DESIGN.md docs/roadmap.md skills/ Expected: empty output. Path JOURNAL.md no longer appears in any active reading list.

Run: grep -rn "docs/JOURNAL" CLAUDE.md docs/DESIGN.md docs/roadmap.md skills/ Expected: empty output.

(Historical files in docs/plans/, docs/specs/, and docs/WhatsNew.md are intentionally NOT scanned — they are dated artifacts.)

  • Step 12: Commit
git add skills/ CLAUDE.md docs/DESIGN.md docs/roadmap.md
git commit -m "iter or.1.3: repoint skill + agent reading lists to docs/journals/"

(CLAUDE.md, DESIGN.md, roadmap.md were already committed in or.1.2 — git add will simply find nothing new there; this is safe.)


Task 4: Carrier change — task_text → task_text_path on implementer + spec-reviewer

Files:

  • Modify: skills/implement/agents/ailang-implementer.md (carrier section + Process Step 1 mention)
  • Modify: skills/implement/agents/ailang-spec-reviewer.md (carrier section)

The change: the carrier field for the task text moves from an inline string (task_text: "<verbatim block>") to a file path (task_text_path: "/tmp/ail-iter/<iter_id>/task-<N>.md"). The agent reads the file as its first action. This eliminates per-task duplication of the task text between the implementer and spec-reviewer dispatches.

  • Step 1: Read ailang-implementer.md carrier-contract block

The file currently has a Carrier-contract section (look for ## Carrier contract or ## Carrier heading). Read it to locate the task_text row.

  • Step 2: Patch ailang-implementer.md — Carrier-contract block

Find the row that defines task_text:

| `task_text` | The verbatim text of the task block, copied from the plan |

(Exact phrasing may differ slightly — match by the cell containing task_text and "verbatim"/"plan".)

Replace with:

| `task_text_path` | Absolute path to a file (typically `/tmp/ail-iter/<iter_id>/task-<N>.md`) containing the verbatim task block extracted from the plan. Read this file as your first action. |
  • Step 3: Patch ailang-implementer.md — Process Step 1 (or wherever task_text is first read)

Find any mention in the Process section that the agent receives the task as an inline string (typical phrasing: "Read the task text the controller handed you" or "The task_text you received…"). Replace with: "Read the file at task_text_path — that is your task block."

If no such mention exists (the agent file relies entirely on the carrier contract), the carrier change in Step 2 is sufficient; do not invent text.

  • Step 4: Patch ailang-spec-reviewer.md — Carrier-contract block

The spec-reviewer carrier contract typically has a task_text row identical in spirit to the implementer's. Apply the same replacement:

| `task_text` | The verbatim text of the task block, identical to what the implementer received |

Replace with:

| `task_text_path` | Absolute path (typically `/tmp/ail-iter/<iter_id>/task-<N>.md`) — same file the implementer received. Read this file as your first action. |
  • Step 5: Patch ailang-spec-reviewer.md — first-action mention

Same as Task 4 Step 3 but for the spec-reviewer. Any phrasing like "Compare the task_text against the diff" → "Read the file at task_text_path; compare it against the diff."

If no inline mention exists, the carrier change is sufficient.

  • Step 6: Verify

Run: grep -n "task_text\b" skills/implement/agents/ailang-implementer.md skills/implement/agents/ailang-spec-reviewer.md Expected: empty output. The literal task_text (without _path suffix) no longer appears.

Run: grep -n "task_text_path" skills/implement/agents/ailang-implementer.md skills/implement/agents/ailang-spec-reviewer.md Expected: at least one match per file — typically two (carrier contract row + first-action mention).

  • Step 7: Commit
git add skills/implement/agents/ailang-implementer.md skills/implement/agents/ailang-spec-reviewer.md
git commit -m "iter or.1.4: carrier switch task_text -> task_text_path"

Task 5: Create new agent — ailang-implement-orchestrator

Files:

  • Create: skills/implement/agents/ailang-implement-orchestrator.md

The new agent follows the standard agent template documented in skills/README.md ("Agent structure" section). The content below is the verbatim file to write — no inventing structure, no skipping sections, no abbreviating.

  • Step 1: Write the agent file

Create skills/implement/agents/ailang-implement-orchestrator.md with the following content:

---
name: ailang-implement-orchestrator
description: Use to run one full /implement iteration in a dedicated subagent context. Carries the per-task loop end-to-end — implementer → spec-reviewer → quality-reviewer, with the canonical re-loop limits — on an isolated branch (`iter/<iter_id>`), writes a per-iter journal file, writes a stats file, returns a ≤500-token end-report. The named exception to "agents do not call other agents".
tools: Read, Edit, Write, Bash, Glob, Grep, Agent
---

# ailang-implement-orchestrator — per-iter loop in isolated context

> **Violating the letter of these rules is violating the spirit.**

## What this role is for

The Boss-Orchestrator's context grew by ~100k tokens per `/implement`
run before this role existed — plan loaded once, task text duplicated
between implementer and spec-reviewer dispatches, review re-loops
amortised against the Boss's context budget. This agent absorbs that
entire loop into its own context and reports back compressed.

The role exists to make context-cost proportional to *outcome*, not
to per-task chatter. Every decision-relevant signal the Boss needs
goes into the end-report; everything else stays inside this agent's
context and dies with it.

## Standing reading list

Read these before doing anything else, in this order:

1. `CLAUDE.md` — orchestrator framing, in particular the
   "Done-state notifications: WhatsNew.md" subsection (WhatsNew is
   Boss-side, NOT this agent's job).
2. `docs/DESIGN.md` — invariants any iter must respect.
3. `docs/journals/INDEX.md` plus the last 13 per-iter journal
   files it points at — recent state of the project.
4. `skills/implement/SKILL.md` — the **canonical discipline**
   (Iron Law, per-task sub-status table, common rationalisations).
   Re-read every dispatch; do not paraphrase from memory.

Do NOT read `docs/journal-archive.md` by default; it is pre-2026-05-11
history.

## Carrier contract

You receive from the Boss-Orchestrator:

| Field | Content |
|-------|---------|
| `mode` | `"standard"` or `"mini"` |
| `iter_id` | e.g. `"ct.2.3"` (standard) or `"bugfix-<short-symptom>"` (mini). Used for branch name, scratch dir, journal filename, stats filename, commit subjects |
| `plan_path` | (standard only) `docs/plans/<file>.md` |
| `task_range` | (standard, optional) e.g. `[3, 8]` — run only Tasks 3..8 inclusive |
| `red_test_path` | (mini only) absolute path to the RED test from `debug` |
| `cause_summary` | (mini only) 12 sentences from the debugger agent |
| `constraint` | (mini only) `"minimal fix, no surrounding cleanup"` |

You produce on return: the fixed-format end-report (see Output format).
You do NOT touch `docs/journals/INDEX.md` and you do NOT merge the
branch — both are Boss-side.

## The Iron Law

ONE BRANCH PER ITER — iter/<iter_id>, created from origin/main. FRESH SUBAGENT PER TASK (implementer, then spec-reviewer, then quality-reviewer). TWO-STAGE REVIEW PER TASK: SPEC COMPLIANCE FIRST, CODE QUALITY SECOND. NEVER START QUALITY REVIEW BEFORE SPEC COMPLIANCE IS GREEN. NEVER PUSH PAST BLOCKED BY HAND — RETURN BLOCKED TO THE BOSS. WRITE THE PER-ITER JOURNAL FILE BEFORE RETURNING — EVEN ON BLOCKED.


## The Process

### Phase 0 — Branch setup (always first)

1. `git fetch origin main`
2. If a branch named `iter/<iter_id>` already exists locally
   (Boss-side repair re-dispatch): `git switch iter/<iter_id>`.
   Otherwise: `git switch -c iter/<iter_id> origin/main`.
3. Record `pre_iter_sha = $(git rev-parse HEAD)` for the end-report.
4. Create scratch dir: `mkdir -p /tmp/ail-iter/<iter_id>`.

### Phase 1 — Load context (mode-dependent)

**Standard mode:**

- Read `plan_path` once. Extract every task with its verbatim block.
- For each task K in scope (full plan if no `task_range`, else
  `task_range[0]..=task_range[1]`), write the verbatim block to
  `/tmp/ail-iter/<iter_id>/task-K.md`.
- Note shared cross-task context (file paths, type names, naming
  conventions) for the `cross_task_context` carrier field.

**Mini mode:**

- Read the RED test at `red_test_path`.
- Compose a single one-task description into
  `/tmp/ail-iter/<iter_id>/task-1.md` of the form:

Make this RED test pass: <red_test_path>

Cause (from debugger): <cause_summary>

Constraint:


- No multi-task expansion.

### Phase 2 — Per-task loop

For each task K in TodoWrite order (use TodoWrite to track tasks as
status changes — but TodoWrite items live in YOUR context, not the
Boss's):

#### 2.1 — Dispatch implementer

`Agent("ailang-implementer", { task_text_path: "/tmp/ail-iter/<iter_id>/task-K.md", scene_set: ..., cross_task_context: ..., mode: ... })`.

#### 2.2 — Handle implementer status

Follow the per-task sub-status table in `skills/implement/SKILL.md`
verbatim. Re-loop limit: ≤ 2 retries with expanded context for
`NEEDS_CONTEXT`. 3rd → return `BLOCKED` to Boss (reason
`context-exhausted`).

#### 2.3 — Spec-compliance review

On implementer DONE / DONE_WITH_CONCERNS, dispatch
`ailang-spec-reviewer` with `task_text_path` (same file the
implementer read), `pre_task_sha`, `head_sha`,
`status_from_implementer`.

`non_compliant`: re-dispatch the implementer with the reviewer's
report as repair brief. Re-loop limit: ≤ 2 retries. 3rd → return
`BLOCKED` (reason `review-loop-exhausted`).

`unclear`: STOP. Return `BLOCKED` to Boss (reason
`spec-ambiguous`, quote the reviewer's `unclear` reasoning).

#### 2.4 — Quality review

Only after spec is `compliant`. Dispatch `ailang-quality-reviewer`
with `pre_task_sha`, `head_sha`, `spec_review_status: "compliant"`,
`task_subject` (one-line title; NOT the full task text).

`changes_requested`: implementer fixes `Important` + `Minor` issues;
re-dispatch reviewer. Re-loop ≤ 2. 3rd → `BLOCKED`
(`review-loop-exhausted`).

#### 2.5 — Task done

TodoWrite update; proceed to next task.

### Phase 3 — E2E coverage (standard mode, on full-iter completion)

Dispatch `ailang-tester` with `iteration_scope`, `coverage_gap` (if
known), `mode: "e2e_after_iter"`. Tester writes E2E fixtures and
commits them on the branch.

(Mini mode: skip Phase 3 — the RED test from `debug` IS the
coverage.)

### Phase 4 — Write per-iter journal file

Write `docs/journals/<YYYY-MM-DD>-iter-<iter_id>.md` (date is today,
not the iter's plan date). Template:

```markdown
# iter <iter_id> — <one-line title>

**Date:** YYYY-MM-DD
**Branch:** iter/<iter_id>
**Status:** DONE | PARTIAL | BLOCKED
**Tasks completed:** <N> of <total>

## Summary

<1-paragraph summary; the Boss may rewrite this section during merge>

## Per-task subjects

- iter <iter_id>.1: <commit subject>
- iter <iter_id>.2: <commit subject>
- ...

## Concerns

<aggregated DONE_WITH_CONCERNS lines, one per task; empty list if none>

## Known debt

<one-liner each, with why-not-touched; empty list if none>

## Blocked detail

<only if BLOCKED / PARTIAL: task N, reason from the sub-status table,
worker's verbatim BLOCKED text, suggested next step>

## Commits

<pre_iter_sha>..<head_sha>

## Stats

bench/orchestrator-stats/<YYYY-MM-DD>-iter-<iter_id>.json

Commit on the branch:

git add docs/journals/<file>.md
git commit -m "iter <iter_id>: per-iter journal"

Phase 5 — Write stats file

Write bench/orchestrator-stats/<YYYY-MM-DD>-iter-<iter_id>.json with at least these fields:

{
  "iter_id": "<iter_id>",
  "date": "YYYY-MM-DD",
  "mode": "standard|mini",
  "outcome": "DONE|PARTIAL|BLOCKED",
  "tasks_total": <int>,
  "tasks_completed": <int>,
  "reloops_per_task": { "1": 0, "2": 1, ... },
  "review_loops_spec": <int>,
  "review_loops_quality": <int>,
  "blocked_reason": "<one of: context-exhausted | review-loop-exhausted | worker-blocked | spec-ambiguous | infra | null>"
}

Commit on the branch:

git add bench/orchestrator-stats/<file>.json
git commit -m "iter <iter_id>: orchestrator stats"

Phase 6 — Return end-report

Compose the end-report per Output format below. Do NOT push the branch — the Boss decides on integration. Do NOT touch docs/journals/INDEX.md — Boss-only.

Status protocol

The agent returns exactly one of:

  • DONE — full iter (or the requested task_range) completed; all reviews green; journal + stats committed on branch.
  • PARTIAL — some tasks completed cleanly, then one task hit the re-loop limit or a hard BLOCKED. Earlier task commits remain on the branch; journal records Status: PARTIAL.
  • BLOCKED — no task in the scope completed cleanly (typically Phase 0 or the first task failed irrecoverably).
  • NEEDS_CONTEXT — the carrier from the Boss was missing required fields (no plan_path in standard mode, no red_test_path in mini mode, malformed iter_id). Distinct from per-task NEEDS_CONTEXT, which is handled inside Phase 2 and never bubbles up.

Output format — end-report

Plain-text, ≤ 500 tokens, fixed structure:

Status:           DONE | PARTIAL | BLOCKED | NEEDS_CONTEXT
Iter:             <iter_id>
Branch:           iter/<iter_id>
Tasks completed:  <N> of <total>
                  - <commit subject 1>
                  - <commit subject 2>
                  ...
Journal file:     docs/journals/<YYYY-MM-DD>-iter-<iter_id>.md (on branch)
Stats:            bench/orchestrator-stats/<YYYY-MM-DD>-iter-<iter_id>.json (on branch)
Commits:          <pre_iter_sha>..<head_sha>
Tests:            <count> green, <count> red
E2E coverage:     <new fixture paths, or "none (mini mode)">
Blocked detail:   (only if BLOCKED or PARTIAL)
                  Task: <N>
                  Reason: context-exhausted | review-loop-exhausted | worker-blocked | spec-ambiguous | infra
                  Worker says: <verbatim reason from the worker's report>
                  Suggested next step: <one sentence>

Common rationalisations

Excuse Reality
"Plan said dispatch a single big task, I'll just inline it" Then the plan is wrong, or you misread it. Tasks are the unit of dispatch; refuse to inline.
"The implementer didn't return DONE_WITH_CONCERNS but flagged a concern in prose" A concern not in the structured status is invisible to you. Re-dispatch asking for the structured status; do not act on prose hints.
"I'll merge the branch myself, the Boss is busy" Out of scope. Merge is Boss-only. Branch + journal + stats sit until the Boss reads the end-report.
"BLOCKED on task 3, I'll skip to task 4" Skip is a Boss decision, not yours. Task dependencies are encoded in the plan and you do not know the graph. Return BLOCKED.
"Quality review fails repeatedly with Nits only — approve anyway" Re-dispatch the implementer with the Nits as advisory and have the reviewer re-issue approved. Nits don't gate, but the reviewer's verdict does.
"I forgot to commit the journal file before returning" Re-do Phase 4. Returning without the journal file committed is a bug, not a corner case.
"Stats file feels excessive on a one-task mini-mode run" The point of stats is empirical calibration of the re-loop limits and the failure-mode distribution. One-task runs ARE the data.

Red Flags — STOP

  • About to dispatch the implementer without reading skills/implement/SKILL.md first this dispatch.
  • About to edit docs/journals/INDEX.md.
  • About to push the branch to remote (any git push).
  • About to merge into main / rebase main / fast-forward main.
  • About to skip Phase 4 (journal file) "because the run is BLOCKED".
  • About to return more than 500 tokens of end-report.
  • About to dispatch the quality-reviewer before spec is compliant.
  • About to skip Phase 5 (stats file) "because mini mode".

- [ ] **Step 2: Verify the new file parses as agent frontmatter**

Run: `head -5 skills/implement/agents/ailang-implement-orchestrator.md`
Expected: lines 1-4 form a valid YAML frontmatter block (`---`, three
`key: value` lines, `---`).

- [ ] **Step 3: Commit**

```bash
git add skills/implement/agents/ailang-implement-orchestrator.md
git commit -m "iter or.1.5: new agent ailang-implement-orchestrator"

Task 6: Rewrite skills/implement/SKILL.md

Files:

  • Modify: skills/implement/SKILL.md (full rewrite, ~210 → ~100 lines)

The rewrite delegates both Standard-Mode and Mini-Mode to the new orchestrator-agent and documents the Boss-side merge step. The Iron Law, per-task sub-status table, and Common Rationalisations remain — they are the canonical discipline source, read by the orchestrator- agent every dispatch.

  • Step 1: Replace the file body

Overwrite skills/implement/SKILL.md with this exact content:

---
name: implement
description: Use when an implementation plan exists in docs/plans/ and is ready to execute, OR when a debug RED-test is handed off for a bugfix. Dispatches the ailang-implement-orchestrator agent, which runs the entire per-task loop (implementer → spec-reviewer → quality-reviewer) on an isolated branch `iter/<iter_id>`, writes a per-iter journal + stats file, and returns a compressed end-report. The Boss reads the end-report, optionally rewrites the journal Summary section, appends one line to docs/journals/INDEX.md, and rebases onto main.
---

# implement — plan execution via a dedicated orchestrator-agent

> **Violating the letter of these rules is violating the spirit.**

## Overview

Plan execution is fully delegated. The Boss-Orchestrator dispatches
ONE subagent (`ailang-implement-orchestrator`), which runs the entire
per-task loop in its own context: implementer → spec-reviewer →
quality-reviewer, per task, with the Iron Law and re-loop limits
below. All commits land on a dedicated branch `iter/<iter_id>`.
The Boss sees one ≤500-token end-report and a per-iter journal file
on the branch.

This skill body is intentionally short. The procedural details of
the per-task loop live in
`skills/implement/agents/ailang-implement-orchestrator.md`. The
**canonical discipline** (Iron Law, sub-status table, common
rationalisations) lives in this file and is read by the
orchestrator-agent every dispatch.

## When to Use / Skipping

Triggers:
- A plan exists at `docs/plans/<iteration>.md` (standard mode).
- A `debug` skill has produced a RED test + cause and is handing off
  for the GREEN side (mini mode).

**Never skipped** when there is code to ship. Trivial mechanical
edits (one-line typo fix, schema rename across N files) MAY be
handled inline by the Boss without dispatch, per CLAUDE.md "trivial
mechanical edits" carve-out — but no review-and-commit discipline
is shed.

## The Iron Law

ONE BRANCH PER ITER — iter/<iter_id>, created from origin/main. FRESH SUBAGENT PER TASK — implementer, then spec-reviewer, then quality-reviewer. TWO-STAGE REVIEW: SPEC COMPLIANCE FIRST, CODE QUALITY SECOND. NEVER START QUALITY REVIEW BEFORE SPEC COMPLIANCE IS GREEN. NEVER PUSH PAST BLOCKED BY HAND. THE PER-ITER JOURNAL FILE IS WRITTEN BEFORE THE ORCHESTRATOR RETURNS — EVEN ON BLOCKED.


## Per-task sub-status mechanics

The orchestrator-agent reads and follows this table verbatim every
dispatch:

| Sub-status | Orchestrator action |
|------------|---------------------|
| `DONE` | next task / next phase |
| `DONE_WITH_CONCERNS` | accumulate concern, next |
| `NEEDS_CONTEXT` (1st2nd) | re-dispatch with expanded carrier |
| `NEEDS_CONTEXT` (3rd) | stop → `BLOCKED` to Boss, reason `context-exhausted` |
| `non_compliant` / `changes_requested` (1st2nd) | implementer re-dispatch with the reviewer's report as repair brief |
| `non_compliant` / `changes_requested` (3rd) | stop → `BLOCKED` to Boss, reason `review-loop-exhausted` |
| `BLOCKED` (worker) | stop → `BLOCKED` to Boss, reason verbatim |
| `unclear` (spec-reviewer) | stop → `BLOCKED` to Boss, reason `spec-ambiguous` |
| Tool / infra error | stop → `BLOCKED` to Boss, reason `infra` + raw error |

Re-loop limit: 2 retries per failure-mode per task. The 3rd is
`BLOCKED` to the Boss. `skip task K, continue` is intentionally NOT
a mode — tasks have implicit ordering dependencies and the
orchestrator does not know the dependency graph.

## The Process — Boss side

### Step 1 — Dispatch the orchestrator-agent

For a standard iteration:

Agent("ailang-implement-orchestrator", { mode: "standard", iter_id: "<iter_id>", // e.g. "ct.2.3", "or.1", "23.4" plan_path: "docs/plans/.md", task_range: [3, 8] // optional })


For a debug-handoff (mini mode):

Agent("ailang-implement-orchestrator", { mode: "mini", iter_id: "bugfix-", red_test_path: "", cause_summary: "<1-2 sentences from debugger>", constraint: "minimal fix, no surrounding cleanup" })


### Step 2 — Read the end-report

The orchestrator returns a ≤500-token plain-text report (see the
agent's "Output format — end-report" section for the fixed
structure). Read it. The end-report is the only thing that costs the
Boss-context tokens; per-task chatter has stayed inside the
orchestrator-agent.

### Step 3 — Boss merge step (on DONE / PARTIAL with partial DONE-tasks)

1. Open the per-iter journal file on the branch:
   `git show iter/<iter_id>:docs/journals/<YYYY-MM-DD>-iter-<iter_id>.md`
   (or check out the branch if a closer look is needed).
2. Accept the agent's Summary section as-is, OR rewrite it with
   Boss-level framing. The rest of the journal file is factual and
   preserved verbatim.
3. Append one line to `docs/journals/INDEX.md`:
   `- YYYY-MM-DD — iter <iter_id>: <one-line title> → <YYYY-MM-DD>-iter-<iter_id>.md`
4. Rebase the iter branch onto main:
   `git rebase iter/<iter_id> onto main` (or fast-forward if linear).
5. Optionally delete the branch: `git branch -D iter/<iter_id>`.
6. If trigger is done-state and the user is away, write a
   `docs/WhatsNew.md` entry + `notify.sh` per CLAUDE.md's
   "Done-state notifications" subsection.

### Step 4 — Boss handling (on BLOCKED)

1. Read the per-iter journal on the branch — `Blocked detail:` names
   the failure mode.
2. Decide:
   - **Repair:** adjust plan or extend context; re-dispatch the
     orchestrator with the same `iter_id` and a `task_range` covering
     the remaining tasks. The orchestrator picks up the existing
     branch.
   - **Discard:** `git branch -D iter/<iter_id>`. INDEX.md is NOT
     touched (the orchestrator did not append).
   - **Escalate:** ask the user via `notify.sh`. The branch sits
     until the conversation resumes.

## Handoff Contract

`implement` consumes:

| Source | Carrier |
|--------|---------|
| from `planner` | path to `docs/plans/<iteration>.md` (+ optional `task_range`) |
| from `debug` | RED-test path + cause summary + minimal-fix constraint |

`implement` produces: a feature branch `iter/<iter_id>` carrying
per-task commits, a per-iter journal file (`docs/journals/<file>.md`),
and a stats file (`bench/orchestrator-stats/<file>.json`). The Boss
merges and updates `docs/journals/INDEX.md`. No further hand-off —
`audit` runs independently at milestone close.

## Common Rationalisations

| Excuse | Reality |
|--------|---------|
| "Single task, dispatch overhead exceeds the work" | The orchestrator-agent IS the discipline. A single dispatch is cheap; the per-task review loop, the branch isolation, and the journal file are the value. |
| "I'll merge on main directly, no need for the iter branch" | The branch is what makes parallel `/implement` activity safe and makes "discard on BLOCKED" trivial. Skipping it puts you back in the pre-2026-05-11 coordination problems. |
| "BLOCKED end-report, let me dig into the branch and continue myself" | Read the `Blocked detail:` first. The orchestrator stopped at the re-loop limit for a reason. Continuing by hand undoes the discipline. |
| "End-report says PARTIAL with 4/5 DONE — close to enough" | The 5th task may carry an invariant the earlier 4 silently depend on. Either re-dispatch for the missing task or treat the iter as incomplete. |
| "Skip the INDEX line, the journal file is enough" | INDEX.md is the only thing that makes per-iter journals navigable. Without it, future agents have to ls the directory and parse filenames. |
| "I'll let the orchestrator-agent update INDEX.md" | No. INDEX.md is Boss-only. The orchestrator-agent does not know what `<one-line title>` the Boss will pick. |

## Red Flags — STOP

- Boss dispatching `ailang-implementer` directly (bypassing the
  orchestrator-agent).
- Boss editing a per-iter journal file on `main` instead of on its
  iter branch.
- Two `/implement` runs sharing one `iter_id`.
- INDEX.md modified by anything other than the Boss.
- Branch `iter/<iter_id>` pushed to remote before the merge step
  decided what to do with it.
- End-report longer than ~500 tokens.

## Cross-references

- **Agent dispatched:**
  `skills/implement/agents/ailang-implement-orchestrator.md` —
  carries the per-task loop, including dispatch of:
  - `skills/implement/agents/ailang-implementer.md` (Phase 2.1)
  - `skills/implement/agents/ailang-spec-reviewer.md` (Phase 2.3)
  - `skills/implement/agents/ailang-quality-reviewer.md` (Phase 2.4)
  - `skills/implement/agents/ailang-tester.md` (Phase 3)
- **Input sources:**
  - `skills/planner/SKILL.md` — produces the plan files this skill
    consumes
  - `skills/debug/SKILL.md` — produces the RED-test handoff for
    mini-mode
- **Output target:** Boss reads the end-report and the per-iter
  journal; `audit` runs at milestone close.
- **Documented exception:** in `skills/README.md`, this is the named
  exception to "agents do not call other agents".
  • Step 2: Verify

Run: wc -l skills/implement/SKILL.md Expected: between 110 and 160 lines (rough sanity; spec said ~100).

Run: grep -c "Iron Law" skills/implement/SKILL.md Expected: ≥ 1. (Discipline source preserved.)

Run: grep -c "Per-task sub-status" skills/implement/SKILL.md Expected: 1. (Sub-status table preserved.)

  • Step 3: Commit
git add skills/implement/SKILL.md
git commit -m "iter or.1.6: rewrite skills/implement/SKILL.md to delegate to orchestrator-agent"

Task 7: One-line exception note in skills/README.md + agent-roster row

Files:

  • Modify: skills/README.md

  • Step 1: Patch the "Agents do not call other agents" line

Find this paragraph in the ## Conventions section (currently near the bottom of the file):

- **Agents do not call other agents.** The dirigierende skill
  composes (e.g. `implement` dispatches implementer, then a separate
  spec-compliance reviewer, then a code-quality reviewer).

Replace with:

- **Agents do not call other agents — one named exception.** The
  dirigierende skill composes (e.g. `audit` dispatches architect, then
  bencher, then docwriter). The single exception is
  `ailang-implement-orchestrator`, which runs the per-task implementer
  → spec-reviewer → quality-reviewer loop on its own; this exception
  is documented in `skills/implement/SKILL.md` and exists to keep
  per-iter chatter out of the Boss-context. No other agent gains the
  `Agent` tool.
  • Step 2: Add the orchestrator-agent to the agent roster table

Find the agent roster table (starts with | Agent | Path | Dispatched by skill |). Insert this row immediately above the ailang-implementer row:

| `ailang-implement-orchestrator` | `implement/agents/` | `implement` (the only agent with the `Agent` tool; runs the per-task loop) |
  • Step 3: Verify

Run: grep -n "ailang-implement-orchestrator" skills/README.md Expected: 1 match (the new roster row).

Run: grep -c "one named exception" skills/README.md Expected: 1.

  • Step 4: Commit
git add skills/README.md
git commit -m "iter or.1.7: document ailang-implement-orchestrator as named exception"

Verification ladder (post-implementation, manual)

Run after all seven tasks have committed. The ladder is the 8-step list from the parent spec §"Testing strategy". Steps 15 are sanity checks the Boss can run inline; steps 67 require an intentionally failing fixture and are deferred to the first real /implement run that hits a re-loop; step 8 is performed live on the first successful orchestrator-agent dispatch.

  • Ladder 1: Agent file parses

Agent("ailang-implement-orchestrator", { mode: "standard", iter_id: "smoke-test", plan_path: "docs/plans/<an existing tiny plan>" }) on a one-task no-op plan resolves and returns either DONE or a structured BLOCKED. (Defer to the first real iter — no synthetic fixture is required for this ladder pass.)

  • Ladder 2: Branch isolation

After Ladder 1's dispatch: git branch | grep iter/smoke-test Expected: branch exists. git diff main..iter/smoke-test shows commits.

  • Ladder 3: Single-task standard-mode run

First real one-task /implement after the refactor lands. Expected: green build, green tests on the branch, journal file at docs/journals/<date>-iter-<id>.md on the branch, stats file at bench/orchestrator-stats/<date>-iter-<id>.json on the branch, end-report in the fixed format.

  • Ladder 4: Multi-task standard-mode run

First real 3+-task /implement after the refactor lands. Same shape as Ladder 3.

  • Ladder 5: Mini-mode run

First real debug/implement mini-mode handoff after the refactor lands. Expected: end-report in same shape, branch named iter/bugfix-<>, no Phase 3 (E2E coverage) — the RED test is the coverage.

  • Ladder 6: Re-loop run (deferred)

Marked complete once a real iter hits 2 review re-loops on the same task and the orchestrator returns BLOCKED with reason review-loop-exhausted.

  • Ladder 7: BLOCKED run (deferred)

Marked complete once a real iter hits a worker BLOCKED and the orchestrator returns BLOCKED with the worker's reason verbatim.

  • Ladder 8: Boss-merge step

On Ladder 3 or 4's successful run: manually integrate — read journal, write INDEX line, rebase, optionally delete branch. Verify linear history with git log --oneline main..HEAD showing no merge commits and INDEX.md gaining exactly one line.

The ladder is not committed as code; it is a Boss checklist. Ladders 15 should be runnable inside the same session that lands the refactor. Ladders 68 are recorded as "passed on first encounter" in the next per-iter journal that hits them.


Out of scope

Per parent spec §"Out of scope":

  • Worker model downgrade — all roles stay at Opus 4.7.
  • Stats aggregation tool — written once empirical data exists.
  • Plan-drafter sub-agent for /planner.
  • /brainstorm spec-drafter.
  • docs/DESIGN.md semantic changes (only the JOURNAL.md → journals reference is updated in Task 2).
  • External-platform integration (Gitea PRs, GitHub mirror).

Acceptance

This plan is accepted as complete when all seven tasks have green commits, the post-implementation Verification Ladder steps 15 pass inline, and Ladders 68 are tracked for "pass on first encounter" in the next iter's journal that exercises them.