Execute Plan
Overview
Load plan, review critically, execute ready tasks in waves in the ticket
venue (this checkout if already on the ticket branch, else a worktree),
run the verifications the plan specifies, report when complete.
Announce at start: "I'm using the execute-plan skill to implement this plan."
The Process
Step 1: Load and Review Plan
- Read the plan file (the one produced by write-plan or interview-plan).
Infer
<TICKET-ID> from the plan path first, then an existing ticket
worktree, then the current branch, then ask once — the user's checkout
may be on main or another ticket.
If the user did not say which file, search in this order:
- already-listed worktree for this ticket (it is live — prefer it)
docs/features/<TICKET-ID>/ (tracked)
docs/plans/<TICKET-ID>/ (gitignored WIP)
- Legacy flat
docs/plans/*.md or docs/PLAN_*.md
If both tracked and WIP copies exist in the same checkout, diff them; if
they diverge, ask which is active — never silently prefer the promoted
copy over newer WIP.
Record the absolute path of the user's checkout — Step 2 copies from
there only when the worktree does not already have the WIP docs.
- Review it critically — identify any questions, gaps, or concerns before
touching code. A plan whose header links a spec but carries no
**Audit:** clean line: if an interview spec exists for this ticket, the
Audit Pass was interrupted — confirm before executing. If there was no
interview (standalone write-plan), missing audit is expected — still
confirm once, then proceed. Do not treat both cases as "interrupted
interview".
- If concerns: raise them with the user before starting. Resume / stash /
TodoWrite wait until Step 2 has the live plan.
Step 2: Open the execution venue
Already on this ticket's branch (git branch --show-current contains
<TICKET-ID>): this checkout is the venue. Skip git-worktrees. Skip the
WIP copy below. Git will not attach the same branch in a second worktree —
stay here instead of deadlocking.
Otherwise execution happens in a dedicated worktree for this
<TICKET-ID>. The user's checkout is theirs — it may be dirty, on another
branch, running a dev server. One worktree per ticket also lets several
tickets execute in parallel on the same repo. Do not ask which branch to
use, do not offer to switch branches, and do not gate on the user's tree
being clean.
Worktree path only. Run the git-worktrees skill with the ticket
ID. It detects existing isolation, reuses or creates the worktree at
.worktrees/<branch> (branch <TICKET-ID>-<slug>, per that skill's
naming), and runs the project's install + baseline check. Consent is
implied by /execute-plan — it does not re-ask. Already inside a linked
worktree for this ticket → it reports and continues; nothing is created.
Live plan (worktree path only). The WIP tiers (docs/plans/,
docs/specs/) are gitignored, so a fresh worktree does not contain the
plan or spec. Run this from inside the worktree. Copy only when the
destination does not already exist — a prior run's worktree copy is live;
overwriting it from the origin checkout destroys ticks, drift notes,
blockers, and review entries:
for d in docs/plans/<TICKET-ID> docs/specs/<TICKET-ID>; do
if [ -d "<origin-checkout>/$d" ] && [ ! -d "$d" ]; then
mkdir -p "$(dirname "$d")" && cp -R "<origin-checkout>/$d" "$d"
fi
done
The worktree copy (or the tracked docs/features/<TICKET-ID>/ already on
the branch) is now the live plan. Never write the origin checkout's copy
mid-run. In-place: the files are already here; this copy does not run.
Resume on the live plan, in this venue. Reconcile checkboxes
against git log here (this is the ticket branch): a ticked task with no
[T<N>] commit → untick and redo; a [T<N>] commit with its task
unticked → re-run the gate and tick without redoing. If ## Blockers
holds an unresolved stash OID, git stash apply <OID> here, then
mark it resolved. Checkboxes are the source of truth; TodoWrite is a
session mirror. Every task ticked but no ## Review with Verdict: ship
at current HEAD → jump to Step 4. Stale reviewed @ SHA (code commits
after it, docs-only excepted) → re-run Step 4.
Confirm the venue is clean (git status --porcelain empty) aside from
gitignored WIP docs. A reused worktree that is dirty is leftover work —
reconcile against ## Blockers before Task 1.
Create a TodoWrite list from the live plan and proceed.
Report the venue path (this checkout, or the worktree) before Task 1 so the
user knows where the work is landing.
Step 3: Execute Tasks
Tasks run in waves: every task that legally can run now is dispatched as a
fresh subagent in one message; this session acts as orchestrator. Waves are
the default, not an optimization to opt into — a plan whose tasks are
independent should finish in as many rounds as its dependency graph is deep,
not as many rounds as it has tasks. All subagents in a wave share the Step 2
venue; isolation between them comes from the disjoint-files rule below, not
from separate directories.
Inline execution is fine for small or tightly coupled plans where one context
comfortably holds the work — task count alone is not the trigger.
Wave scheduling
Each round, build the ready set from the unticked tasks. A task joins the
current wave only if all four hold:
Depends on: satisfied — every named task is already ticked. A task
declaring none is ready immediately. If every task omits Depends on:,
treat each as depending on the one before it and run sequentially — an
absent declaration is unknown, not independent. If some tasks declare
Depends on: and one omits it, stop and ask — do not treat the omit as
none (vacuously ready) and do not silently serialize the whole plan.
Files: disjoint from every other task already in this wave. Compare
paths only — strip a trailing :line-range (e.g. src/foo.py:123-145
→ src/foo.py) before the check. Two tasks on the same file at different
lines still collide. Two subagents editing one file in one venue overwrite
each other; there is no merge step to catch it. A task with no Files:
list does not join a wave with others — unknown overlap. (The Review gate
has no Files: and is excluded by rule 4 anyway.)
- Gate commands do not contend — tasks whose verifications write the same
build output, coverage file, fixture database, or bind the same port go in
different waves even when their
Files: are disjoint. Shared read-only
test infrastructure is fine, but a gate whose scope is the whole repo
(typecheck, compile, lint, full-suite) reads a sibling's half-written files
and contends the same way: scope it to the task's own paths, or schedule the
task in a later wave.
- Not the Review gate task — see the exception below.
Dispatch the whole ready set in a single message (parallel tool calls), then
wait for all of them before fanning in. Do not start the next wave early:
a later task's Depends on: is only satisfied once its predecessor is
ticked, which happens in fan-in after the orchestrator's own gate run.
Width is whatever the ready set allows — there is no cap beyond rules 2 and 3.
Record the wave composition in your progress notes (wave 1: T1, T3, T5) so a
resumed session can tell which tasks were in flight together.
Subagent contract — the prompt MUST contain all of:
- the absolute venue path from Step 2, and the instruction to work only
inside it — a subagent given a repo-relative path can resolve it against
the wrong checkout and silently edit the other tree;
- the plan file path and the task number (the plan's Architecture
constraints section is the subagent's conventions source — it sees nothing
else);
- the spec file path from the plan header (so decisions are checkable, not
hearsay);
- the repo quirks doc path when it exists (e.g.
docs/quirks.md);
- the task's gate/verification command(s) verbatim;
- the 5-attempt cap and the instruction to report a blocker instead of
grinding;
- the Plan Drift Protocol below. Dispatched subagents return a proposed
> Drift: line; they do not write the plan. The orchestrator applies it
at fan-in. Only inline execution amends the plan in place;
- edit and test only — never commit, never write the plan file (git index
and plan md are orchestrator-owned state, sequential or parallel): skip the
task's commit step and return changed paths, drift notes, and gate output
instead — the orchestrator commits after its own checks (substeps 5–7).
Trust but verify: subagents overclaim. Before ticking a task's checkbox,
the orchestrator re-runs the task's gate command itself and confirms the
expected output. A subagent "done" summary is a claim, not evidence.
Exception — the Review gate task: the plan's final Review gate task is
NEVER dispatched to a task subagent (a task subagent cannot spawn the
read-only reviewer, and an implementer must not review its own diff). Skip
it when building the ready set. When it is the only remaining unticked
task, leave Step 3 and go to Step 4 — do not stall on an empty ready set.
The orchestrator runs the gate as Step 4.4 (after data-path trace, full-suite,
and spec promotion) and ticks its checkboxes when ## Review records
Verdict: ship.
Per task
Substeps 1–3 are the task work — done by the subagent in dispatch mode, by
this session inline. Substeps 4–8 are always the orchestrator's, and in a
wave they run serially, in task-number order, after every subagent in that
wave has returned: the git index and the plan file are single-writer state
no matter how wide the wave was.
- Mark the todo
in_progress.
- Follow each step exactly — the plan has bite-sized steps (write failing test
→ run red → minimal impl → run green → commit). When reality contradicts a
step, apply the Plan Drift Protocol — do not silently diverge and do not
stop for trivial mismatches.
- Run the verifications the step specifies. Do not skip them. Do not invent your
own success criteria when the plan gave one.
- Before the task's commit step, run substeps 5–6 first — the commit
must be able to include synced doc paths, and gate findings are cheaper to
fix pre-commit than post-commit. Apply each returned
> Drift: note to the
plan here too; subagents never write it.
- Per-task check (orchestrator, cheap): re-run the gate command (see
above), then skim the task's diff against the plan's Architecture
constraints — layering respected, canonical helpers used, no hardcoded
test-expected values. For a task that changes a contract or persisted
data (API/event shape, schema, migration), have a fresh read-only
subagent do this skim instead — the implementer must not check its own
contract change. Findings → fix now, before the next task builds on it.
- Feature-docs sync: if your repo has a feature-docs sync flow and
docs/features/<TICKET-ID>/ exists, run it when the task changed
decisions, contracts, deploy, or QA; skip for behavior-preserving fixes.
The edited doc paths join the task's commit below.
- When the plan step says "commit", commit code + synced doc paths together —
stage explicit paths (or use the repo's commit helper); never
git add ..
Keep the plan's [T<N>] task tag in the message.
- Tick the task's checkboxes (
- [x]) in the plan file after the
orchestrator's own gate run passes — the plan file tracks progress, not the
session. If the plan file is tracked (docs/features/ tier), tick before
the step-7 commit and include the plan path in it — uncommitted checkbox
edits dirty the tree and block the review gate. Then mark the todo
completed.
When one task in a wave fails. A blocked or failing subagent does not void
its siblings. Fan in the tasks that passed their gate normally — commit and
tick each one — then handle the failure on its own terms: retry within the
5-attempt cap, or append a ## Blockers entry and stop. Do not open the next
wave while a blocker is unresolved; its tasks may depend on the failed one, and
resuming from a half-applied wave is exactly what the plan file's checkboxes
exist to prevent.
Plan Drift Protocol (plan meets reality)
Plan code was written before implementation; minor mismatch is normal, not a
blocker. When a step's code or command doesn't match reality (renamed symbol,
different signature, moved file, API mismatch):
- Adapt — implement what the step intends against the real code.
- Record the drift — dispatched: return
> Drift: <what differed and why>
to the orchestrator (do not write the plan). Inline: amend the step in place
and append that line under it. The plan file stays the as-built source of
truth; a plan that lies about what was built is worse than no plan.
- Escalate instead when the drift changes a spec decision, a
contract, invalidates a later task, or would make you delete, narrow, or
invert an assertion covering behavior the plan never set out to change —
that is a plan gap or a regression, not drift. Flipping such an assertion
makes the test match the bug.
Stop and ask (see below). If the user approves the change, update the spec
immediately — record the new decision with
supersedes D<n> and strike
the old one — before continuing. The review gate reads the spec and must
not judge the diff against a stale decision.
Step 4: Complete
After all tasks are done and verified:
- Trace the data path to its real sink. If the change persists or transmits a
field, follow the value from its source to where it lands (DB write, queue
publish, HTTP response). Open the actual writer — the repository insert /
build(...) / publish payload — and confirm the new field is listed there, not
just on the domain type. Green unit tests that mock the writer do NOT prove
this; confirm at least one test reaches the sink without mocking it (in-memory
DB round-trip or emitted-payload assertion), or flag it to the user. A field set
on a domain object but missing from the writer ships schema defaults (0/null)
to production — a silent failure that looks deployed.
- Run the full relevant test/lint suite for the touched code.
- Promote the spec before the review: copy
docs/specs/<TICKET-ID>/spec.md to
docs/features/<TICKET-ID>/design.md (or merge into an existing one) and
commit — in a multi-repo setup where another repo owns the shared
design.md, merge there instead and record that path. The read-only
reviewer may run from a context that cannot see gitignored WIP paths, and
a missing spec caps its verdict at fix-first.
Then confirm the tree is clean (git status --porcelain empty): the
review's Step 0 refuses a dirty tree because uncommitted changes silently
escape the diff.
- Run the review gate: invoke thermo-nuclear-code-quality-review as a
read-only subagent with this venue as its working directory (or
equivalent
git -C <venue>) on the branch diff, passing the spec and
plan absolute paths in the prompt. A reviewer launched from a
different checkout than the venue diffs the wrong branch. A fresh-context
reviewer cannot find gitignored WIP paths on its own. This step IS the
plan's final Review gate
task (write-plan appends one to every plan) — tick that task's checkboxes
here; never run the review once in the Step 3 loop and again here.
- Pinned review model: launch the reviewer subagent with the model
named in thermo-nuclear-code-quality-review's "Pinned review model"
section — that skill is the single source of truth for the slug; do not
hardcode it here. Never the session's own model (auto included). If the
slug is unavailable, stop and ask the user — never silently substitute.
- Record evidence: append the reviewer's 3-line rollup (Verdict / Top
issue / Net), the model used, the full-suite command + result at that
SHA,
reviewed @ <HEAD SHA> and base @ <base SHA>, and the subagent
link to the plan file under a ## Review section — one entry per review
cycle. This is what the Step 2 resume check looks for; a review that
leaves no ## Review entry did not happen.
- Accepted findings are inserted into the plan as structured remediation
tasks before the review gate task (write-plan's remediation
template); fix them via the same Step 3 loop, then have the reviewer
re-check the changed areas. Before
accepting a
ship verdict after any fix cycle, re-run the full test
suite at the final HEAD — targeted gate commands alone do not qualify.
Repeat until the verdict is ship (the review skill caps cycles at 3,
then escalates).
- As-built reconciliation: re-read the plan file end to end — every
checkbox ticked or explained, every
> Drift: note in place, the
## Review section's last entry reads Verdict: ship at the current HEAD,
## Blockers entries resolved or still-open-and-flagged (## Deferred suggestions stays for the user — it does not block); confirm
superseded spec decisions were marked at escalation time (Drift Protocol
step 3). Then promote the plan to docs/features/<TICKET-ID>/ (the spec
was already promoted in substep 3) and commit, or ask the user if
promotion is premature. Docs-only commits after the reviewed SHA that
leave spec decisions unchanged do not invalidate the ship verdict.
- Report what was implemented, which verifications passed, and anything
skipped — and state the venue path and branch so the user knows
where to look.
- Hand back to the user for manual testing. Do not open a PR or merge unless the
user asks. If the venue is a worktree, leave it in place: it holds
the branch, the as-built plan, and any still-gitignored WIP docs.
Removing it is git-worktrees Step 4, run only after merge or on explicit
user say-so.
When to Stop and Ask for Help
STOP executing immediately when:
- You hit a blocker (missing dependency, failing test you can't trivially fix,
unclear instruction).
- The plan has a critical gap that prevents starting a task.
- You don't understand a step.
- A verification fails 5 times (hard cap). On the 5th failure: STOP, append
the blocker to a
## Blockers section at the end of the plan file (task number,
what fails, what was tried), and escalate to the user. Never grind past the cap.
- A verification cannot be run as written — it hangs, it is already red for
unrelated reasons, or it needs access you cannot obtain. Append a
## Blockers
entry and ask what counts as ship evidence. Never tick the step, and never
silently substitute a narrower command — a gate downgraded inside a > Drift:
note is invisible to the reviewer.
Leave a clean tree when blocked. Before escalating, park the partial work so
resume doesn't inherit a dirty workspace:
git stash push -u -m "T<N>-blocked" -- <task's changed paths> (default) —
scoped to the task's paths so the user's unrelated work is never swept up,
-u so untracked new files are not left behind. Record the stash OID
(git rev-parse stash@{0}) in the ## Blockers entry. Alternative: a wip
commit on the feature branch if the user prefers history — record which was
done.
Ask for clarification rather than guessing.
When to Revisit the Plan
Return to Step 1 (review) when:
- The user updates the plan based on your feedback.
- The fundamental approach needs rethinking.
Don't force through blockers — stop and ask.
Subagent-driven execution
Subagent-per-task, dispatched in waves of everything currently legal to
run, is the default (see Step 3). Each task gets a fresh context, which
prevents context rot on long plans; the plan file (checkboxes + ## Blockers)
carries all state between tasks, so any session — or a replacement session —
can resume from it. Because state lives in the plan and the git index, both
single-writer and both orchestrator-owned, widening a wave never widens the
blast radius.
A subagent that hits the 5-attempt cap reports the blocker back; the
orchestrator writes it to the plan file and stops. Inline execution remains
fine for small or tightly coupled plans where one context comfortably holds
the work.
Remember
- Review the plan critically first.
- Follow plan steps exactly; don't skip verifications.
- Commit with explicit paths only (or the repo's commit helper); never
git add ..
- Stop when blocked — don't guess.
- Execute in this checkout when already on the ticket branch; otherwise in
the ticket worktree. The venue's plan copy is the live one.
- Dispatch every legal task in a wave; fan in serially — commit, sync docs,
tick, one task at a time.
- This skill runs the review gate as Step 4.4. Do not also invoke
/thermo-nuclear-code-quality-review unless the user edited code after
Verdict: ship. /graph-retro is post-merge, not the next implement step.
1---2name: execute-plan3description: Implement a written plan (from write-plan or interview-plan) when the user says execute or implement it. Loads the plan, executes ready tasks in waves in the ticket venue, runs the plan's review gate itself. Do not use while still interviewing or writing the plan.4---56# Execute Plan78## Overview910Load plan, review critically, execute ready tasks in waves in the ticket11venue (this checkout if already on the ticket branch, else a worktree),12run the verifications the plan specifies, report when complete.1314**Announce at start:** "I'm using the execute-plan skill to implement this plan."1516## The Process1718### Step 1: Load and Review Plan19201. Read the plan file (the one produced by **write-plan** or **interview-plan**).21 Infer `<TICKET-ID>` from the plan path first, then an existing ticket22 worktree, then the current branch, then ask once — the user's checkout23 may be on `main` or another ticket.24 If the user did not say which file, search in this order:25 - already-listed worktree for this ticket (it is live — prefer it)26 - `docs/features/<TICKET-ID>/` (tracked)27 - `docs/plans/<TICKET-ID>/` (gitignored WIP)28 - Legacy flat `docs/plans/*.md` or `docs/PLAN_*.md`29 If both tracked and WIP copies exist in the same checkout, diff them; if30 they diverge, ask which is active — never silently prefer the promoted31 copy over newer WIP.32 Record the **absolute path of the user's checkout** — Step 2 copies from33 there only when the worktree does not already have the WIP docs.342. Review it critically — identify any questions, gaps, or concerns before35 touching code. A plan whose header links a spec but carries no36 `**Audit:** clean` line: if an interview spec exists for this ticket, the37 Audit Pass was interrupted — confirm before executing. If there was no38 interview (standalone write-plan), missing audit is expected — still39 confirm once, then proceed. Do not treat both cases as "interrupted40 interview".413. If concerns: raise them with the user before starting. Resume / stash /42 TodoWrite wait until Step 2 has the live plan.4344### Step 2: Open the execution venue4546**Already on this ticket's branch** (`git branch --show-current` contains47`<TICKET-ID>`): this checkout is the venue. Skip git-worktrees. Skip the48WIP copy below. Git will not attach the same branch in a second worktree —49stay here instead of deadlocking.5051**Otherwise** execution happens in a dedicated worktree for this52`<TICKET-ID>`. The user's checkout is theirs — it may be dirty, on another53branch, running a dev server. One worktree per ticket also lets several54tickets execute in parallel on the same repo. Do not ask which branch to55use, do not offer to switch branches, and do not gate on the user's tree56being clean.57581. **Worktree path only.** Run the **git-worktrees** skill with the ticket59 ID. It detects existing isolation, reuses or creates the worktree at60 `.worktrees/<branch>` (branch `<TICKET-ID>-<slug>`, per that skill's61 naming), and runs the project's install + baseline check. Consent is62 implied by `/execute-plan` — it does not re-ask. Already inside a linked63 worktree for this ticket → it reports and continues; nothing is created.642. **Live plan (worktree path only).** The WIP tiers (`docs/plans/`,65 `docs/specs/`) are gitignored, so a *fresh* worktree does not contain the66 plan or spec. Run this **from inside the worktree**. Copy only when the67 destination does not already exist — a prior run's worktree copy is live;68 overwriting it from the origin checkout destroys ticks, drift notes,69 blockers, and review entries:7071 ```bash72 for d in docs/plans/<TICKET-ID> docs/specs/<TICKET-ID>; do73 if [ -d "<origin-checkout>/$d" ] && [ ! -d "$d" ]; then74 mkdir -p "$(dirname "$d")" && cp -R "<origin-checkout>/$d" "$d"75 fi76 done77 ```7879 The worktree copy (or the tracked `docs/features/<TICKET-ID>/` already on80 the branch) is now the live plan. Never write the origin checkout's copy81 mid-run. In-place: the files are already here; this copy does not run.823. **Resume on the live plan, in this venue.** Reconcile checkboxes83 against `git log` here (this is the ticket branch): a ticked task with no84 `[T<N>]` commit → untick and redo; a `[T<N>]` commit with its task85 unticked → re-run the gate and tick without redoing. If `## Blockers`86 holds an unresolved stash OID, `git stash apply <OID>` **here**, then87 mark it resolved. Checkboxes are the source of truth; TodoWrite is a88 session mirror. Every task ticked but no `## Review` with `Verdict: ship`89 at current HEAD → jump to Step 4. Stale `reviewed @` SHA (code commits90 after it, docs-only excepted) → re-run Step 4.914. Confirm the venue is clean (`git status --porcelain` empty) aside from92 gitignored WIP docs. A reused worktree that is dirty is leftover work —93 reconcile against `## Blockers` before Task 1.945. Create a TodoWrite list from the live plan and proceed.9596Report the venue path (this checkout, or the worktree) before Task 1 so the97user knows where the work is landing.9899### Step 3: Execute Tasks100101**Tasks run in waves: every task that legally can run now is dispatched as a102fresh subagent in one message; this session acts as orchestrator.** Waves are103the default, not an optimization to opt into — a plan whose tasks are104independent should finish in as many rounds as its dependency graph is deep,105not as many rounds as it has tasks. All subagents in a wave share the Step 2106venue; isolation between them comes from the disjoint-files rule below, not107from separate directories.108109Inline execution is fine for small or tightly coupled plans where one context110comfortably holds the work — task count alone is not the trigger.111112#### Wave scheduling113114Each round, build the **ready set** from the unticked tasks. A task joins the115current wave only if all four hold:1161171. **`Depends on:` satisfied** — every named task is already ticked. A task118 declaring `none` is ready immediately. **If every task omits `Depends on:`**,119 treat each as depending on the one before it and run sequentially — an120 absent declaration is unknown, not independent. **If some tasks declare121 `Depends on:` and one omits it, stop and ask** — do not treat the omit as122 `none` (vacuously ready) and do not silently serialize the whole plan.1232. **`Files:` disjoint** from every other task already in this wave. Compare124 **paths only** — strip a trailing `:line-range` (e.g. `src/foo.py:123-145`125 → `src/foo.py`) before the check. Two tasks on the same file at different126 lines still collide. Two subagents editing one file in one venue overwrite127 each other; there is no merge step to catch it. A task with no `Files:`128 list does not join a wave with others — unknown overlap. (The Review gate129 has no `Files:` and is excluded by rule 4 anyway.)1303. **Gate commands do not contend** — tasks whose verifications write the same131 build output, coverage file, fixture database, or bind the same port go in132 different waves even when their `Files:` are disjoint. Shared *read-only*133 test infrastructure is fine, but a gate whose scope is the whole repo134 (typecheck, compile, lint, full-suite) reads a sibling's half-written files135 and contends the same way: scope it to the task's own paths, or schedule the136 task in a later wave.1374. **Not the Review gate task** — see the exception below.138139Dispatch the whole ready set in a single message (parallel tool calls), then140wait for all of them before fanning in. Do not start the next wave early:141a later task's `Depends on:` is only satisfied once its predecessor is142**ticked**, which happens in fan-in after the orchestrator's own gate run.143144Width is whatever the ready set allows — there is no cap beyond rules 2 and 3.145Record the wave composition in your progress notes (`wave 1: T1, T3, T5`) so a146resumed session can tell which tasks were in flight together.147148**Subagent contract — the prompt MUST contain all of:**149150- the **absolute venue path** from Step 2, and the instruction to work only151 inside it — a subagent given a repo-relative path can resolve it against152 the wrong checkout and silently edit the other tree;153- the plan file path and the task number (the plan's **Architecture154 constraints** section is the subagent's conventions source — it sees nothing155 else);156- the spec file path from the plan header (so decisions are checkable, not157 hearsay);158- the repo quirks doc path when it exists (e.g. `docs/quirks.md`);159- the task's gate/verification command(s) verbatim;160- the 5-attempt cap and the instruction to report a blocker instead of161 grinding;162- the Plan Drift Protocol below. **Dispatched subagents return a proposed163 `> Drift:` line; they do not write the plan.** The orchestrator applies it164 at fan-in. Only inline execution amends the plan in place;165- **edit and test only — never commit, never write the plan file** (git index166 and plan md are orchestrator-owned state, sequential or parallel): skip the167 task's commit step and return changed paths, drift notes, and gate output168 instead — the orchestrator commits after its own checks (substeps 5–7).169170**Trust but verify:** subagents overclaim. Before ticking a task's checkbox,171the orchestrator **re-runs the task's gate command itself** and confirms the172expected output. A subagent "done" summary is a claim, not evidence.173174**Exception — the Review gate task:** the plan's final Review gate task is175NEVER dispatched to a task subagent (a task subagent cannot spawn the176read-only reviewer, and an implementer must not review its own diff). Skip177it when building the ready set. **When it is the only remaining unticked178task, leave Step 3 and go to Step 4** — do not stall on an empty ready set.179The orchestrator runs the gate as Step 4.4 (after data-path trace, full-suite,180and spec promotion) and ticks its checkboxes when `## Review` records181`Verdict: ship`.182183#### Per task184185Substeps 1–3 are the task work — done by the subagent in dispatch mode, by186this session inline. Substeps 4–8 are **always the orchestrator's**, and in a187wave they run **serially, in task-number order, after every subagent in that188wave has returned**: the git index and the plan file are single-writer state189no matter how wide the wave was.1901911. Mark the todo `in_progress`.1922. Follow each step exactly — the plan has bite-sized steps (write failing test193 → run red → minimal impl → run green → commit). When reality contradicts a194 step, apply the Plan Drift Protocol — do not silently diverge and do not195 stop for trivial mismatches.1963. Run the verifications the step specifies. Do not skip them. Do not invent your197 own success criteria when the plan gave one.1984. **Before the task's commit step, run substeps 5–6 first** — the commit199 must be able to include synced doc paths, and gate findings are cheaper to200 fix pre-commit than post-commit. Apply each returned `> Drift:` note to the201 plan here too; subagents never write it.2025. **Per-task check (orchestrator, cheap):** re-run the gate command (see203 above), then skim the task's diff against the plan's Architecture204 constraints — layering respected, canonical helpers used, no hardcoded205 test-expected values. For a task that changes a **contract or persisted206 data** (API/event shape, schema, migration), have a fresh read-only207 subagent do this skim instead — the implementer must not check its own208 contract change. Findings → fix now, before the next task builds on it.2096. **Feature-docs sync:** if your repo has a feature-docs sync flow and210 `docs/features/<TICKET-ID>/` exists, run it when the task changed211 decisions, contracts, deploy, or QA; skip for behavior-preserving fixes.212 The edited doc paths join the task's commit below.2137. When the plan step says "commit", commit code + synced doc paths together —214 stage explicit paths (or use the repo's commit helper); never `git add .`.215 Keep the plan's `[T<N>]` task tag in the message.2168. **Tick the task's checkboxes (`- [x]`) in the plan file** after the217 orchestrator's own gate run passes — the plan file tracks progress, not the218 session. If the plan file is tracked (`docs/features/` tier), tick before219 the step-7 commit and include the plan path in it — uncommitted checkbox220 edits dirty the tree and block the review gate. Then mark the todo221 `completed`.222223**When one task in a wave fails.** A blocked or failing subagent does not void224its siblings. Fan in the tasks that passed their gate normally — commit and225tick each one — then handle the failure on its own terms: retry within the2265-attempt cap, or append a `## Blockers` entry and stop. Do not open the next227wave while a blocker is unresolved; its tasks may depend on the failed one, and228resuming from a half-applied wave is exactly what the plan file's checkboxes229exist to prevent.230231### Plan Drift Protocol (plan meets reality)232233Plan code was written before implementation; minor mismatch is normal, not a234blocker. When a step's code or command doesn't match reality (renamed symbol,235different signature, moved file, API mismatch):2362371. **Adapt** — implement what the step *intends* against the real code.2382. **Record the drift** — dispatched: return `> Drift: <what differed and why>`239 to the orchestrator (do not write the plan). Inline: amend the step in place240 and append that line under it. The plan file stays the as-built source of241 truth; a plan that lies about what was built is worse than no plan.2423. **Escalate instead** when the drift changes a spec **decision**, a243 contract, invalidates a later task, or would make you delete, narrow, or244 invert an assertion covering behavior the plan never set out to change —245 that is a plan gap or a regression, not drift. Flipping such an assertion246 makes the test match the bug.247 Stop and ask (see below). If the user approves the change, update the spec248 **immediately** — record the new decision with `supersedes D<n>` and strike249 the old one — before continuing. The review gate reads the spec and must250 not judge the diff against a stale decision.251252### Step 4: Complete253254After all tasks are done and verified:2552561. **Trace the data path to its real sink.** If the change persists or transmits a257 field, follow the value from its source to where it lands (DB write, queue258 publish, HTTP response). Open the actual writer — the repository insert /259 `build(...)` / publish payload — and confirm the new field is listed there, not260 just on the domain type. Green unit tests that mock the writer do NOT prove261 this; confirm at least one test reaches the sink without mocking it (in-memory262 DB round-trip or emitted-payload assertion), or flag it to the user. A field set263 on a domain object but missing from the writer ships schema defaults (`0`/`null`)264 to production — a silent failure that looks deployed.2652. Run the full relevant test/lint suite for the touched code.2663. **Promote the spec before the review:** copy267 `docs/specs/<TICKET-ID>/spec.md` to268 `docs/features/<TICKET-ID>/design.md` (or merge into an existing one) and269 commit — in a multi-repo setup where another repo owns the shared270 `design.md`, merge there instead and record that path. The read-only271 reviewer may run from a context that cannot see gitignored WIP paths, and272 a missing spec caps its verdict at `fix-first`.273 Then confirm the tree is clean (`git status --porcelain` empty): the274 review's Step 0 refuses a dirty tree because uncommitted changes silently275 escape the diff.2764. **Run the review gate:** invoke **thermo-nuclear-code-quality-review** as a277 read-only subagent **with this venue as its working directory** (or278 equivalent `git -C <venue>`) on the branch diff, passing the spec and279 plan **absolute** paths in the prompt. A reviewer launched from a280 different checkout than the venue diffs the wrong branch. A fresh-context281 reviewer cannot find gitignored WIP paths on its own. This step IS the282 plan's final Review gate283 task (write-plan appends one to every plan) — tick that task's checkboxes284 here; never run the review once in the Step 3 loop and again here.285 - **Pinned review model:** launch the reviewer subagent with the model286 named in thermo-nuclear-code-quality-review's "Pinned review model"287 section — that skill is the single source of truth for the slug; do not288 hardcode it here. Never the session's own model (auto included). If the289 slug is unavailable, stop and ask the user — never silently substitute.290 - **Record evidence:** append the reviewer's 3-line rollup (Verdict / Top291 issue / Net), the model used, the full-suite command + result at that292 SHA, `reviewed @ <HEAD SHA>` and `base @ <base SHA>`, and the subagent293 link to the plan file under a `## Review` section — one entry per review294 cycle. This is what the Step 2 resume check looks for; a review that295 leaves no `## Review` entry did not happen.296 - Accepted findings are inserted into the plan as structured remediation297 tasks **before the review gate task** (write-plan's remediation298 template); fix them via the same Step 3 loop, then have the reviewer299 re-check the changed areas. **Before300 accepting a `ship` verdict after any fix cycle, re-run the full test301 suite at the final HEAD** — targeted gate commands alone do not qualify.302 Repeat until the verdict is `ship` (the review skill caps cycles at 3,303 then escalates).3045. **As-built reconciliation:** re-read the plan file end to end — every305 checkbox ticked or explained, every `> Drift:` note in place, the306 `## Review` section's last entry reads `Verdict: ship` at the current HEAD,307 `## Blockers` entries resolved or still-open-and-flagged (`## Deferred308 suggestions` stays for the user — it does not block); confirm309 superseded spec decisions were marked at escalation time (Drift Protocol310 step 3). Then promote the plan to `docs/features/<TICKET-ID>/` (the spec311 was already promoted in substep 3) and commit, or ask the user if312 promotion is premature. Docs-only commits after the reviewed SHA that313 leave spec decisions unchanged do not invalidate the ship verdict.3146. Report what was implemented, which verifications passed, and anything315 skipped — and state the **venue path and branch** so the user knows316 where to look.3177. Hand back to the user for manual testing. Do not open a PR or merge unless the318 user asks. If the venue is a worktree, **leave it in place**: it holds319 the branch, the as-built plan, and any still-gitignored WIP docs.320 Removing it is git-worktrees Step 4, run only after merge or on explicit321 user say-so.322323## When to Stop and Ask for Help324325**STOP executing immediately when:**326327- You hit a blocker (missing dependency, failing test you can't trivially fix,328 unclear instruction).329- The plan has a critical gap that prevents starting a task.330- You don't understand a step.331- **A verification fails 5 times (hard cap).** On the 5th failure: STOP, append332 the blocker to a `## Blockers` section at the end of the plan file (task number,333 what fails, what was tried), and escalate to the user. Never grind past the cap.334- **A verification cannot be run as written** — it hangs, it is already red for335 unrelated reasons, or it needs access you cannot obtain. Append a `## Blockers`336 entry and ask what counts as ship evidence. Never tick the step, and never337 silently substitute a narrower command — a gate downgraded inside a `> Drift:`338 note is invisible to the reviewer.339340**Leave a clean tree when blocked.** Before escalating, park the partial work so341resume doesn't inherit a dirty workspace:342`git stash push -u -m "T<N>-blocked" -- <task's changed paths>` (default) —343scoped to the task's paths so the user's unrelated work is never swept up,344`-u` so untracked new files are not left behind. Record the stash OID345(`git rev-parse stash@{0}`) in the `## Blockers` entry. Alternative: a wip346commit on the feature branch if the user prefers history — record which was347done.348349Ask for clarification rather than guessing.350351## When to Revisit the Plan352353Return to Step 1 (review) when:354355- The user updates the plan based on your feedback.356- The fundamental approach needs rethinking.357358Don't force through blockers — stop and ask.359360## Subagent-driven execution361362Subagent-per-task, dispatched in **waves** of everything currently legal to363run, is the default (see Step 3). Each task gets a fresh context, which364prevents context rot on long plans; the plan file (checkboxes + `## Blockers`)365carries all state between tasks, so any session — or a replacement session —366can resume from it. Because state lives in the plan and the git index, both367single-writer and both orchestrator-owned, widening a wave never widens the368blast radius.369370A subagent that hits the 5-attempt cap reports the blocker back; the371orchestrator writes it to the plan file and stops. Inline execution remains372fine for small or tightly coupled plans where one context comfortably holds373the work.374375## Remember376377- Review the plan critically first.378- Follow plan steps exactly; don't skip verifications.379- Commit with explicit paths only (or the repo's commit helper); never `git add .`.380- Stop when blocked — don't guess.381- Execute in this checkout when already on the ticket branch; otherwise in382 the ticket worktree. The venue's plan copy is the live one.383- Dispatch every legal task in a wave; fan in serially — commit, sync docs,384 tick, one task at a time.385- This skill runs the review gate as Step 4.4. Do not also invoke386 `/thermo-nuclear-code-quality-review` unless the user edited code after387 `Verdict: ship`. `/graph-retro` is post-merge, not the next implement step.