---
name: subagent-driven-development
description: Use when executing implementation plans with independent tasks in the current session
---

> **Related skills:** Need an isolated workspace? `/skill:using-git-worktrees`. Need a plan first? `/skill:writing-plans`. Done? `/skill:finishing-a-development-branch`. Reached via the auto-chain from `/skill:writing-plans` (not a direct human entry point; direct invocation stays possible for recovery, e.g. re-running after a STOP).

# Subagent-Driven Development

Execute a plan by dispatching a **fresh subagent per task**, with two-stage review after each: spec compliance first, then code quality.

**Core principle:** Fresh subagent per task + two-stage review = high quality, fast iteration.

If a tool result contains a ⚠️ workflow warning, stop immediately and address it before continuing.

Gauntlet execution dispatches are foreground: set top-level `async: false` on every implementation, review, conformance, retry, and prose-described dispatch. Preserve parallel `tasks` batches and chain groups. `forceTopLevelAsync` is incompatible; an unexpected async handle means stop and report, never poll or relaunch. See [pi-cohort dispatch configuration](https://github.com/jjuraszek/pi-cohort/blob/main/doc/configuration.md).

## Why Subagents

Your context window holds the full plan, prior decisions, and conversation history. Each subagent gets a fresh window with only the current task's text and context.

- **No context pollution.** Task N's noise doesn't leak into Task N+1.
- **Tighter focus.** Subagent reads less, makes fewer cross-task assumptions, ships smaller diffs.
- **Cheaper at scale.** Operator pins (`subagents.agentOverrides.<agent>.model`) route simple subtasks to smaller models; you spend top-tier tokens on orchestration and hard problems.

You are the **orchestrator**. You read the plan, dispatch, review the review, decide. You do **not** write code yourself.

## Continuous Execution

**Do not pause to check in with the user between tasks.** The plan is already approved. Pause only when:

- A subagent returns `NEEDS_CONTEXT` or `BLOCKED` (see [Implementer Status](#implementer-status))
- An escalated round fails (stop note per [Fix-Loop Rounds](#fix-loop-rounds))
- A ⚠️ workflow warning fires

Reaching the end of the plan is not a pause: continue through verification and invoke `/skill:finishing-a-development-branch <abs worktree path>` as defined in [After All Tasks](#after-all-tasks-complete).

Periodic "should I continue?" prompts add latency without adding safety. The plan is the contract; execute it.

## Prerequisites

- The worktree path is known - from the `using-git-worktrees` Step 4 report in this session or the handoff brief's `worktree:` row - and is passed as the top-level dispatch `cwd`. If no worktree path exists, stop and invoke `/skill:using-git-worktrees` first - implementation never lands directly on `main`. The process cwd is the primary checkout; nothing here changes it.
- Approved plan or clear task scope
- `plan_tracker` list initialized at writing-plans handoff with the full wave-ordered task list. Consume and preserve it on continuation; only direct recovery with no tracker initializes the full plan list once, before dispatch, and never over an existing list.

## Sequential vs. Parallel-Wave

subagent-driven-development runs **sequentially by default**; when the plan groups independent tasks into waves, [Parallel-Wave Mode](#parallel-wave-mode) parallelizes the tasks within a wave. The mode is auto-selected by `writing-plans` at handoff (≥2 tasks in some wave → parallel; else sequential) — you are not asked to choose.

**Dependent tasks:** include the previous task's implementation summary and relevant file paths in the next subagent's `task`. Track outputs so you can pass them forward.

## The Process

Before the first task, enter the implement phase: `phase_tracker({ action: "start", phase: "implement" })` — you hold this phase for the parent session while the per-task work is dispatched to subagents; `plan_tracker` auto-completes it once every task is done.

For each task in `plan_tracker`:

**`SCOPED_TEST_COMMANDS`** = the task's `**Tests:**` command bullets, backticks stripped, one per line; `- none:` -> `none`; a wave = the union of its tasks' commands. `via:` bullets and `- Test:` paths are contract, not commands: they ride with the task text, never in `SCOPED_TEST_COMMANDS`.

1. **Start, then dispatch implementer.** Mark the task's existing `plan_tracker` index `in_progress` before dispatch. Pass the full task text + scene-setting context + its `SCOPED_TEST_COMMANDS` (definition above) and its `**Tests:**` block verbatim. Don't make the subagent re-read the plan.
2. **Handle implementer status** (see below).
3. **Dispatch spec reviewer.** Pass the task text, the patch diff, the absolute spec path, and the task's `**Spec:**` anchors, plus the task's `**Tests:**` block and `- Test:` paths as contract (never as commands - SR never executes) — SR reads the anchored ranges from the spec file itself; never inline spec excerpts. The spec wins every dispute; the authority hierarchy and finding labels live in `./spec-reviewer-prompt.md`. Anchor-less tasks (no `**Spec:**` line): task text alone is the contract. Verify the change satisfies the anchored spec — nothing missing, nothing extra.
4. If spec reviewer finds gaps → re-dispatch implementer to fix → re-review. Loop until ✅, within [Fix-Loop Rounds](#fix-loop-rounds).
5. **Dispatch code-quality reviewer.** Only after spec is ✅. Skip for doc-only tasks (every file in the task's `Files:` block documentation-only) — SR-only, same exemption as doc-only waves. Pass the task's `SCOPED_TEST_COMMANDS`.
6. If quality reviewer finds issues → re-dispatch implementer → re-review. Loop until ✅, within [Fix-Loop Rounds](#fix-loop-rounds).
7. After its existing reviews accept the work (and its required commit point), mark that same task index `complete` in `plan_tracker`. A subagent exit or green tests alone are not acceptance.

The orchestrator is the spec's only writer during execution. Amendment trigger: implementer `BLOCKED` citing a spec defect, or a review finding showing the spec (not the code) is wrong -> pause the fix loop, execute brainstorming's [amendment path](../brainstorming/SKILL.md#amending-an-approved-spec) in place (it reviews first, stops only on escalation or redraw), resume. Code-vs-spec mismatch stays in the SR loop. An SR unable to read the spec at a cited anchor (missing file, unresolvable heading/range) returns a blocking finding — the contract is spec+task or stop, never a silent fallback to task-only review.

After all tasks: proceed to [After All Tasks](#after-all-tasks-complete) - it owns parent full verification, then whole-diff code review, then conformance.

## Fix-Loop Rounds

One rule governs both review loops - spec-compliance and code-quality - in sequential and parallel-wave modes alike.

**Re-review dispatch rule:** every re-review task includes the complete prior review report verbatim under the marker `## Previous review report (re-review trigger)`, plus the trajectory block from the reviewer's prompt template. The marker's presence is what obligates the reviewer to emit the `TRAJECTORY:` line. You never select, summarize, or diff findings yourself - pattern-match the sentinel line only.

**Fix fan-out.** When the triggering review's `Parallel-safe:` line certifies a `disjoint` group of ≥ 2 findings, dispatch that fix round per `dispatching-parallel-agents` "Fix fan-out"; the fan-out counts as **one** fix against this budget, its scoped test gate is the consuming task/wave's `SCOPED_TEST_COMMANDS`, and one re-review of the integrated delta follows.

**Behaviour-change reroute.** When the triggering CR report carries `Behaviour-change: yes`, the fix round's re-review is SR first, then CR. The SR dispatch reviews the fix diff against the task's spec anchors as a first review (no `## Previous review report` marker, so no `TRAJECTORY:` line; SR carries no test commands but does carry the task's `**Tests:**` block and `- Test:` paths), but its ordinal continues the task's SR-loop count - a task whose SR loop ended at review 2 gets review 3 here, and an issue-bearing rerouted SR after review 4 escalates. Issues follow the normal sequence: fix, then SR re-review pasting this SR's report. CR round numbering is unchanged. `Behaviour-change: no` re-reviews with CR only. A missing or malformed `Behaviour-change:` line is re-asked once like `Parallel-safe:` (see `dispatching-parallel-agents` "Structural probe"); still missing -> route through SR, never default to `no`. In wave mode the SR re-review targets the task(s) whose files the fix touched.

Every fix re-dispatch (implementer) and code-review re-review carries the consuming task/wave's `SCOPED_TEST_COMMANDS`; spec-reviewer re-reviews carry the `**Tests:**` block and `- Test:` paths, no commands - SR never executes.

**The sequence.** Each review that finds issues is a decision point: read the `TRAJECTORY:` line before dispatching anything (review 1 has no line - on issues, dispatch fix 1). Any clean review ends the loop.

1. **Review 1** (first review - no sentinel). Issues -> dispatch fix 1.
2. **Review 2** (re-review). Issues -> if `STAGNANT`, escalate now - no fix 2. Otherwise dispatch fix 2.
3. **Review 3** (re-review). Issues -> if the line reads `CONVERGING` and does not contain `max severity Critical` (spec reviews: `CONVERGING` alone), run the convergence exception: dispatch fix 3, then review 4. Any other outcome - `STAGNANT`, `DIVERGING`, a missing or malformed line, `max severity Critical` - escalate. Do not re-dispatch just to obtain the line.
4. **Review 4** (re-review, only after the exception). Issues -> escalate, whatever the verdict. The exception fires at most once per loop; verdicts never chain into a second grant.

Every dispatched fix is verified by a re-review before escalation or task progression - the loop only ever exits on a clean review or an escalation.

**Escalate** = one escalated round; stop only on failure. Call `gauntlet_setting({ key: "escalationLoop" })` (unavailable -> stop and report). `implModel` undefined -> stop note. Otherwise re-dispatch that fix - same payload and isolation knobs (`cwd`, `worktree`, `SCOPED_TEST_COMMANDS`, status protocol, prior patch, spec anchors) plus the prior report verbatim - overriding only `model: <implModel>`, `context: "fresh"`, `async: false`; one implementer, no fan-out. Run the normal fix-round review gate (SR then CR on `Behaviour-change: yes`, else the triggering reviewer with the re-review marker). All clean -> proceed; in wave mode the escalated patch supersedes the prior one at integrate. Any review with issues, a non-`DONE` status, or a dispatch error -> stop note per `stop-note.md`; no second dispatch. Once per loop; independent of the convergence exception. No `plan_tracker` write during escalation - the task stays `in_progress` until the human decides.

**Worked examples:**

- Review-2 verdict `TRAJECTORY: STAGNANT (repeat of: unchecked error path in parser)` -> escalate now, before fix 2 - earlier than the ordinary budget.
- Review-3 verdict `TRAJECTORY: CONVERGING (3 -> 1, max severity Moderate)` -> dispatch fix 3; if review 4 still finds issues, escalate.
- Review-3 verdict `TRAJECTORY: CONVERGING (3 -> 2, max severity Critical)` or `TRAJECTORY: DIVERGING` or no `TRAJECTORY:` line -> escalate.

## Implementer Status

Every implementer dispatch returns one of:

| Status | Meaning | Orchestrator action |
|---|---|---|
| `DONE` | Implemented + tests pass + self-reviewed + committed | Proceed to spec review |
| `DONE_WITH_CONCERNS` | Implemented + tests pass, but flagged a deviation or risk | Read concerns. If acceptable, proceed. If not, dispatch fix subagent. |
| `NEEDS_CONTEXT` | Implementer needs information you have | Answer the questions, re-dispatch with answers in the task text |
| `BLOCKED` | Cannot proceed (missing dependency, spec contradicts code, environment broken) | Stop. Diagnose. Either fix orchestration-level issue and re-dispatch, or escalate to user. |

Implementer prompt templates must instruct subagents to return one of these statuses explicitly.

## Model

- Omit `model:` so the operator's `subagents.agentOverrides.<agent>.model` pin applies, or else the child inherits the main loop.
- Pass `model:` only a runtime-resolved `gauntlet_setting` value (`closureReview.model`, `escalationLoop.implModel`, `specCouncil.members[]`, `specCouncil.chair`) or a model the user named for that dispatch.
- Read the main loop's own string from `$PI_PROVIDER`/`$PI_MODEL` with the bash tool only when a skill must bypass a persona's frontmatter `thinking` pin for cost or must pass an explicit fallback after a configured model is unreachable.
- Omit `model:` when `closureReview.model` or `specCouncil.chair` is `undefined`; pass an `implModel` string verbatim, and stop with a note when `implModel` is `undefined` (Fix-Loop Rounds).
- Apply suffix edits such as `:low` only to a runtime-resolved string, never to a name the skill wrote; never write a provider or model name, tier tasks by cost, or swap a pinned model for a cheaper or stronger one.

## Dispatch

Every dispatch carries the worktree as top-level `cwd` - sequential mode included.

```ts
// implementer
subagent({ agent: "implementer", async: false, cwd: "<abs worktree path>", task: "<task text + context + SCOPED_TEST_COMMANDS + status protocol>" })

// escalated fix round (Fix-Loop Rounds): same fix payload, model from gauntlet_setting({ key: "escalationLoop" }).implModel
subagent({ agent: "implementer", model: "<implModel>", context: "fresh", async: false, cwd: "<abs worktree path>", task: "<the just-dispatched fix payload + prior review report verbatim>" })

// spec compliance
subagent({ agent: "spec-reviewer", async: false, cwd: "<abs worktree path>", task: "<task text + patch diff + absolute spec path + task's Spec: anchors + Tests: block + Test: paths>" })

// code quality
subagent({ agent: "code-reviewer", async: false, cwd: "<abs worktree path>", task: "<diff range + SCOPED_TEST_COMMANDS (task commands; wave: union; whole-diff: none) + ask: production-ready?>" })

// closing-loop conformance (origin vs deliverable) — its OWN dispatch, never fused with code quality
// model: call gauntlet_setting({ key: "closureReview" }) first; use the returned model (omit model: if undefined to inherit) and maxFixRounds
// If gauntlet_setting is unavailable, stop and report - never fall back to a manual bash/JSON settings merge.
subagent({ agent: "conformance-reviewer", async: false, cwd: "<abs worktree path>", model: /* gauntlet_setting({ key: "closureReview" }).model, else omit to inherit */, task: "<spec path + verbatim original prompt + full diff vs main; per conformance-check.md>" })
```

Prompt templates live alongside this SKILL.md:

- `./implementer-prompt.md`
- `./spec-reviewer-prompt.md`
- `./code-quality-reviewer-prompt.md`

## Parallel-Wave Mode

Auto-selected at handoff by `writing-plans` (any wave with ≥2 tasks) when the plan groups tasks into **waves** (see `writing-plans`). Waves run in sequence; within a wave, tasks that the plan certified file- **and** runtime-resource-disjoint run concurrently in isolated worktrees, integrated serially behind one test + review gate. The sequential [Process](#the-process) above is the default and the fallback; this mode is the deliberate, worktree-isolated exception to the "no parallel implementers" red flag.

**Enter the implement phase first.** Before the first wave, call `phase_tracker({ action: "start", phase: "implement" })` (as in [The Process](#the-process)); `plan_tracker` auto-completes it once every task across all waves is done.

**Progress tracking (`plan_tracker`).** `plan_tracker` is a flat list with no native group concept, so waves are *encoded*, not modeled:

- **Consume, preserve, recover only if absent:** consume the wave-ordered list initialized at writing-plans handoff; indices are positional and stable, so never re-init on continuation or mid-run. Only direct recovery with no tracker initializes the full plan list once before dispatch.
- **Wave fan-out → `in_progress`:** unconditionally mark every task index in the wave `in_progress` before dispatch, in increasing index order (the tracker validates each call against the previous one and rejects a start while an earlier index is still `pending`). Multiple simultaneous entries are expected (sequential mode has one).
- **Wave commit → `complete`:** after the wave's gate passes and it commits, unconditionally mark all those same indices `complete`. `complete` = durably committed, so a task in conflict fallback stays `in_progress` until its wave commits.
- **Lifecycle per task:** `pending → in_progress (wave fan-out) → complete (wave commit)`; `failed` when a task ran and did not pass; `skipped` when the plan drops it as not applicable (terminal, counted done). A rejected `update` names the earlier pending tasks and the legal fixes - record those tasks' true state, never `clear` or re-`init` to move on.
- **Widget caveat (known, deliberately unfixed).** The persistent `plan_tracker` widget's icon strip (`○ → ✓`) and `(c/total)` count reflect every task, but its trailing *name* shows only the **first** `in_progress` task. In parallel mode the icon strip and the `status` action are the full in-flight view; a richer multi-task widget is a separate extension change, out of scope (YAGNI).
- **Sequential mode:** consume the same existing full list, one `in_progress` index at a time; wave prefixes are harmless.

**Per-wave loop:**

1. **Independence check.** Parse the wave's tasks' `Files:` blocks; assert pairwise-disjoint (mechanical, mirroring `wave-file-disjointness`: `Test`/`Test` on one path is not overlap, `Test` vs another task's `Create`/`Modify` is, `Modify`/`Modify` is). Runtime-resource disjointness (DB/schema, port, fixture, external service, shared temp path) is not machine-checkable here — trust the plan's wave grouping, which `writing-plans`' D5 contract guarantees. Either kind of overlap → the wave is mis-grouped; run those tasks as sequential single-task waves and note it.
2. **Start, then fan out.** Mark every wave index `in_progress` before one parallel foreground dispatch (shape below): `implementer` per task, `context: "fresh"`, `worktree: true`. Each returns a status + a patch.
3. **Status + spec review per task.** Parse each `DONE`/`BLOCKED`/etc. (see [Implementer Status](#implementer-status)) **first**. Then **dispatch a `spec-reviewer` per accepted patch** (`DONE`, or a `DONE_WITH_CONCERNS` you proceeded with) in one parallel fan-out — `context: "fresh"`, `cwd: <this worktree>`, **no `worktree` flag** (read-only) — each passed its task text, the returned **patch diff**, the absolute spec path, and the task's `**Spec:**` anchors, plus its `**Tests:**` block and `- Test:` paths as contract — SR reads the anchored ranges itself (never inline excerpts; authority hierarchy in `./spec-reviewer-prompt.md`; anchor-less tasks are task-text-only). Review starts from the diff (its hunks carry `file:line`) and reads each touched file in full, and test execution is never the reviewer's job - in either mode (persona rule; the wave test gate in step 5 runs the wave's `SCOPED_TEST_COMMANDS`). Inline verdicts are fine at normal wave sizes; large waves use `output:` + `outputMode: "file-only"` to keep verdicts out of your context. **Re-dispatch by cause:** `BLOCKED`/`NEEDS_CONTEXT` per the [Implementer Status](#implementer-status) matrix; a **spec gap** re-dispatches the implementer (fresh, `worktree: true`) carrying the prior patch + the reviewer's findings, the new patch superseding the old at step 4. Loop until accepted + spec ✅, within [Fix-Loop Rounds](#fix-loop-rounds), same as sequential.
4. **Integrate.** `git -C <worktree> apply` each task's patch sequentially onto HEAD. Apply fails = textual conflict → drop that task, finish the rest, re-run the dropped task sequentially on the updated HEAD.
5. **Test gate.** Run the wave's `SCOPED_TEST_COMMANDS` (union of its tasks' `Tests:` commands) on the integrated tree as `(cd "<worktree>" && <command>)` for each command — the full verification set is the verify phase's job, run once. Failure = semantic conflict or bug → re-run the offending task sequentially, else fix per [When a Subagent Fails](#when-a-subagent-fails).
6. **Quality review.** CR binds to the wave: exactly one **initial** code-review dispatch per code-touching wave, over the integrated wave diff - never per task within a wave, never batched across waves. Subsequent dispatches within the wave are re-reviews triggered only by findings, per Fix-Loop Rounds. Pass the wave's `SCOPED_TEST_COMMANDS`. Code-quality review on the integrated wave diff; loop fixes to ✅ within [Fix-Loop Rounds](#fix-loop-rounds), same as sequential. Skip for doc-only waves (SR-only per the commit precondition below).
7. **Commit and complete the wave.** After the gate passes, commit with `git -C <worktree> add ... && git -C <worktree> commit ...`, then mark all of its existing indices `complete`. Leaves a clean tree; the next wave's children branch from this commit and so see the integrated work.

**Two-stage review is preserved:** spec review per task (pre-integration, dispatched `spec-reviewer` — not inline), quality review per wave (post-integration). A wave commit requires one spec-review verdict per accepted task, plus one code-review verdict on the integrated diff for waves that touch code. A doc-only wave (every task's `Files:` block documentation-only, per `writing-plans`' Wave Grouping) is SR-only — the CR gate does not apply.

**Dependent context across waves:** wave N+1 tasks branch from a HEAD containing wave N, so they see the code; still forward wave N's task summaries into wave N+1 prompts.

**Caveat:** each task must be independently runnable and verifiable in a fresh worktree — no reliance on uncommitted local state. `pi-cohort` symlinks `node_modules`; repos needing other per-worktree setup must account for it.

Pass the worktree's absolute path as the top-level `cwd` on every dispatch; rule and rationale: `dispatching-parallel-agents` "pi-cohort Integration".

```bash
REPORT_DIR=$(mktemp -d)
```

```ts
subagent({
  context: "fresh",
  async: false,
  cwd: "/abs/path/to/this/worktree",  // REQUIRED: the worktree path, else children branch from main
  worktree: true,        // each task in its own git worktree, branched from cwd's HEAD
  concurrency: 4,        // default; cap = wave size
  tasks: [
    // do NOT set per-task cwd under worktree:true — it must equal the top-level cwd or the run errors
    { agent: "implementer", task: "<task text + owned files + SCOPED_TEST_COMMANDS + status protocol>", output: "<REPORT_DIR>/wave1-task1.md" },
    { agent: "implementer", task: "<task text + owned files + SCOPED_TEST_COMMANDS + status protocol>", output: "<REPORT_DIR>/wave1-task2.md" },
  ],
})
```

For the fan-out + worktree + patch-integration + conflict mechanics, see `dispatching-parallel-agents`.

## When a Subagent Fails

**You are the orchestrator. You do NOT write code.**

1. **Attempt 1:** dispatch a NEW fix subagent with the error output, the original task, and specific instructions about what went wrong.
2. **Attempt 2:** if attempt 1 also fails, dispatch one more with a simplified scope or different approach.
3. **After 2 failed attempts:** STOP. Report failure to the user. The task probably needs redesign.

**NEVER:**

- Write code yourself to "help" or "finish up"
- Fix the subagent's work inline — that pollutes your context and defeats fresh-subagent isolation
- Silently skip the failed task
- Lower quality gates (skip reviews) because a task is "almost done"

## After All Tasks Complete

0. Call `phase_tracker({ action: "start", phase: "verify" })`. (The `implement` phase was started at execution start and auto-completes from `plan_tracker` once all tasks are done; this flow runs its own verify gate instead of `/skill:verification-before-completion`, so it must mark verify itself.)
1. **Parent full verification.** Run the complete plan-header `**Verification:**` command set foreground in the worktree via `(cd "<worktree>" && <command>)`: tests plus every declared lint, type, format, and build check. A failure must be repaired and the full set rerun successfully before the next step. Before dispatching a verification repair, reopen (`in_progress`) every existing plan-task index whose `Files:` ownership includes its touched files; leave unowned cross-cutting repair work in the verification report. Those indices stay `in_progress` through the successful full rerun **and** step 2's whole-diff review accepting the repair — that acceptance is their completion point, not the passing rerun. Commit any verification-produced tracked changes; use the resulting `HEAD_SHA` in the review task and include the commands/results in its existing `DESCRIPTION`.
2. **Whole-diff code review.** Only after passing full verification, dispatch one foreground whole-diff `code-reviewer` per `/skill:requesting-code-review` against that committed HEAD, with `SCOPED_TEST_COMMANDS: none`; the reviewer does not repeat the full suite. Address Critical and Moderate findings. Before dispatching a review repair, reopen (`in_progress`) every existing plan-task index whose `Files:` ownership includes its touched files; leave unowned cross-cutting repair work in the review report. Mark each reopened index `complete` only once the repair is re-verified and the re-review accepts it — this is the same completion point step 1's reopened indices wait for, not an extra gate, and the gate order stays full verification -> whole-diff CR -> conformance. Any repair invalidates prior full verification, so rerun the full set successfully before the next gate.
3. **Close the loop — conformance check.** The review in step 2 is plan-vs-code (single-step); it inherits any requirement the plan already dropped.

   **Happy-path run - first action of this step, only when the plan header carries a `**Happy path:**` line or the diff selects a row.** The overrides file's `## Happy path` table (schema in the README overrides contract) names path-prefixed rows; the plan header's line is the plan-time default.

   1. Re-derive the row from `git -C "<worktree>" diff --name-only <base>..HEAD` (`<base>` = the branch point): two or more non-`cross-cutting` rows, or a path inside the `cross-cutting` row's own `Paths` and inside no other row's -> `cross-cutting`, taking precedence (no `cross-cutting` row -> no run and no outcome line); else paths inside exactly one non-`cross-cutting` row's `Paths` -> that row; none -> no run and no outcome line. Run the diff-derived row; when it differs from the header label, record `row: <diff-derived> (header: <label>)` in `summary.txt`.
   2. Substitute shell-quoted literal values for every placeholder in this one bash block: the absolute worktree path, command verbatim, first command token after leading `NAME=value` assignments, duration (default `10m`), diff-derived row, and optional header label (use the row label when absent). Derive the token from the declared command without evaluating it or parsing general shell grammar. Run the entire block in one tool call; do not carry shell variables between calls. Read its printed summary path and outcome for subsequent tools.

      <!-- happy-path-shell -->
      ```bash
      HP_WORKTREE={{HP_WORKTREE}}
      HP_CMD={{HP_COMMAND}}
      HP_TOKEN={{HP_TOKEN}}
      HP_DURATION={{HP_DURATION}}
      HP_ROW={{HP_ROW}}
      HP_HEADER={{HP_HEADER}}
      HP_DIR=$(mktemp -d) || exit 1
      HEAD=$(git -C "$HP_WORKTREE" rev-parse HEAD) || exit 1
      HP_LABEL=$HP_ROW
      if [[ "$HP_HEADER" != "$HP_ROW" ]]; then HP_LABEL="$HP_ROW (header: $HP_HEADER)"; fi
      if ! TO=$(command -v timeout || command -v gtimeout); then
        OUTCOME='happy-path: not run - no timeout binary'
      elif [[ -z "$HP_TOKEN" || -z "${HP_CMD//[[:space:]]/}" ]] || ! (cd "$HP_WORKTREE" && command -v "$HP_TOKEN" >/dev/null); then
        OUTCOME='happy-path: not run - command not found'
      else
        BEFORE=$(git -C "$HP_WORKTREE" status --porcelain --untracked-files=all) || exit 1
        if (cd "$HP_WORKTREE" && "$TO" -k 30s "$HP_DURATION" bash -c "$HP_CMD") >"$HP_DIR/transcript.log" 2>&1; then
          EXIT=0
        else
          EXIT=$?
        fi
        AFTER=$(git -C "$HP_WORKTREE" status --porcelain --untracked-files=all) || exit 1
        if [[ "$BEFORE" != "$AFTER" ]]; then
          OUTCOME="happy-path: failed - dirtied worktree: ${AFTER//$'\n'/; }"
        elif [[ "$EXIT" == 0 ]]; then
          OUTCOME='happy-path: passed'
        elif [[ "$EXIT" == 75 ]]; then
          OUTCOME="happy-path: not run - environment unavailable: $(tail -n 1 "$HP_DIR/transcript.log")"
        elif [[ "$EXIT" == 124 || "$EXIT" == 137 ]]; then
          OUTCOME="happy-path: failed - timed out after $HP_DURATION"
        elif [[ "$EXIT" == 126 ]]; then
          OUTCOME='happy-path: not run - not executable'
        else
          OUTCOME="happy-path: failed (exit $EXIT)"
        fi
      fi
      { printf '%s\nhead: %s\nrow: %s\n' "$OUTCOME" "$HEAD" "$HP_LABEL"; if [[ -f "$HP_DIR/transcript.log" ]]; then printf '\n'; tail -n 200 "$HP_DIR/transcript.log"; fi; } >"$HP_DIR/summary.txt" || exit 1
      printf 'summary: %s\noutcome: %s\n' "$HP_DIR/summary.txt" "$OUTCOME"
      ```

   3. If the block exits non-zero or its printed summary is missing/unreadable, stop verification and report the shell error; never dispatch conformance with the selected run omitted. Distinguish this runner failure from a command's `failed`/`not run` outcome recorded in a readable summary. Treat any status difference (tracked or untracked residue) as failed regardless of exit code. Never stage or commit the listed paths as deliverables; remove untracked residue and restore tracked residue (`git -C "<worktree>" checkout -- <paths>`) explicitly before the conformance dispatch, so the tree is clean when the audit-time input rule runs.

   | Condition | Outcome line |
   |---|---|
   | worktree differs after run | `happy-path: failed - dirtied worktree: <paths>` |
   | exit 0, worktree clean | `happy-path: passed` |
   | exit 75 | `happy-path: not run - environment unavailable: <last line of transcript.log>` |
   | exit 124, or 137 after the `-k` kill | `happy-path: failed - timed out after <duration>` |
   | exit 126 | `happy-path: not run - not executable` |
   | pre-check failed | `happy-path: not run - <reason>` |
   | any other non-zero | `happy-path: failed (exit <n>)` |
   | no header line and no diff-derived row | no run, no outcome line |

   A timeout is `failed`, not `not run`: a consumer that never receives its message hangs, and the reviewer must see it; `not run` is reserved for a command that never executed. `timeout -k 30s` sends `TERM` then `KILL`; a script that does not trap `TERM` leaves its stack up, and the next run's exit 75 surfaces that. The full `transcript.log` stays in `$HP_DIR` for the human; the reviewer receives `summary.txt` only (outcome, `head:`, `row:`, 200-line tail). A `failed` or `not run` outcome never stops the flow and never becomes a repair item at this step - it is evidence for the audit; `$HP_DIR` and the outcome carry into the fix loop per `conformance-check.md`. Never split the shell block across calls.

   Before marking verify complete, dispatch a fresh-context **`conformance-reviewer`** — its **own** dispatch, never fused into the step-2 review — to confront the deliverable (code **and** docs) against the *origin* — the spec **and** the original prompt — per `verification-before-completion/reference/conformance-check.md`. Pass the spec path, the verbatim original prompt, the full diff, and - when a run happened - `Happy path: <abs path to $HP_DIR/summary.txt> (<outcome>)` (`<outcome>` = the outcome line without its `happy-path: ` prefix). Follow that reference for the partition rule, concern decomposition, and fix-loop mechanics; do not reimplement them here. The fix loop reuses durable `Gn` gap indices as defined in conformance-check.md; it never calls `phase_tracker`. Call `phase_tracker({ action: "complete", phase: "verify" })` only when the reference says the handoff is durably complete: either a current `CONFORMS` result, or a current `## Closure / conformance` inventory whose carried-open concerns all come from valid deferred gaps, including `recommended: fix` gaps carried open because a declared precondition made the fix loop unavailable (`maxFixRounds: 0`, or no eligible named-branch worktree). A started positive-cap fix loop that blocks, fails, or exhausts its rounds with an open `fix` gap is escalation, not completion; on escalation, do not complete verify, stop and report.
4. Summarize what was implemented (tasks completed, files changed, test counts, code-review verdict). Emit the `## Closure / conformance` block exactly as defined in `verification-before-completion/reference/conformance-check.md`: it must open with the sentinel (`status: CONFORMS (0 open)` or `status: GAPS (N open)`, then `audited-base: <full HEAD SHA>`, then - exactly when a happy-path run happened - `happy-path: <value of the reviewer's Happy path: line from the final audit, the text after Happy path: >`), then carry the exact durable concern schema by reference with no renamed or reformatted fields. `finishing-a-development-branch` Step 3.5 consumes that block verbatim.
5. **Proceed to finishing — no confirmation prompt.** Once verify is complete per step 3's criterion, invoke `/skill:finishing-a-development-branch <abs worktree path>` immediately - the same absolute path every dispatch in this flow carried as `cwd`; finishing stops without it. Its Step 4 menu (PR / draft PR / squash / keep / discard) is the human gate; a separate "ready to finish?" prompt only stacks a second stop in front of it. Carried-open concerns are resolved there per concern via the `## Closure / conformance` block from step 4. Manual testing is a follow-up after the finishing choice (on `<base-branch>` after a squash-merge, or on the PR branch), never a reason to hold this gate.

## Red Flags — STOP

- Writing code yourself instead of dispatching.
- Pausing between tasks for anything other than `NEEDS_CONTEXT`, `BLOCKED`, a fix-loop escalation, a workflow warning, or a spec amendment.
- Dispatching parallel implementers on overlapping files, on a shared mutable runtime resource, or without `worktree: true`.
- Making a subagent read the plan, inlining spec excerpts to the spec reviewer, or dispatching with a `SCOPED_TEST_COMMANDS` value missing or not copied from the plan's `Tests:` bullets.
- Dispatching `code-reviewer` before every in-scope spec-review verdict is ✅, or per task inside a wave.
- Moving to the next task with either review still showing issues, or skipping the `Implementer Status` parse.
- Dispatching fix 3 without a reviewer-emitted `CONVERGING` verdict, or continuing past `STAGNANT` instead of escalating.
- Running the full verification entrypoint, or any test command outside `SCOPED_TEST_COMMANDS`, during the implement phase.
- Dispatching a repair before reopening the plan-task indices that own its files, whole-diff CR before parent verification passes, or conformance before the CR result is accepted.
- Polling, joining, or relaunching an unexpectedly asynchronous dispatch, or starting on main without explicit user consent.

## Integration

**Required workflow skills:**

- `/skill:using-git-worktrees` — set up isolation first (small changes can branch in place with user approval)
- `/skill:writing-plans` — creates the plan this skill executes
- `/skill:requesting-code-review` — review template for reviewer subagents
- `/skill:finishing-a-development-branch <abs worktree path>` — invoked automatically once every gap is fixed (`CONFORMS`) or carried open

**Subagents follow by default:**

- TDD — runtime warnings on source-before-test. Implementer agents receive the three-scenario TDD instructions (new feature / modifying tested code / trivial) via agent profile and prompt template.

## Project overrides

If a gauntlet overrides file exists - checked in order: `.pi/gauntlet-overrides.md`, `<repo root>/gauntlet-overrides.md`, `<repo root>/doc/gauntlet-overrides.md`; first found wins - read it. Read and apply `## conventions` whenever present, without a relevance judgment. Give this skill's named section precedence over conflicting `## conventions` rules. Use other relevant sections - by name match, by topic (routing, verification, worktrees, etc.), or by workflow convention - to override or extend the instructions above. Project-local `AGENTS.md` is already in context — check it for project-specific routing tables, service paths, and verification commands.
