fc0e1d0d46
Per-skill prose tightening from the same audit swarm; each finding passed an adversarial second reviewer. No behavioural change. - audit: drop garbled "Conventions require deferred audits to compound" sentence (says the opposite of intent; the preceding line already closes the loophole). - brainstorm: drop forward-pointing meta-comment about the Rationalisations table. - debug: drop third restatement that debugger.md is the single source for the carrier/handoff fields. - docwriter: drop motivational opener; Overview starts at the waste argument. - fieldtest: fold the 2-4-examples rationale into the dispatch sentence instead of restating the count a fourth time. - implement: drop "known platform constraint at the time" aside. - planner: cut the verbose anti-drift paragraph (which restated the very table it claimed not to) down to a cross-reference. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
255 lines
13 KiB
Markdown
255 lines
13 KiB
Markdown
---
|
|
name: implement
|
|
description: Use when an implementation plan exists under paths.plan_dir and is ready to execute, OR when a debug RED-test is handed off for a bugfix. Dispatches the implement-orchestrator agent, which runs the entire per-task loop (implementer phase → spec-compliance check → quality check, as sequential role-switches in its own context) directly in the working tree without creating commits, writes a stats file (and on BLOCKED/PARTIAL also `BLOCKED.md`), and returns a compressed end-report. The orchestrator reads the end-report, inspects the working tree, decides commit shape, and performs all commits.
|
|
---
|
|
|
|
# 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 orchestrator dispatches
|
|
ONE subagent (`implement-orchestrator`), which runs the entire
|
|
per-task loop in its own context: implementer phase → spec-
|
|
compliance check → quality check, per task, as sequential
|
|
role-switches inside the orchestrator-agent itself (Claude
|
|
Code does not permit nested subagent dispatch — see
|
|
Cross-references). All work lives in the working tree: code
|
|
edits and the stats file (and `BLOCKED.md` if the outcome is
|
|
PARTIAL/BLOCKED). The orchestrator-agent does NOT commit.
|
|
The orchestrator sees one ≤500-token end-report and an
|
|
unstaged working tree, then decides commit shape — the
|
|
end-report carries the per-task summary the orchestrator
|
|
uses to write the commit body.
|
|
|
|
This skill body is intentionally short. The procedural
|
|
details of the per-task loop live in
|
|
`agents/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 under `paths.plan_dir` (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 orchestrator without
|
|
dispatch, per the project's CLAUDE.md "trivial mechanical
|
|
edits" carve-out — but no review-and-commit discipline is
|
|
shed.
|
|
|
|
## The Iron Law
|
|
|
|
```
|
|
THE IMPLEMENTER NEVER COMMITS. CODE EDITS AND THE STATS FILE LIVE IN THE WORKING TREE AS UNSTAGED CHANGES UNTIL THE ORCHESTRATOR COMMITS THEM.
|
|
MAIN HEAD IS SACROSANCT — NO RESET, NO REVERT, BY ANY ACTOR. MAIN MOVES FORWARD ONLY VIA ORCHESTRATOR COMMITS.
|
|
PER-TASK PHASES RUN SEQUENTIALLY IN THE ORCHESTRATOR-AGENT'S OWN CONTEXT — implementer phase, then spec-compliance check, then quality check. Each phase is a deliberate role-switch, NOT a fresh subagent (nested-subagent dispatch is forbidden by Claude Code).
|
|
TWO-STAGE CHECK PER TASK: SPEC COMPLIANCE FIRST, CODE QUALITY SECOND.
|
|
NEVER START THE QUALITY CHECK BEFORE THE SPEC-COMPLIANCE CHECK IS GREEN.
|
|
NEVER PUSH PAST `BLOCKED` BY HAND.
|
|
ON `PARTIAL` OR `BLOCKED`, THE ORCHESTRATOR-AGENT WRITES `BLOCKED.md` AT THE REPO ROOT BEFORE RETURNING — UNCOMMITTED BY CONVENTION. ON `DONE`, NO SEPARATE FILE.
|
|
```
|
|
|
|
## Per-task sub-status mechanics
|
|
|
|
Each dispatch, the orchestrator-agent runs an internal per-task
|
|
loop over a sub-status vocabulary — `DONE`, `DONE_WITH_CONCERNS`,
|
|
`NEEDS_CONTEXT`, `non_compliant` / `changes_requested`, `BLOCKED`,
|
|
`unclear`, and tool/infra errors — bounded by a 2-retries-per-
|
|
failure-mode re-loop limit (the 3rd attempt escalates to
|
|
`BLOCKED`). These values are *internal* to the orchestrator-agent:
|
|
they describe the state of an inline role-phase, not a separate
|
|
subagent, and are not reported upstream.
|
|
|
|
The mapping of each value to its action (and the `BLOCKED` reasons
|
|
`context-exhausted` / `review-loop-exhausted` / `spec-ambiguous` /
|
|
`infra`) is defined authoritatively under **Per-task sub-status
|
|
vocabulary** in `agents/implement-orchestrator.md` — the file the
|
|
agent actually carries at runtime in its fresh context. That table
|
|
is the single source; it is deliberately not restated here, so the
|
|
two files cannot drift.
|
|
|
|
## The Process — orchestrator side
|
|
|
|
### Step 1 — Dispatch the orchestrator-agent
|
|
|
|
For a standard iteration:
|
|
|
|
```
|
|
Agent("implement-orchestrator", {
|
|
mode: "standard",
|
|
iter_id: "<iter_id>",
|
|
plan_path: "<path under paths.plan_dir>",
|
|
task_range: [3, 8]
|
|
})
|
|
```
|
|
|
|
For a debug-handoff (mini mode):
|
|
|
|
```
|
|
Agent("implement-orchestrator", {
|
|
mode: "mini",
|
|
iter_id: "bugfix-<short-symptom>",
|
|
red_test_path: "<absolute path>",
|
|
cause_summary: "<1-2 sentences from debugger>",
|
|
constraint: "minimal fix, no surrounding cleanup"
|
|
})
|
|
```
|
|
|
|
The blocks above show the call shape; each field's semantics
|
|
(including the load-bearing `iter_id` rule — it names the scratch
|
|
dir and stats filename, NOT a branch) are defined authoritatively
|
|
under **Carrier contract** in `agents/implement-orchestrator.md`.
|
|
That table is the single source for the field semantics; they are
|
|
deliberately not restated here, so the two files cannot drift.
|
|
|
|
Before dispatch: ensure the working tree is clean
|
|
(`git status --porcelain` empty). The orchestrator-agent's
|
|
Phase 0 will refuse to start on a dirty tree.
|
|
|
|
### Step 2 — Read the end-report
|
|
|
|
The orchestrator-agent 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 orchestrator-context tokens;
|
|
per-task chatter has stayed inside the orchestrator-agent.
|
|
|
|
### Step 3 — Orchestrator inspect + commit step (on DONE)
|
|
|
|
The orchestrator-agent returns with code edits and the stats
|
|
file sitting in the working tree as unstaged changes.
|
|
Nothing is committed yet, and there is no `BLOCKED.md` (DONE
|
|
never writes one).
|
|
|
|
1. Inspect: `git status` and `git diff` — confirm the
|
|
changes match what the end-report claims. The end-report
|
|
is the per-task summary; use it as the basis for the
|
|
commit body.
|
|
2. Decide commit shape — by default one cohesive commit for
|
|
the whole iter; split into a few logical commits only if
|
|
the diff genuinely covers multiple unrelated changes.
|
|
Per-task commit splitting is NOT a goal; the iter is the
|
|
unit of consistency the orchestrator is committing to.
|
|
3. Write the commit body. It carries everything a future
|
|
reader needs that the diff itself does not: the *why*,
|
|
the alternatives that were considered and rejected, the
|
|
verification steps run, and any concerns that remain.
|
|
Detail-fill comes from the end-report — the per-task
|
|
chatter that stayed inside the orchestrator-agent does
|
|
not come back, by design.
|
|
4. Stage + commit the code edits and the stats file.
|
|
5. If trigger is done-state and the user is away, run the
|
|
project's configured notification command per
|
|
`../boss/SKILL.md` "Done-state notifications" subsection.
|
|
|
|
### Step 4 — Orchestrator handling (on PARTIAL or BLOCKED)
|
|
|
|
The orchestrator-agent returns with whatever work-in-progress
|
|
it managed plus `BLOCKED.md` at the repo root carrying the
|
|
diagnostic. Nothing is committed. The orchestrator decides
|
|
what to do with the dirty working tree:
|
|
|
|
1. Read `BLOCKED.md` — `## What did not` names the failure
|
|
mode and the worker's verbatim reason. Read `git diff`
|
|
to see what was attempted.
|
|
2. Decide:
|
|
- **Repair:** keep the working-tree changes in place (or
|
|
stash them with `git stash` if a clarifying read of
|
|
clean main is needed first). Adjust plan or extend
|
|
context; **delete `BLOCKED.md`** (`rm BLOCKED.md`)
|
|
before re-dispatch — the orchestrator-agent's Phase 0
|
|
clean-tree check counts it as dirt. Either stash
|
|
everything and re-dispatch on a clean tree, or commit
|
|
the known-good subset, then `rm BLOCKED.md`, then
|
|
re-dispatch.
|
|
- **Discard:** `git checkout -- .` to drop unstaged file
|
|
changes; `git clean -fd BLOCKED.md` (or `rm BLOCKED.md`)
|
|
plus anything else new. main HEAD does NOT move.
|
|
- **Escalate:** ask the user via the configured
|
|
notification command. `BLOCKED.md` sits in the working
|
|
tree until the conversation resumes.
|
|
|
|
Under no circumstance does the orchestrator `git reset` or
|
|
`git revert` on main: there is nothing on main to undo (the
|
|
orchestrator-agent did not commit), and the policy forbids
|
|
history rewinding on main even if there were.
|
|
|
|
## Handoff Contract
|
|
|
|
`implement` consumes:
|
|
|
|
| Source | Carrier |
|
|
|--------|---------|
|
|
| from `planner` | path to plan under `paths.plan_dir` (+ optional `task_range`) |
|
|
| from `debug` | RED-test path + cause summary + minimal-fix constraint |
|
|
|
|
`implement` produces: an unstaged working tree containing the
|
|
code edits and the stats file; on PARTIAL/BLOCKED, also
|
|
`BLOCKED.md` at the repo root. The orchestrator inspects,
|
|
commits the code + stats (DONE) or repairs/discards
|
|
(PARTIAL/BLOCKED). No further hand-off — `audit` runs
|
|
independently at cycle 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 phase loop and the working-tree isolation are the value. |
|
|
| "Let me have the orchestrator-agent commit the per-task work, it's cleaner" | The orchestrator-agent never commits. Orchestrator-only commit is a project-wide rule: only the orchestrator decides when a state is consistent enough to enter main history. |
|
|
| "Per-task commits would help bisection later" | The orchestrator-agent's per-task phases are review gates, not bisection points. Iter-level commits are the bisection unit — and they only exist if the whole iter passes the orchestrator's review. |
|
|
| "BLOCKED end-report, let me dig into BLOCKED.md and continue myself" | Read the `## What did not` section first. The orchestrator-agent stopped at the re-loop limit for a reason. Continuing by hand undoes the discipline. |
|
|
| "End-report says PARTIAL with 4/5 tasks DONE — close enough, commit them" | The 5th task may carry an invariant the earlier 4 silently depend on. Either re-dispatch for the missing task or `git checkout -- .` and re-plan. |
|
|
| "BLOCKED.md feels redundant — the end-report already has the blocked detail" | The end-report dies when the chat scrolls; `BLOCKED.md` sits in the working tree across pauses, mode-switches, and orchestrator-inspection rounds. It is the durable handoff. |
|
|
| "The per-task phases run inline anyway, just have the orchestrator dispatch the reviewer-agents instead and skip the orchestrator-agent" | That gives back fresh-per-phase context but loses the orchestrator-context offload — the per-task chatter goes back through the orchestrator. The orchestrator-agent exists precisely for the offload. If you want fresh-per-phase context AND offload, you want a capability Claude Code does not provide. |
|
|
| "BLOCKED iter with a bad commit on main — let me `git revert` it" | There is no bad commit on main: the orchestrator-agent did not commit. Bad work stays in the working tree where it is still discardable. main HEAD is sacrosanct. |
|
|
| "Re-dispatch refuses because `BLOCKED.md` is still in the tree — let me just commit it to clear the check" | No. `BLOCKED.md` is never committed. `rm BLOCKED.md` (or stash) before re-dispatch — the file's whole purpose is to live in the working tree, not on main. |
|
|
|
|
## Red Flags — STOP
|
|
|
|
- Orchestrator dispatching `implementer` directly (bypassing
|
|
the orchestrator-agent).
|
|
- Orchestrator running `git reset` or `git revert` on main.
|
|
- Orchestrator-agent running `git commit` (anywhere, ever).
|
|
- Two `/implement` runs overlapping on the same working tree.
|
|
- `BLOCKED.md` staged or committed by anyone.
|
|
- End-report longer than ~500 tokens.
|
|
|
|
## Cross-references
|
|
|
|
- **Agent dispatched:** `agents/implement-orchestrator.md` —
|
|
carries the per-task loop inline; each phase is a
|
|
role-switch in the orchestrator-agent's own context. The
|
|
role-files below are *phase references* (the
|
|
orchestrator-agent reads them at each role-switch to
|
|
inhale the discipline) — they are NOT separately
|
|
dispatched subagents:
|
|
- `agents/implementer.md` — Phase 2.1 reference
|
|
(implementer mindset, TDD discipline)
|
|
- `agents/spec-reviewer.md` — Phase 2.2 reference
|
|
(spec-compliance mindset)
|
|
- `agents/quality-reviewer.md` — Phase 2.3 reference
|
|
(quality-review mindset)
|
|
- `agents/tester.md` — Phase 3 reference (E2E coverage
|
|
mindset)
|
|
- **Why inline phases, not nested subagents.** Claude Code
|
|
does not permit a subagent to spawn other subagents. The
|
|
orchestrator-agent cannot dispatch the role-agents above;
|
|
it adopts each role as a sequential phase in its own
|
|
context.
|
|
- **Input sources:**
|
|
- `../planner/SKILL.md` — produces the plan files this
|
|
skill consumes
|
|
- `../debug/SKILL.md` — produces the RED-test handoff for
|
|
mini-mode
|
|
- **Output target:** orchestrator reads the end-report,
|
|
inspects the working tree, and commits; `../audit` runs
|
|
at cycle close.
|