---
name: dev-operations
description: Unified reference for all 17+ dev-* operations — purpose, inputs, backing (skill/CLI/inline), and behavior contract. The single source of truth for what each `/sp:dev-*` command does. (`implement` is covered as a sub-mode of run, #4; `runall` is the batch execution operation, #13; `refineall` is the batch refine operation, #5a.)
see_also:
  - spur-dev
---

# Dev Operations

Every `sp:dev-*` command maps to exactly one **operation** defined here. This is the authoritative
reference: if an operation is not in this file, no command should delegate to it. The operation
table is the index; the per-operation sections below are the detail.

## Two backing patterns

| Pattern   | Meaning                                                                                                                                             | Commands                                                                                                                    |
| --------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `Skill()` | Delegates to a backing skill via `Skill(skill="<skill>", args="<op> $ARGUMENTS")`. The skill owns the procedure; the command is a thin entry point. | implement, unit, review, verify, verifyall, run, refine, refineall, plan, brainstorm, runall, parallel, wrap, wrapall, idea, job-dump, job-resume |
| `inline`  | The procedure is defined directly in the command file. No `Skill()` delegation — the command carries its own steps.                                 | changelog, gitmsg, fixall, handover                                                                                         |

The `Skill()` commands back onto six skills: `sp:spur-dev` (planning + execution workflow + batch),
`sp:code-implementation` (single implement step), `sp:code-testing` (unit/coverage work),
`sp:code-verification` (SECUA review + traceability), `sp:parallel-execution` (fan-out / parallel batch),
and `sp:brainstorm` (structured ideation). The `runall` operation (#13) is `sp:spur-dev`'s batch entry — it delegates the driver loop to the
`sp:super-planner` agent (the batch orchestrator) per [execution-batch.md](execution-batch.md).
`dev-parallel` (#13a) is the parallel counterpart. `dev-brainstorm` carries the two artifact exits — `--task` (one task) and `--feature` (validated
feature with BDD AC; the front-half entry that hands off to `dev-plan`). The 4 `inline` commands
cover git tooling and operational utilities that have no natural skill home — creating a skill for
each would be scope creep for one-liner procedures.

> **`dev-dogfood`** is not in this table. It is a thin `Skill()` wrapper over the **`sp:dogfood-testing`**
> backbone skill (which owns the 4-phase dogfood protocol, the live ledger, and the report template);
> it does not map to a numbered dev-\* operation. See its command file and the backing skill for details.

> **`dev-find-issue`** is not in this table. It is a thin `Skill()` wrapper over
> **`sp:history-anatomy`** for daily/ad-hoc imported-history forensics: fixed twelve-section report,
> baseline comparison, cache branch, independent validation, and atomic publication. It never
> imports history or creates a task. See `plugins/sp/commands/dev-find-issue.md` and
> `plugins/sp/skills/history-anatomy/SKILL.md`.

> **`dev-review-session`** is not in this table. It is a thin `Skill()` wrapper over
> **`sp:session-review`** for an immediate, inline review of the active conversation. Report-only
> is the default; `--fix auto` (alias `--triage`) applies pure-doc / one-to-two-line fixes and files
> remaining actionable findings as implement-ready tasks through the task CLI; `--fix all` fixes
> every actionable finding inline and files none. It launches no workflow or agent and
> imports no history. Use it before the active session ends; use history-anatomy for ended sessions,
> cross-agent windows, trends, or quantitative forensics.

> **`dev-find-conflict`** is not in this table. It is a thin `Skill()` wrapper over
> **`sp:conflict-finding`** (authority-aware four-pillar semantic audit → optional confirmed,
> owner-routed remediation). Standalone audit — not a spine pipeline stage. Audit mode is read-only;
> `--resolve` opens a proposal/confirmation workflow that routes each approved repair through its
> owner surface (`spur task`/`spur feature`, `sp:doc-evolve`, the Spur dev lifecycle, or the
> Superskill capability lifecycle). See `plugins/sp/commands/dev-find-conflict.md` and
> `plugins/sp/skills/conflict-finding/SKILL.md`.

> **`dev-next`** is likewise not a numbered spine operation. It is a thin `Skill()` wrapper over the
> **`sp:next-router`** skill — a status→command _meta-router_ that dispatches into the operations
> above (refine/run/verify/unit/wrap/…) via TABLE A/B/C; it never implements an operation itself.
> See `plugins/sp/skills/next-router/references/routing-table.md` for the routing SSOT.
>
> **Batch consumer (task 0279):** `sp:super-planner` / `/sp:dev-runall` **consumes** TABLE A STOP rows
> for preflight + one-shot recovery (`plugins/sp/scripts/batch-preflight.ts`) but keeps
> `task-pipeline.yaml` as the happy path. Do **not** deep-merge batch orchestration into a loop of
> `/sp:dev-next`. Single-task "what's next?" stays `/sp:dev-next`; multi-task execution stays
> `/sp:dev-runall` → super-planner.

## Operation map

| #   | Operation  | Command             | Backing           | Skill / Verb                                                                       | Arg-hint                                                                                                                                                                                               |
| --- | ---------- | ------------------- | ----------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 1   | unit       | `dev-unit`          | `Skill()`         | `sp:code-testing`                                                                  | `<target> [--coverage <pct>] [--agent <inline\|auto\|name>] [--auto]`                                                                                                                                  |
| 2   | review     | `dev-review`        | `Skill()`         | `sp:code-verification` (`review`) + `sp:functional-review` + `sp:code-improvement` | `[--tasks <selector> \| --feature <id>[,<id>] \| --scope <path>[,<path>]] [--agent <inline\|auto\|name>] [--focus <dims>] [--triage] [--worktree [<name>]] [--auto]`                                                                                              |
| 3   | verify     | `dev-verify`        | `Skill()`         | `sp:code-verification` (`verify`)                                                  | `<wbs> [--agent <inline\|auto\|name>] [--fix <none\|blockers-first\|all>] [--focus <lens>] [--bdd] [--auto] [--force] [--next] [--skip-shippable]`                                                     |
| 3a  | verifyall  | `dev-verifyall`     | `Skill()` → agent | `sp:spur-dev` (`verifyall`)                                                        | `--tasks <selector> [--feature <id>] [--agent <inline\|auto\|name>] [--fix <none\|blockers-first\|all>] [--focus <lens>] [--bdd] [--auto] [--force] [--next] [--json] [--skip-shippable] [--worktree [<name>]]` |
| 4   | run        | `dev-run`           | `Skill()`         | `sp:spur-dev` (`run` / `implement`)                                                | `<wbs> [--mode <full\|implement>] [--agent <inline\|auto\|name>] [--auto] [--next] [--wrap] [--continue] [--worktree [<name>]] [--no-summary]`                                                                                              |
| 5   | refine     | `dev-refine`        | `Skill()`         | `sp:spur-dev` (`refine`)                                                           | `<wbs> [--focus <mode>] [--description <text>] [--depth <standard\|ready>] [--agent <inline\|auto\|name>] [--auto] [--next]`                                                                           |
| 5a  | refineall  | `dev-refineall`     | `Skill()`         | `sp:spur-dev` (`refineall`)                                                        | `--feature <id> \| --tasks <selector> [--focus <mode>] [--description <text>] [--depth <standard\|ready>] [--agent <inline\|auto\|name>] [--auto] [--keep-going] [--status <s>] [--json] [--worktree [<name>]]` |
| 6   | plan       | `dev-plan`          | `Skill()`         | inline driver (`idea-pipeline`) or async workflow                                  | `"<description>" [--feature <id>] [--parent <feature-id>] [--skip-design] [--agent <inline\|auto\|name>] [--auto]`                                                                   |
| 7   | docs       | _(no thin wrapper)_ | `Skill()`         | `sp:doc-evolve`                                                                    | `"<change description>"`                                                                                                                                                                               |
| 8   | changelog  | `dev-changelog`     | `inline`          | git log + conventional-commit grouping                                             | `[<file>] [--since <ref>] [--until <ref>] [--version <ver>]`                                                                                                                                            |
| 9   | gitmsg     | `dev-gitmsg`        | `inline`          | bounded diff capture → concern grouping → conventional commit                      | `[--commit] [--squash] [--all] [--scope <path>]`                                                                                                                            |
| 10  | fixall     | `dev-fixall`        | `inline`          | lint + test fix loop                                                               | `[<validation-command>] [--max-retry <n>] [--scope <path>] [--gate-log <path>] [--findings <anchors>]`                                                                                                 |
| 11  | handover   | `dev-handover`      | `inline`          | structured doc generation                                                          | `"<blocker description>"`                                                                                                                                                                              |
| 11a | job-dump   | `dev-job-dump`      | `Skill()`         | `sp:spur-dev` (`job-dump`) | `--file <path>` |
| 11b | job-resume | `dev-job-resume`    | `Skill()`         | `sp:spur-dev` (`job-resume`) | `--file <path>` |
| 12  | brainstorm | `dev-brainstorm`    | `Skill()`         | `sp:brainstorm` (`dev-brainstorm`)                                                 | `<topic> [--depth <basic\|detailed\|comprehensive>] [--options <n>] [--agent <inline\|auto\|name>] [--skip-discovery] [--wayfind] [--task [<feature-id>]] [--feature [<parent-id>]] [--next]`          |
| 13  | runall     | `dev-runall`        | `Skill()` → agent | `sp:spur-dev` (`runall`) → `sp:super-planner`                                      | `--tasks <selector> [--feature <id>] [--mode <sequential\|parallel>] [--keep-going] [--auto] [--agent <inline\|auto\|name>] [--json] [--wrap] [--next] [--continue] [--worktree [<name>]] [--no-summary]`                      |
| 13a | parallel   | `dev-parallel`      | `Skill()`         | `sp:parallel-execution`                                                            | `--tasks <selector> [--feature <id>] [--mode <fan-out\|review-panel\|investigation>] [--agent <inline\|auto\|name>] [--json]`                                                                          |
| 14  | wrap       | `dev-wrap`          | `Skill()`         | `spur workflow run` (wrapup-pipeline)                                              | `<wbs> [--agent <inline\|auto\|name>] [--auto] [--merge] [--dry-run]`                                                                                                                                 |
| 15  | wrapall    | `dev-wrapall`       | `Skill()`         | `spur workflow run` (wrapup-pipeline)                                              | `[--since <iso>] [--feature <id>] [--status <s>] [--agent <inline\|auto\|name>] [--auto] [--merge] [--dry-run]`                                                                                        |
| 16  | idea       | `dev-idea`          | `Skill()`         | inline driver (`idea-pipeline`) or async workflow                                  | `"<idea>" \| --from-file <path> [--skip-design] [--agent <inline\|auto\|name>] [--auto]`                                                                                                                              |
| 17  | refactor   | `dev-refactor`      | `Skill()`         | `sp:code-refactoring` skill (thin wrapper, ADR-032)                                | `[<description>] [--scope <path>] [--focus <api\|architect\|tests\|ui\|auto>] [--fix <none\|blockers-first\|all>] [--check <cmd>] [--agent <inline\|auto\|name>] [--auto]`                                                                                          |

## Skill-backed operations

These delegate to a backing skill via `Skill()`. The command file is a thin wrapper; the skill
owns the full procedure. The command's `## Implementation` section contains the `Skill()` call and
must not be changed without updating the backing skill.

> **`--agent <inline|auto|name>` SSOT:** the full value-semantics contract (one rule, value table,
> objective triggers, executor precedence chain, `implementAgent` override) lives in
> [cross-cutting.md](cross-cutting.md#inline-default-execution-surface).
> Every `Skill()` operation below accepts the selector; `inline` runs in-session, `auto`
> tier-resolves a subprocess executor, a name pins that executor, and named escalation triggers
> override inline. This note is the single statement of that contract; per-operation entries do
> not restate it.

### 1. unit

- **Purpose:** Extend or generate tests for a task or file until the coverage target is met with a fully passing suite.
- **Inputs:** `<target>` (required — WBS, task file, source file, or glob). `--coverage <pct>` overrides the default target. Execution defaults to inline (in-session); `--agent <inline|auto|name>` selector accepted (see [SSOT](cross-cutting.md#inline-default-execution-surface)).
- **Backing:** `sp:code-testing` competency skill.
- **Behavior:** Detect the project stack → read the implementation → identify untested paths → write targeted tests → measure coverage → iterate until the per-file line/function target (≥90%) is met. The language-agnostic procedure (two workflows, gap categorization, coverage-vs-quality, escalation) and the per-stack adapters are the SSOT in **`sp:code-testing`** (`references/unit-testing.md` + `references/stacks/`). The spine dispatches here; it does not inline the procedure.
- **Delegation:** `Skill(skill="sp:code-testing", args="$ARGUMENTS")`

### 2. review

- **Purpose:** Multi-dimensional code review of a task, a task set, or paths — (1) functional requirements traceability (per task target), (2) SECUA framework (Security, Efficiency, Correctness, Usability, Architecture), (3) architecture depth.
- **Modes:**
  - **Task-set mode (`--tasks <selector>` / `--feature <id>[,<id>]`)**: resolves the set once with the batch selector grammar ([execution-batch.md § Step 1](execution-batch.md#step-1--selector-resolution-r1)) — comma WBS list or `feature:<id>` (the `--feature` comma list is union sugar); status pseudo-lists and `ready` are rejected for review. One WBS-mode review per implemented task, each writing its own merged `## Review` (F92 0593 R1); tasks in `backlog`/`todo`/`blocked` are reported NOT-STARTED and skipped (§ 3a vocabulary); a per-task failure does not stop the remaining tasks; the run ends with a combined summary table (WBS, verdict, P1/P2 counts).
  - **WBS mode (`<wbs>`, the per-task recipe)**: Runs functional requirements traceability (`sp:functional-review`), SECUA framework (`sp:code-verification`), and architectural depth (`sp:code-improvement`). The three skills return review fragments; the coordinator writes the combined `## Review` (F92 0593 R1).
  - **Path mode (`<path>`, the per-path recipe)**: Runs advisory SECUA framework (`sp:code-verification`) and architectural depth (`sp:code-improvement`). Performs no task mutation.
  - **Path-set mode (`--scope <path>[,<path>]`)**: paths must exist (exit 2 otherwise), are normalized, duplicates dropped and nested paths collapse to the ancestor (`--scope apps,apps/cli` → `apps`); one advisory sub-review per surviving path (Step 3p path scope, eligible for native-subagent dispatch per [dispatch-surface.md](../../parallel-execution/references/dispatch-surface.md)); the coordinator merges the sub-reviews, runs one cross-path architecture pass (`sp:code-improvement` over the inter-path imports), and emits one merged advisory report. No task mutation.
- **Inputs:** exactly one of `--tasks <selector>`, `--feature <id>[,<id>]`, or `--scope <path>[,<path>]` (deprecated positional alias, below) — more than one exits 2 naming the conflict; none exits 2 with usage (no implicit `cwd` target). Review executes inline (in-session) by default. `--agent <inline|auto|name>` selector accepted (see [SSOT](cross-cutting.md#inline-default-execution-surface)). `--focus <dims>` narrows the review dimensions — vocabulary SSOT: [code-verification/SKILL.md](../../code-verification/SKILL.md) review mode (`functional` → `sp:functional-review`; `architecture` → `sp:code-improvement` + SECUA-A; S/E/C/U → `sp:code-verification`). `--auto` skips objective HITL confirmations (the pipeline's review stage passes it). `--triage` opts into bounded remediation after the report (below). `--worktree [<name>]` isolates the triage writes (below; requires `--triage`). Note: the positional `<wbs\|path>` is a **deprecated alias** for one release — a `^\d{4}$` token with a resolvable task → `--tasks`; an existing path → `--scope`; otherwise exit 2, with a deprecation warning naming the replacement. `--fix` is **deprecated** (accepted no-op with warning; route remediation to `--triage` or `/sp:dev-verify --fix`); `--next` is **removed** (route progression to `/sp:dev-next`). The task pipeline's review stage never passes `--triage` or `--worktree`.
- **Triage (`--triage`):** runs inline in the invoking session after the merged report — never inside `sp:super-reviewer` or the review skills, which stay report-only. With `--agent <name>`, only the review is delegated; triage still runs inline on the returned findings. Never fix straight from the raw findings list:
  1. **Bucket every finding exactly once.** **Direct fix** — local, low-risk, obvious root cause: no design choice, no public-surface / schema / dependency change, not a shared write path, verifiable by a targeted check (docs, a guard, a missing throw, a wrong path helper, a stale comment). **Task** — real and actionable but needs design, crosses modules, touches a public surface, or is not verifiable locally; skip it when an existing task already owns it (cite that WBS). **Note** — pre-existing, environmental, or ownerless; report only.
  2. **Apply direct fixes** — smallest surgical diff in project style, then re-verify each with its targeted check (focused test, lint, or the exact command that exhibited the defect). A fix that grows beyond the bar or fails its check moves to the Task bucket with what was learned; do not leave it half-applied.
  3. **File the Task bucket as one or more tasks**, one per cohesive unit of work that one agent can implement and verify in one run — split unrelated fixes, merge findings that share a root cause or file set. File under the existing non-terminal feature that owns the affected surface (a `done` owner blocks `todo` promotion with `L4.feature-terminal` — reopen it with `spur feature update <id> active` when its goal still covers the work); if none fits, create a child feature under the closest existing parent — never a new root feature. Write through the CLI-gated corpus surface only (`spur task create --feature <id> --skip-ready`, then `spur task update <wbs> --section <s> --from-file`). Each task must meet the implement-ready bar ([§ 5. refine](#5-refine), `--depth ready`) so it cannot drift: per finding the evidence (`file:line`), the defect (a root cause not reproduced in this session is written as a labeled hypothesis with its confirming repro, never as the fix premise), the chosen fix direction with rejected alternatives, file targets, AC, and out-of-scope; promote `backlog → todo` only when `spur task check <wbs> --json` is clean. Name what the direct fixes already resolved in each task's Background.
  4. **Gate and report.** Run the project gate once after the direct fixes. Report a Triage section: each applied fix (path + one-line what + verification), each filed task (WBS + feature + scope), and the Notes. Never commit or create a branch outside `--worktree`.
- **Worktree (`--worktree [<name>]`):** omitted → all writes land in the current working tree on the current branch; no branch creation, checkout, or commit (the operator commits). Given → the [execution-batch.md § Worktree isolation](execution-batch.md#worktree-isolation---worktree-name) lifecycle as a run of one: marker `command` = `dev-review`, `selector` = the full normalized target list, derived branch/directory slug = `sp/review-<first>-and-<N>-<short-id>` for a multi-target run (N = target count) or `sp/review-<slug>-<short-id>` for a single target (the WBS or the path's basename). Admission is "every target resolves" (each a known WBS or an existing path) — no `quickReadiness` task-set check. Review and triage both run in the tree; WT-3b commits the fixes and filed tasks, bucketed across all targets once (identical `file:line` findings deduped). The WT-4 success condition reads as "every direct fix passed its check and the project gate is green"; a failed check or gate takes the WT-5 retention path. Rejected without `--triage` (WT-7) — to review another worktree read-only, pass a path inside it.
- **Backing:** `sp:functional-review`, `sp:code-verification` (review mode), `sp:code-improvement`.
- **Behavior:** WBS mode runs functional traceability + SECUA + architecture depth, ranking findings P1–P4, and hands the merged report to the review coordinator, which writes `## Review`. Component skills never write `## Review` in coordinated mode. Path mode runs advisory SECUA + architecture depth with no task mutation.
- **Delegation:** WBS mode: `sp:functional-review` + `sp:code-verification` (review) + `sp:code-improvement`; Path mode: `sp:code-verification` (review) + `sp:code-improvement`.

### 3. verify

- **Purpose:** Requirements traceability — verify a task's implementation against its acceptance criteria, producing a PASS/PARTIAL/FAIL verdict with per-requirement evidence. Optionally (with `--fix all`) evaluate **feature shippable readiness**.
- **Inputs:** `<wbs>` (required). Verify executes inline (in-session) by default. `--agent <inline|auto|name>` selector accepted (see [SSOT](cross-cutting.md#inline-default-execution-surface)). `--fix`, `--focus`, `--bdd`, `--auto`, `--force` modulate the verify pass. `--next` (terminal chain link): on the **post-`--fix`** PASS verdict, transition `testing → done` through the FSM (target-aware `--as done` guard honored). On PARTIAL/FAIL or guard failure, stop as review-pending. **`--skip-shippable`** (alias `--skip-shipable`): disable the shippable gate that otherwise runs under `--fix all` when the task has a `feature_id`.
- **Backing:** `sp:code-verification` skill, `verify` mode.
- **Behavior:** Status guard → change-scope detection → requirements traceability → SECUA review → verdict aggregation → findings write-back → verdict-artifact emission → optional `--fix` pass → **shippable readiness** (when active). The per-task verdict gates the pipeline's `done` transition. With `--next`: the (post-`--fix`) PASS verdict → transition to `done` (FSM guard honored); PARTIAL/FAIL → stop and surface verdict. Shippable FAIL does not rewrite the task verdict line but must be printed; feature is not “ready.”
- **Shippable readiness (default on with `--fix all`):** After the task verdict, if `--fix all` and the task has `feature_id` and not `--skip-shippable`, run `spur feature check <id> --json` + linked-task completeness. Emit `Shippable: PASS|FAIL|N/A`. FAIL when feature AC scenarios are orphaned/unverified or any linked task is not `done`/`cancelled`. SSOT procedure: `sp:code-verification` Step 13.
- **Delegation:** `Skill(skill="sp:code-verification", args="verify $ARGUMENTS")`

### 3a. verifyall

- **Purpose:** Batch verification of a set of tasks (or all tasks under a feature) against their requirements and AC. Produces per-task verdicts + a summary report with aggregate statistics (counts, table, overall batch verdict). With `--fix all`, also evaluates **feature shippable readiness** once for the set.
- **Inputs:** `--tasks <selector>` (required unless `--feature`). `--feature <id>` (convenience for `--tasks feature:<id>`). Shared verify flags from `dev-verify` (`--agent <inline|auto|name>`, `--fix`, `--focus`, `--bdd`, `--auto`, `--force`, **`--skip-shippable`**). `--next` (per-task lifecycle chaining: on a PASS verdict transition `testing → done` through the FSM with the target-aware `--as done` guard honored; PARTIAL/FAIL does not transition; transitions run **before** the shippable gate so `spur feature check` sees final statuses). `--json` for machine-readable summary report.
- **Backing:** `sp:spur-dev` skill, `verifyall` operation (resolves the set using the shared selector grammar, dispatches per-task verify via `sp:code-verification` verify mode, writes per-task artifacts, aggregates and emits the batch summary report, then optional shippable gate).
- **Behavior:** Resolve + freeze the set (supports `--feature` sugar). For each task: apply status guard, requirements traceability + AC + SECUA review, emit the verdict artifact (per-task fix pass under `--fix`). `## Testing` is written by the deterministic `record` step from the artifact (F92 0593 R1). After the batch: **shippable gate once** when active (see below). Emit a structured summary report (markdown or `--json`). Per-task behavior matches single `dev-verify` (except shippable is batch-once). **Batch verdict rollup is deterministic** — computed by `spur task verifyall-aggregate --from-file <batch-input.json> --json` (a tested service module, not agent discretion). **Per-task outcome grammar:** `PASS` / `PARTIAL` / `FAIL` for implemented tasks; `NOT-STARTED` for tasks that have not entered implementation (status `backlog`/`todo`/`blocked` — reachable only via `--force`). **Rollup rule:** all-NOT-STARTED → `UNKNOWN`; any `FAIL` → `FAIL`; any `PARTIAL` or `UNKNOWN` → `PARTIAL`; all `PASS` → `PASS`. NOT-STARTED rows are _excluded_ from the FAIL/PARTIAL rollup (they cannot manufacture a batch failure) but are _reported explicitly_ in the summary ("N NOT-STARTED, excluded from rollup"). This closes the 0341 dogfood gap where a healthy feature with 5 PASS + 2 unstarted tasks read as FAIL. **Shippable FAIL:** treat the batch as not clean — force rollup to at least **PARTIAL** and set `"shippable": false` under `--json` even if every task outcome is PASS.
- **Shippable readiness (default on with `--fix all`):** Active when `--fix all` and feature context exists (`--feature` or unique shared `feature_id`) and not `--skip-shippable`. Procedure: `sp:code-verification` Step 13 once after all per-task legs. Without `--fix all`, do not run the hard gate (optional note: use `--fix all` for ship evaluation).
- **Cache discipline (batch):** freeze the `spur task list --feature <id> --json` (or selector) capture once at resolve; reuse that snapshot for every per-task verify leg. Do not re-list the set mid-batch. Re-read a task body only when that task's sections changed (e.g. after a `--fix` write). Prefer re-reading only cited `file:line` anchors over re-tokenizing full Solution sections when prior Testing is already present.
- **Dogfood / mutation composition:** prefer step-split when dogfooding verifyall with `--fix all` and/or `--next` — first observe-only verifyall, then a separate fix pass, then `--next` only if status transitions are still needed. See `sp:dogfood-testing` §step-splitting.
- **Delegation:** `Skill(skill="sp:spur-dev", args="verifyall $ARGUMENTS")`

### 4. run

- **Purpose:** Run a task through the execution pipeline (full) or execute a single pipeline step (implement).
- **Inputs:** `<wbs>` (required). `--mode <full|implement>` selects the execution mode. `implement` invokes `sp:code-implementation` inline by default. Interactive `full` resolves the selector uniformly (task 0687): omit ≡ explicit `--agent inline`; full mode reads `task-pipeline.yaml` and drives its actions/guards in the host session — host-controlled and non-subprocess, with 0508 eligibility applying to the resolved-inline selector (eligible `agent.run` stages dispatch once to a native subagent, host fallback)). `--agent auto`, a name, or headless invocation launches the workflow subprocess. `--agent <inline|auto|name>` selects the execution surface (see [SSOT](cross-cutting.md#inline-default-execution-surface)). `--auto` skips the HITL approve gate / confirmations and propagates down the `--next` chain. `--next` controls chaining only and never changes the mode; a pipeline implement stage must invoke `/sp:dev-run <wbs> --mode implement`. On implement success with `--next`, transition `todo → wip → testing` through the FSM (guards honored — no `--no-lifecycle`) + chain to `/sp:dev-verify <wbs> --auto --next`. On a guard failure, stop as review-pending. **Partial-deliverable rule:** if the task ships only part of its requirements (e.g. an R1/R2 split with the rest in a follow-up task), the `## Solution` section must state that explicitly and the verify verdict will record the scope. `--worktree [<name>]` runs the full pipeline inside an isolated git worktree (create or reuse; FF-merge on success, retain on failure) — the batch lifecycle in [execution-batch.md § Worktree isolation](execution-batch.md#worktree-isolation---worktree-name) applied to a batch of one; rejected with `--mode implement`. `--no-summary` skips the [execution summary](#execution-summary) printed after a full-mode run. `--wrap` hands off to `/sp:dev-wrap <wbs>` after the main step; the `--agent` selector is preserved into that handoff when supplied (omission remains omission), and the wrap hop reports its own trigger-3 subprocess override per the wrap contract.
- **Backing:** `sp:spur-dev` skill — `run` operation for the full pipeline (the spine drives it); `sp:code-implementation` competency skill for the implement step (the spine dispatches to it).
- **Modes:**
  - **`full`** (default): Drive the full pipeline — precheck → implement → test → review → approve(HITL) → verify → record → done. Interactive omit/inline uses [inline-pipeline-driver.md](inline-pipeline-driver.md) (host-controlled; eligible stages may use a native subagent); explicit/headless executor selection invokes `spur workflow run task-pipeline.yaml --vars '{"wbs":"<wbs>"}'` (with `profile: auto` when `--auto`). Both monitor/surface HITL and preserve the YAML gates. `--next` never changes this mode.
  - **`implement`** (explicit `--mode implement` only): Execute only the implement step. Read the task's `## Requirements` / `## Design` / `## Plan`, write the code that satisfies them, author the `## Solution` change-map section (file:line + what/why per changed file) via `spur task update <wbs> --section Solution --from-file`. This is the implement step the pipeline calls — it is NOT the pipeline driver. With `--next`: on success, transition `todo → wip → testing` through the FSM (guards honored — no `--no-lifecycle`) + chain to `/sp:dev-verify <wbs> --auto --next`; on a guard failure, stop as review-pending. **Partial-deliverable rule:** if the task ships only part of its requirements (e.g. an R1/R2 split with the rest in a follow-up task), the `## Solution` and `## Review` sections MUST carry a `⚠️ PARTIAL` marker naming the deferred part and the follow-up WBS — see `plugins/sp/commands/dev-run.md` → "Section ownership".
- **Delegation:** `Skill(skill="sp:spur-dev", args="run-inline $ARGUMENTS")` for interactive full omit/inline (resolved-inline semantics, task 0687); `Skill(skill="sp:spur-dev", args="run $ARGUMENTS")` for explicit/headless full mode; `Skill(skill="sp:code-implementation", args="$ARGUMENTS")` for implement mode.

#### Execution summary

Default on for full-mode `dev-run` and `dev-runall`; `--no-summary` skips it. At command start record
`SINCE=$(date -u +%Y-%m-%dT%H:%M:%SZ)`. When the run settles (done, failed or paused), write each run's
`spur workflow progress <run-id> --json` to `$TMPDIR/<run-id>-progress.json` and print, verbatim under an
`### Execution summary` heading:
`node "$(superskill script path sp run-summary.mjs)" --since "$SINCE" --progress <file> --markdown`
(`dev-runall`: one `--progress <wbs>=<file>` per attempted run). One file renders one row per state visit;
several render one row per run; a `driver overhead` row carries host work outside every stage window so rows
sum to `Total` (omitted when parallel runs overlap). Columns: Stage | Status | Time | Wait | Tool calls |
Token (total / non-cached) — total counts every input class plus output; non-cached drops cache reads.
Stage windows with no host transcript record (subprocess executors) render `n/a`, never 0. The summary is
reporting only: a failure prints `Execution summary: n/a (<reason>)` and never changes the run's outcome.
Not printed for `--mode implement` (no workflow run).

### 5. refine

- **Purpose:** Refine a task's requirements via structured Q&A — clarify scope, elicit missing details, tighten acceptance criteria before execution. Optional **implement-ready** depth freezes Design/Requirements/Plan so another agent can implement without inventing design, and is also the path for **evaluating and correcting an existing task** — a review-triage filing, a stale backlog capture, or any task whose claims and proposed fixes may no longer hold.
- **Inputs:** `<wbs>` (required). `--focus <mode>` narrows the gap analysis (values below). `--description <text>` injects operator framing into the Q&A/synthesis. `--depth <standard|ready>` (default **`standard`**) sets the depth bar — see [flag-glossary.md](flag-glossary.md#flag-depth). Execution defaults to inline (in-session); `--agent <inline|auto|name>` selector accepted (see [SSOT](cross-cutting.md#inline-default-execution-surface)). `--auto` skips interactive Q&A (synthesis only) and propagates down the `--next` chain. `--next`: advance to the next step — transition `backlog → todo` through the FSM **idempotently** (only when `status == backlog`; a task already at `todo` or past it skips the transition and chains anyway — `status >= todo` ⇒ already advanced) and invoke `/sp:dev-run <wbs> --mode implement --auto --next`. On a guard/refine failure, stop as review-pending.
- **Status scope:** refine targets `backlog`/`todo` tasks (the same rule `batch-preflight` applies to refineall). A task at `wip` or later has an implementation built on its current spec. Refine it only on an explicit operator request, never under `--auto` alone, and never move its status backwards.
- **`--focus` values** (hint bundles for the gap analysis/Q&A; default `all`):

  | Value | Domain hints | When |
  | --- | --- | --- |
  | `all` | purpose, scope, constraints, dependencies, acceptance criteria, users, timeline | Complete refinement |
  | `requirements` | purpose, scope, acceptance criteria | Standard refinement |
  | `background` | purpose, scope | Thin tasks needing context |
  | `constraints` | constraints, dependencies, timeline | Technical depth |
  | `acceptance` | acceptance criteria, users | Verification focus |
  | `quick` | scope, acceptance criteria | Fast pass |

  Focus narrows what `--depth standard` looks at. Under `--depth ready` the full checklist still runs, and focus only orders the work.
- **Backing:** `sp:spur-dev` skill, `refine` operation. Q&A clarifications are presented as decision briefs per [decision-brief.md](decision-brief.md).
- **Behavior:** Read the task → (ready depth) audit the existing content against the current tree → elicit missing or wrong Background/Requirements/AC/Design/Plan through targeted Q&A (or auto-synthesis) → write each via `spur task update <wbs> --section <name> --from-file`. Done just-in-time, per task, immediately before execution. With `--next`: on success, transition status (idempotently — see Inputs) + chain to dev-run; on failure, stop and surface error.
- **Pre-synthesis skip gate (under `--auto` + `--depth standard` only):** Before invoking synthesis, run `spur task check <wbs> --json`. Filter the findings to the **refine target sections** only:
  `{Background, Requirements, Acceptance Criteria, Design, Plan}`.
  These are the anti-drift surfaces: constraints + planning that cheaper implementers must follow.
  **Solution is not a refine target** (as-built change-map owned by implement). If there are no L3
  findings for any of those sections (regardless of whether the _overall_ exit code is 0 — other
  sections may have findings), emit a structured SKIP result instead of synthesizing:

  ```
  SKIP — sections already meet L3: sections-considered=[Background, Requirements, Acceptance Criteria, Design, Plan], reason="no L3 findings for target sections" (N L4 advisory: <labels>)
  ```

  The `(N L4 advisory: <labels>)` suffix is emitted whenever `spur task check` returned ≥1 L4
  finding — list each L4 finding's one-line label, comma-separated. Omit the suffix when there
  are zero L4 findings. L4 advisories do not block the SKIP; the suffix is informational only.
  Under `--json`/machine consumption, emit the same decision as a structured object so a downstream
  (observe-only) driver need not re-run `spur task check` to reconstruct it:

  ```json
  {
    "result": "SKIP",
    "sections-considered": [
      "Background",
      "Requirements",
      "Acceptance Criteria",
      "Design",
      "Plan"
    ],
    "reason": "no L3 findings for target sections",
    "depth": "standard",
    "l4Advisories": [{ "message": "Missing feature_id — ..." }]
  }
  ```

  Synthesis is only invoked when a real L3 gap exists in a target section. The SKIP result is the normal outcome for a well-specified task under `--auto` + `standard`; it is not a failure.
  **Scope:** only L3 findings whose `section` ∈ {Background, Requirements, Acceptance Criteria, Design, Plan} count toward the SKIP gate. L3 findings on other sections (e.g. `### Review`, `### Solution`) do not block the SKIP — refine does not own those sections.
  **Variant note:** for templates that omit Design or AC (e.g. `review`, `meta`, `issue`), only apply the target sections that the section-matrix allows at the current status (`spur task check` `requiredSections` / optional list).

- **`--depth ready` (implement-ready — never L3-SKIP alone):** When `--depth ready` is set, **do not**
  apply the L3-only SKIP gate above, even under `--auto`. Instead evaluate the **implement-ready
  checklist** against target sections (read codebases, ADRs, dependent WBS, dogfood evidence as
  needed). If any item fails, synthesize and rewrite via CLI-gated section updates until all pass
  (or surface a blocked Q&A with a concrete question). Outcome vocabulary: `refined` (wrote) |
  `ready` (checklist already met, no write — optional alias of refined with zero writes) | `failed`.
  Prefer reporting `refined` when any section changed; if checklist already fully met, emit:

  ```
  SKIP — sections already meet implement-ready checklist: depth=ready, sections-considered=[…]
  ```

  **Implement-ready checklist (all must hold for allowed target sections).** Each item's `id` is
  the `READY_CHECKLIST_IDS` value (`packages/app/src/services/task-readiness.ts`) that the
  create-time ready preparation and the idea-pipeline ready-prepare stage also use:
  1. **`requirements`** — R-items are observable outcomes; explicit out-of-scope / non-goals; no
     ambiguous “wire it up” without a named seam or file area.
  2. **`design`** — WHAT / WHY / WHERE; **frozen names** (types, flags, vars, paths) **or** explicit
     “no new API”; precedence / algorithm when behavior is non-obvious; **anti-patterns** (what not
     to implement); primary file/package targets; handoff to dependent tasks (WBS) if any.
  3. **`plan`** — ordered checklist mappable to R-items; test/verification intent called out.
  4. **`ac`** — every scenario uses an [ac-style-guide.md](ac-style-guide.md) task-side form
     (`- [ ] AC<n> — <title>` or `Scenario: AC<n> — <title>`, with `(req: R<n>)`). `spur task check`
     parses only checkbox and `Scenario:` lines, so any other shape (a plain `- AC1 —` bullet, a bold
     heading) silently escapes its AC checks. When `feature_id` is set, each AC
     title matches a feature scenario title, unless the task is deliberately `ac_altitude:
     task-local`. Given/When/Then stays executable as a verify lens.
  5. **`decisions`** — Q&A open decisions closed or explicitly deferred with owner; links to ADR /
     feature / upstream tasks present when the design depends on them.
  6. **`dependencies`** — if `dependencies[]` exist, Design states what this task assumes from deps
     and what it must leave for dependents (no silent re-ownership of upstream contracts). A
     dependency the Design relies on but `dependencies[]` lacks is added with `spur task deps`.
  7. **`premises`** — every factual claim in Background, Requirements, Design and Plan is checked
     against the **current tree** (read the file, run the query, grep the corpus), not only the gaps.
     This is the **audit pass**; it matters most for a task written earlier or by another agent
     (review-triage filings, stale backlog). Lenses:
     - **Facts** — statuses, `file:line` references, type/field/flag names, counts, "already fixed"
       or "not yet implemented" claims.
     - **Sources** — a cited run, artifact, session or doc exists and says what the task claims. If
       it is gone, say so and restate the claim from code.
     - **Fix soundness** — each proposed fix holds for every caller and mode of the seam it touches,
       does not break a currently valid path, and reuses an existing mechanism before adding one.
     - **Test observability** — each AC names a test layer (and file) that can actually observe the
       behavior. A test that mocks the collaborator carrying the behavior cannot.
     - **Environment** — installed dependency versions match the lockfile and generated artifacts
       are current. If not, the Plan gets a step-0 precondition.
     - **Concurrency** — active worktrees or `wip` tasks touching the same files (`git worktree
       list`, `spur task list --status wip --json`) are recorded in References/Design.
     - **Scope** — the work is not already done, and not owned by another task.

     Contradictions are corrected in **this** refine (rewrite the claim, or re-point the design at
     ground truth), never deferred to the implementer. `--depth ready` exists so a downstream agent
     does not re-derive the analysis; a frozen design built on a false premise is the worst
     available outcome.

  **Correction record.** When the audit changes a claim, append a dated block to Background —
  `**Refine corrections (<YYYY-MM-DD>)**`, one line per correction: claim → verified reality →
  resolution. Never delete an earlier block, so the next reader sees what changed and why. Scope
  decisions made along the way also go into Q&A as closed decisions.

  **Ready finalization.** Once every item holds:
  1. Run `spur task check <wbs> --as todo --json`. Any error means the task is not ready. Fix it,
     or report `failed`.
  2. Fill metadata that is still unset: `spur task update <wbs> --priority <P0–P3>` and
     `--estimate-hours <n>` (both `--json`). Never overwrite a value the operator set.
  3. Promote `backlog → todo` idempotently with `spur task update <wbs> todo --json`, the same FSM
     transition `--next` uses. Create-time ready preparation skips its own promotion when the task
     is already `todo`, and next-router stops routing the task back to refine. Without `--next`,
     refine does not chain into run.
  4. Report the checklist as rows `{id, pass, evidence}`, one per id, in the markdown result and in
     the `--json` object, alongside the corrections count and status before → after.

  A decision refine cannot close under `--auto` makes the outcome `failed`. Report the concrete
  question, and leave the task at `backlog`.

  Ready depth is the canonical path for three jobs: the ready competency behind `spur task create`
  (its recovery command), evaluating and correcting an existing task, and freezing multi-package or
  multi-agent handoffs. It is not for every small task. Default remains `standard`.

- **SKIP short-circuits synthesis, not `--next`.** A SKIP means no synthesis was needed — it does **not** cancel the `--next` chain. Under `--auto --next`, a SKIP still flows into the (idempotent) status transition and the chained `/sp:dev-run --mode implement`. "`refine --auto --next` on a well-specified task" is therefore effectively "run the implement→verify chain"; an operator who wanted refinement only should drop `--next`.
- **Delegation:** `Skill(skill="sp:spur-dev", args="refine $ARGUMENTS")`

### 5a. refineall

- **Purpose:** Batch-refine a set of tasks (or all refine-eligible tasks under a feature) — resolve a set, topo-sort by dependencies, run per-task `refine`, emit a summary report. Planning-half counterpart of `verifyall` / `runall` for the just-in-time spec-completion gate. With `--depth ready`, batch **implement-ready** freeze before multi-agent implement or runall.
- **Inputs:**
  - `--feature <id>` **or** `--tasks <selector>` (required — at least one). `--feature` is sugar for `--tasks feature:<id>` (shared selector grammar: explicit WBS list, `feature:<id>`, `ready`, status pseudo-list — [execution-batch.md](execution-batch.md) Step 1). If both are present, `--tasks` wins (one-line note in the report).
  - Shared refine flags (passed through to each per-task refine): `--focus <mode>`, `--description <text>`, `--depth <standard|ready>`, `--agent <inline|auto|name>`, `--auto`.
  - Batch-only flags: `--keep-going` (continue independents after a failure; default halt), `--status <s>` (filter resolved membership; default **`backlog` + `todo`** — planning-side fill candidates. The filter is applied in-agent against the frozen set; `spur task list --status` takes exactly one canonical status per call (see `execution-batch.md` Step 1).), `--json` (machine-readable batch report).
- **Backing:** `sp:spur-dev` skill, `refineall` operation (orchestrates; per-task body is the single-task `refine` operation — never a second refine implementation).
- **Behavior:**
  1. Resolve + **freeze** the set at kickoff (never re-query membership mid-batch).
  2. Apply `--status` filter (default `backlog` + `todo`; applied in-agent against the frozen set; `spur task list --status` takes exactly one canonical status per call — see `execution-batch.md` Step 1). Tasks already `done`/`cancelled`/`testing` are excluded unless the operator widens `--status`. Report each exclusion with reason.
  3. Topo-sort by `dependencies[]` (Kahn, WBS-ascending tie-break). Cycle → abort entire batch before any refine. Out-of-set deps: `done` → allow; else → block subtree (same as runall).
  4. For each WBS in order: invoke single-task refine with shared flags **including `--depth`**. Under `--auto` + **`--depth standard`** (default), the per-task **L3 pre-synthesis SKIP gate** still applies. Under **`--depth ready`**, each task runs the implement-ready checklist (no L3-only SKIP). That includes the premises audit, the correction record and ready finalization, so a passing task leaves at `todo`.
  5. Failure policy: **stop-the-batch** (default) or `--keep-going` (skip in-batch dependents of a failed refine; continue independents).
  6. Emit a batch report (markdown or `--json`) that records `depth` once at the header. Under `--depth ready`, each row also carries the corrections count, status before → after, and failed checklist ids.
- **Per-task outcome vocabulary:** `refined` (synthesis wrote sections) | `SKIP` (already meets the active depth bar under `--auto`) | `failed` | `skipped` (dep failed under `--keep-going`) | `not-attempted` (halted) | `blocked` (unmet out-of-set dep).
- **Batch verdict:** `clean` (all attempted tasks `refined` or `SKIP`) | `halted` (a failure stopped the batch) | `aborted` (cycle / unknown selector / empty set after filter).
- **`--next` is not accepted** (dropped by feature H8, 2026-07-31 — see `plugins/sp/commands/dev-refineall.md` for the removal record). Chain execution explicitly: refineall, then `/sp:dev-runall --feature <id>`.
- **`--auto` recommendation:** Batch refine without `--auto` requires per-task interactive Q&A and does not scale. Default operator path: `/sp:dev-refineall --feature <id> --auto`. For implement handoffs, or to re-audit a feature's filed tasks: `/sp:dev-refineall --feature <id> --auto --depth ready`.
- **Delegation:** `Skill(skill="sp:spur-dev", args="refineall $ARGUMENTS")` → per task `Skill(skill="sp:spur-dev", args="refine <wbs> $SHARED_FLAGS")` (shared flags include `--depth` when set).

### 6. plan

- **Purpose:** Plan a feature from a description — intake → feature create → AC generation → feature check gate → decomposition → batch-create (with **Design by default**).
- **Inputs:** `"<description>"` (required). `--feature <id>` links to an existing feature. `--parent <feature-id>` nests under a parent. Omitted/`inline` drives `idea-pipeline.yaml` in the host session; `auto` or a name launches the async workflow worker. **Design package flags (unified with `/sp:dev-idea`):**
  - **Default:** author task `design` on every batch item + feature satellite when the seam heuristic fires (**ties lean design**). There is **no** `--design` force flag.
  - `--skip-design` — skip feature satellite **and** omit task `design` fields (scaffold only; refine fills later). Sole design opt-out.
  - `--auto` — accept the recommendation at every operator gate, taste gates included (same contract as § 16 idea).
- **Backing:** `sp:spur-dev` skill, `plan` operation. Stage floor: the `planner` role per [`roles.md`](../../../references/roles.md) — this file names roles, never tiers (0538 R4).
- **Behavior:** Clarify scope → `spur feature create` → author BDD AC → `spur feature check` gate → decompose into task-batch JSON **including `design` (unless `--skip-design`)** → `spur task batch-create` gate. Design package details: [planning-workflow.md](planning-workflow.md) Step 5.5.
- **Delegation:** `Skill(skill="sp:spur-dev", args="plan $ARGUMENTS")`

### 7. docs

- **Purpose:** Evolve project documentation — update ADR, PRD, ARCHITECTURE, DESIGN, FEATURES docs per the constitution's edit rules.
- **Inputs:** `"<change description>"` (required).
- **Backing:** `sp:doc-evolve` skill — no thin `dev-docs` command wrapper exists (the skill is invoked directly or via the operator).
- **Behavior:** Read the affected doc → apply the constitution's edit rules (single-source-of-truth, cross-reference updates, same-commit sync triggers) → write via the correct tool.
- **Delegation:** `Skill(skill="sp:doc-evolve", args="$ARGUMENTS")` (no thin command wrapper)

### 11a. job-dump

- **Purpose:** Transfer any unfinished job to another session, agent, or operator through a Markdown snapshot; a blocker or task/feature ID is optional.
- **Inputs:** Required `--file <path>`; shared path semantics live in [flag-glossary.md](flag-glossary.md).
- **Backing:** `sp:spur-dev`, in the current session. Use the [shared handoff template](#job-handoff-template).
- **Behavior:**
  1. Parse arguments, preserving quoted paths with spaces. Reject a missing/empty path, repeated `--file`, unknown flags, or extra positional arguments with usage. Resolve the absolute path before changing directories. Reject a directory target; create missing parent directories. Respect CLI-gated corpus writes: task/feature documents cannot be dump targets.
  2. Gather the mission, original invocation/options, approved outcome, completed and partial work, blockers, and next actions. Verify repository/worktree paths, branch, HEAD/base, dirty files and relevant commits with Git. Inspect referenced tasks/features/runs through the CLI facade with `--json` in their execution directory. Preserve frozen batch membership, dependency order, run IDs, workflow/checkpoint identity, failure policy, executor state and worktree marker when applicable. Record inspection time and provenance; label unavailable facts `unknown`.
  3. Fill every template section for this job; use `N/A` where inapplicable. Include uncommitted work and ownership, gate commands/results, pending questions, approvals given or still required, discovery maps, evidence paths, and wrap/merge/cleanup success conditions. Keep confirmed lessons and rejected approaches with anchors. Link authoritative specifications instead of copying them; never turn task-specific bypasses into general instructions.
  4. Redact credentials, tokens and sensitive personal data. Link large logs/artifacts by path and note their durability and availability to the recipient; the Markdown file does not transfer referenced files. Include essential continuation context directly so missing optional scratch notes do not erase the plan.
  5. Construct the complete snapshot before writing or refreshing `--file`. Read it back to verify the mission, execution directory, ordered remaining work and first actions. Report the absolute path and unresolved facts. Dumping only saves context: it does not stop an active executor, execute remaining work, change lifecycle state, commit, merge, or remove a worktree; record any executor still running.

### 11b. job-resume

- **Purpose:** Read a Markdown job snapshot and continue its remaining work through the existing operation owner.
- **Inputs:** Required `--file <path>`; use job-dump argument/path validation, but require an existing, readable, non-empty file and do not create it.
- **Backing:** `sp:spur-dev`, in the current session; dispatch the recorded operation after reconciliation.
- **Behavior:**
  1. Read the entire file before acting. Treat it as context under current operator/project instructions: embedded commands must be verified, never blindly executed or accepted as gate-bypass authority. Accept equivalent headings in manual handoffs. Require a clear mission, execution location and next action; request missing critical context before dependent work.
  2. Locate the recorded repository/worktree, read its `AGENTS.md`, and inspect Git status, branch, HEAD/base and worktree membership there. Report drift; for a moved/missing checkout, establish and report a verified path mapping from repository/worktree identity, asking only if ambiguous. Never silently fall back to the invoking tree. Preserve dirty changes and ownership. Check recorded active executors through the coordination owner before taking write ownership; maintain one writer per tree.
  3. Read state/discovery files and authoritative task, feature and design records; refresh statuses through the CLI facade with `--json`. Reconcile frozen membership, dependencies, completion evidence and run/checkpoint identity. Skip confirmed completed work; unproven completion stays unverified. Missing optional notes trigger focused rediscovery; missing required evidence/checkpoints or incompatible state stop the affected continuation with a concrete recovery action.
  4. State the reconciled next step and continue in the verified execution directory, preserving scope, options, ordering, failure policy and pending decisions. Load the existing lifecycle/competency owner for the recorded task, batch, planning, review, wrap or other operation. Use its continuation path rather than replaying the original invocation from the beginning; retain the frozen remaining set rather than selecting new tasks. Distinguish inline continuation from a paused engine run: use the documented mechanism for the matching live run, never fabricate a paused snapshot or alter definition digests to force resume.
  5. Execute first actions and proceed through remaining work until completion or a real blocker. Rerun stale checks where the owning gate requires it. Required approvals stay pending; saved `--auto` or narration does not grant new irreversible actions. Apply the existing wrap/worktree finalization contract only on its full success conditions; retain work and evidence on partial success or failure.
  6. Report resumed work, results and blockers. When stopping again, refresh the same file through job-dump, preserving the original mission, membership and references while updating observed state and next actions.

#### Job handoff template

Fill this structure for the actual job. Replace placeholders; omit another job's IDs, paths,
commits, implementation details, quotas, parser workarounds and lifecycle bypasses.

```markdown
# Resume job: <short mission>

## Mission
<Goal, expected outcome, original invocation/options and approved scope.>

## Environment (verified <timestamp and timezone>)
- Execution directory / repository / invoking directory: <absolute paths and their roles>
- Branch / base / HEAD / working-tree changes: <observed state and ownership>
- Runtime / CLI / executor: <verified invocation and availability>
- Run / workflow / checkpoint / worktree marker: <identity and state, or N/A>
- State, discovery maps and evidence: <paths, retention and availability>

## Completed so far
<Completed items, commits and verification receipts; separate partial/uncommitted work.>

## Remaining work, in order
1. <Next item, dependency, current stage, authoritative specification and required gate.>
2. <Subsequent items, then wrap/finalization and its success conditions.>

## Execution mode
<Inline/delegated mode, one-writer ownership, frozen membership/order, failure policy,
gate commands, pending questions and approval requirements.>

## Lessons and rejected approaches
<Verified pitfalls, discoveries and approaches ruled out, with evidence.>

## Constraints and authoritative references
<Frozen decisions, boundaries, required reading and evidence paths; link specifications.>

## First actions for the new session
1. <Verify the execution directory and current repository/run state.>
2. <Read state/discovery files and relevant authoritative records.>
3. <Resume the next unfinished step through its existing owner.>
```

### 12. brainstorm

- **Purpose:** Interactive solution design — heuristic discovery interview (grilling) followed by structured ideation with trade-offs and confidence scoring.
- **Inputs:** `"<topic>"` (required). `--depth <basic|detailed|comprehensive>` controls how deep to walk the decision tree. `--options <n>` sets the number of solution approaches (default 3). Model steps execute inline (in-session) by default; `--agent <inline|auto|name>` selector accepted (see [SSOT](cross-cutting.md#inline-default-execution-surface)). `--skip-discovery` skips the grilling interview and goes straight to ideation. `--task [<feature-id>]` and `--feature [<parent-id>]` are the two **artifact exits** (mutually exclusive — see below). `--next` chains the `--feature` exit into `/sp:dev-plan` decomposition.
- **Backing:** `sp:brainstorm` skill, `dev-brainstorm` operation.
- **Behavior:** Two-phase protocol. Phase 1 (inline): walk the decision tree one question at a time, each with a recommended answer, exploring the codebase before asking the user. Phase 2 (delegated): pass the resolved decision tree to `sp:brainstorm` for structured ideation — each approach includes description, trade-offs, implementation notes, confidence level, and decision trace.
- **Artifact exits (mutually exclusive):**
  - `--task [<feature-id>]` — create one `todo` task from the ⭐ approach via `spur task create` (Background/Requirements/Plan seeded from the brainstorm). The fast path for a single unit of work.
  - `--feature [<parent-id>]` — the **front-half entry**: `spur feature create`, then author Goal/Scope/BDD-AC by editing the feature file (no `--section` verb on `feature update`), then loop `spur feature check` to exit 0. Lands a validated feature; hands off to `/sp:dev-plan --feature <ID>` for decomposition. AC scenarios derive from the decision trace per [ac-style-guide.md](ac-style-guide.md#decision-trace--ac-scenario-mapping).
  - `--next` (with `--feature`) — on a clean `feature check`, auto-invoke `/sp:dev-plan --feature <ID>` so the planning half chains end-to-end like the execution half. Ignored without `--feature`.
  - Passing both `--task` and `--feature` is an error.
- **`--task` exit seeding:** create via `spur task create "<approach-name>" --feature <id> --template feature-impl` (omit `--feature` when no feature-id is given). The task is seeded with:
  - **Background** ← the brainstorm Overview + the chosen approach's Description + decision-trace context
  - **Requirements** ← the approach's Implementation Notes, converted to R-item checkboxes
  - **Plan** ← the brainstorm's Next Steps, converted to an ordered checklist

  Report the new task WBS and file path; the task lands at `todo`, ready for `/sp:dev-refine`.

- **Delegation:** `Skill(skill="sp:brainstorm", args="dev-brainstorm --context <decision-tree> --options <n>")`

### 13. runall

- **Purpose:** Run a batch of tasks through their pipelines in dependency-correct order — resolve a set, topo-sort, run each via `task-pipeline.yaml`, inspect verdicts, apply the failure policy, emit a batch report.
- **Inputs:** `--tasks <selector>` (required — explicit WBS list, status pseudo-list, `feature:<id>`, or `ready`). `--mode <sequential|parallel>` (default `sequential`; `parallel` fans out a proven-independent subset per `execution-batch.md` § Parallel Execution). `--keep-going` skips a failed task's in-batch dependents and continues independents (default halts on first failure). `--auto` sets `profile=auto` on each per-task run (skips the HITL approve gate). `--feature <id>` is sugar for `--tasks feature:<id>`; when the effective selector is feature-derived, the batch runs `spur feature check <id> --strict --json` **once** before task resolution — a non-zero strict check aborts with verdict `aborted`, zero attempted tasks, and the structured findings (task 0510 R2); scoped: `L4.scenario-unverified` (expected pre-run state of any not-yet-run feature) is reported verbatim but does not abort — any other strict error aborts. Explicit WBS/status/`ready` selectors add no feature check. The orchestrator loop itself continues in this session; interactive sequential omit/`inline` uses the host driver — host-controlled with eligible `agent.run` stages dispatching once to a native subagent and host fallback (task 0508) — while `--agent auto`/a name, parallel mode, and headless invocation keep the isolated per-task workflow subprocess boundary. `--agent <inline|auto|name>` pins the executor for the per-task stages (see [SSOT](cross-cutting.md#inline-default-execution-surface)); the value crosses into per-task `vars.agent`, not the orchestrator. `--json` emits the report as JSON. `--wrap` triggers `wrapup-pipeline.yaml` **once for the batch** over the `done` subset only (execution-batch.md Step 6: `vars.feature` only when every frozen task is `done`/`cancelled`; empty done subset skips with a reason), `--next` chains each task to terminal status then runs the same batch-once wrap, `--continue` resumes from checkpoint. `--no-summary` skips the [execution summary](#execution-summary) printed after the batch report (one row per attempted run).
- **Three orthogonal axes (do not confuse):** `--keep-going` = batch failure policy (halt vs skip dependents); `--continue` = resume from checkpoint against the batch's original frozen identity (execution-batch.md § Batch continuation, task 0919); `--next` = per-task lifecycle chaining (advance status on a verdict — `dev-verify`/`dev-verifyall` only). `routing-table.md` offers `--continue` and `--next` as competing options for the same situation only when the batch was interrupted mid-run; otherwise they address different problems.
- **Backing:** `sp:spur-dev` skill, `runall` operation → delegates the driver loop to the **`sp:super-planner`** agent (the batch orchestrator).
- **Behavior:** The orchestrator reads [execution-batch.md](execution-batch.md) and drives: resolve selector → freeze set → topo-sort by `dependencies[]` (Kahn, WBS-ascending tie-break; cycle aborts) → resolve out-of-set deps by status (done → allow, else → block subtree) → run each task via `spur workflow run task-pipeline.yaml --async` + `spur workflow trace` polling → inspect terminal state + `.spur/run/<wbs>-verdict.json` → stop-the-batch default or `--keep-going` subtree skip → emit batch report. Per-task pipeline is invoked **verbatim** — no new FSM, no step edits. `--auto`/`--agent` are the only flags that cross the orchestrator→pipeline boundary (both into per-task `--vars`).
- **Delegation:** `Skill(skill="sp:spur-dev", args="runall $ARGUMENTS")` → `sp:super-planner` agent.

### 14. wrap

- **Purpose:** Wrap up a single completed task — capture learnings, record metrics, sync docs, and optionally advance the feature / clean up the branch.
- **Inputs:** `<wbs>` (required, positional). `--agent <inline|auto|name>` names the wrap's model-bearing executor (default: `inline`, resolving identically when omitted; task 0687); wrap is workflow-backed (headless), so omit ≡ explicit `inline` (task 0687): tier substitution under objective trigger 3 (durable auditable run record required) plus one warning naming the substituted executor. `auto` tier-resolves an executor, and a name pins that executor into `vars.agent` (see [SSOT](cross-cutting.md#inline-default-execution-surface)). `--auto` skips objective confirmations (the branch-cleanup HITL gate still pauses — irreversible). `--merge` triggers branch cleanup (irreversible HITL gate).
- **Backing:** `spur workflow run wrapup-pipeline.yaml` — direct workflow invocation (no backing skill; the pipeline IS the procedure).
- **Behavior:** Resolves the executor (`agent.default` for omit/`inline`, tier-resolved for `auto`, unchanged for a name), emits a pre-dispatch notice naming the subprocess override — `execution surface: subprocess`, `reason: trigger 3 — durable auditable run record required`, `requested agent: <selector>`, `executor: <resolved>` — then builds `--vars '{"tasks":"[\"<wbs>\"]","agent":"<resolved>","profile":"interactive|auto","merge":"true|false"}'` and invokes the wrapup pipeline. The pipeline runs: task-resolve → doc-sync → learnings-validate → learnings-append → doc-tripwire → metrics-record → (feature-transition) → (branch-cleanup) → done. `doc-tripwire` (1037) runs the TRUSTED CONFIG ONLY `docTripwireCmd` over the still-uncommitted wrap diff after the doc-sync exits converge — the default runs `bun run test-repo-wide` only when `package.json` declares the script (a no-op in other projects); override it via `--vars`, and an empty string disables the check while still recording PASS; a FAIL fails the wrap with already-written learnings/docs preserved. Task statuses are NOT mutated. Branch cleanup is an irreversible HITL gate that always pauses, even under `--auto`.
- **Vars string typing:** `tasks` is a JSON-encoded **string**, not a JSON array — `spur workflow run --vars` accepts only string values (`--vars values must be strings`); the pipeline's guards parse the string with `jq length`. `jq -nc` guarantees the shape:

  ```bash
  VARS=$(jq -nc --arg tasks "[\"$WBS\"]" --arg agent "$AGENT" --arg profile "$PROFILE" --arg merge "$MERGE" \
    '{tasks:$tasks, agent:$agent, profile:$profile, merge:$merge}')
  spur workflow run wrapup-pipeline.yaml --vars "$VARS"
  ```

- **Delegation:** Direct `spur workflow run wrapup-pipeline.yaml` (no `Skill()` call — the command builds the vars JSON and invokes the workflow directly via `Bash`).

### 15. wrapall

- **Purpose:** Wrap up a batch of completed tasks — capture learnings, record metrics, sync docs, advance a feature through legal lifecycle edges, and optionally clean up branches.
- **Inputs:** `--since <iso-date>` filters done tasks by frontmatter `updated_at >= date` (v1 approximation). `--feature <id>` selects all tasks under a feature AND advances the feature through legal lifecycle edges (`backlog → active → verifying → done`, guards honored). `--status <s>` (default: `done`) filters by task status. `--agent <inline|auto|name>` names the wrap's model-bearing executor (default: `inline`, resolving identically when omitted; task 0687); wrap is workflow-backed (headless), so omit ≡ explicit `inline` (task 0687): tier substitution under objective trigger 3 (durable auditable run record required) plus one warning naming the substituted executor. `auto` tier-resolves an executor, and a name pins that executor into `vars.agent` (see [SSOT](cross-cutting.md#inline-default-execution-surface)). `--auto` skips objective confirmations. `--merge` triggers branch cleanup (irreversible HITL gate).
- **Backing:** `spur workflow run wrapup-pipeline.yaml` — direct workflow invocation.
- **Behavior:** Resolves the task list via `spur task list --json` (filtered by `--feature`, `--since`, `--status`), resolves the executor (omission and explicit `--agent inline` tier-substitute identically with a warning per task 0687, `auto` tier-resolves, a name pins), emits a pre-dispatch notice naming the subprocess override — `execution surface: subprocess`, `reason: trigger 3 — durable auditable run record required`, `requested agent: <selector>`, `executor: <resolved>` — then builds `--vars '{"tasks":"[...]","feature":"<id>","agent":"<resolved>","profile":"interactive|auto","merge":"true|false"}'` and invokes the wrapup pipeline. The pipeline runs the same states as `wrap` — including the `doc-tripwire` hop (1037), whose TRUSTED CONFIG ONLY `docTripwireCmd` runs the repo-wide tripwires over the still-uncommitted wrap diff and can be overridden or disabled (empty string) via `--vars` — but with the full task list and optional feature transition. Task statuses are NOT mutated. Feature transitions go through `spur feature update` so lifecycle guards apply. Branch cleanup is an irreversible HITL gate.
- **Vars string typing:** `tasks` is a JSON-encoded **string**, not a JSON array — `--vars` values must be strings (the CLI rejects raw arrays); `jq -nc` passes the array text through as a string value:

  ```bash
  VARS=$(jq -nc --arg tasks "$TASKS" --arg feature "$FEATURE" --arg agent "$AGENT" --arg profile "$PROFILE" --arg merge "$MERGE" \
    '{tasks:$tasks, feature:$feature, agent:$agent, profile:$profile, merge:$merge}')
  spur workflow run wrapup-pipeline.yaml --vars "$VARS"
  ```

- **Delegation:** Direct `spur workflow run wrapup-pipeline.yaml` (no `Skill()` call — the command resolves tasks and invokes the workflow directly via `Bash`).

### 16. idea

- **Purpose:** Turn a vague idea into a feature with AC and a decomposed task batch — the unified entry point for the planning half.
- **Inputs:** `"<idea>"` (quoted) or `--from-file <path>` — exactly one; the two are mutually
  exclusive (0887 R7). Two everyday axes:
  - `--auto` — accept the recommendation at **every** operator gate (objective and taste):
    sets `profile=auto`, `idea_approved=true`, `design_approved=true`. idea-eval follows the
    report's `## Recommendation` (`proceed`/`reshape` continue, `drop` cancels, missing still
    asks); design-approval approves only on a PASS design check (FAIL still asks).
  - `--skip-design` — design package off (system-design + task Design). There is **no** `--design` force flag.
  - Removed: `--approve-taste`, `--idea-approved`, `--design-approved` (folded into `--auto`;
    ignored with a one-line notice if passed).
  - `--from-file <path>` — read the idea text from a file instead of the positional argument
    (verbatim; long/multiline asks). Mutually exclusive with `"<idea>"`.
- **Verbatim idea artifact:** before `start` executes, the driver persists the idea argument (or
  `--from-file` contents) unmodified to `.spur/run/<run-id>-idea-input.md` (0887 R1); the precheck
  fails the run when that file is empty or missing, and every model-bearing stage prompt treats
  it as the authoritative ask (R2).
- **Backing:** `idea-pipeline.yaml` through the inline driver for omitted/`inline`, or `spur workflow run idea-pipeline.yaml --async` for `auto`/name.
- **Behavior:** Builds vars from the table above and drives the idea pipeline. Flow: discovery → **idea-eval** (taste; reject → cancelled) → feature-create → ac-generate → feature-check → system-design (conditional) → design-approval (taste) → decompose → batch-create (`--skip-ready`) → ready-prepare (ready checklist per created task + ready-evidence sidecar, 0788) → handoff. STOPS at handoff — no task execution, no pipeline nesting. Headless runs use one `trace --follow`; cancellation is reported stopped only when `workflow cancel --json` returns `killed: true`.
- **Delegation:** Host-session inline driver by default; explicit executor selection uses the async workflow worker.
- **Idea-evaluation gate:** After discovery, operator reviews `.spur/run/idea-eval-report.md` ([idea-evaluation.md](idea-evaluation.md)). Approve continues; reject/cancel → no feature. Under `--auto`, follows the report's recommendation (`drop` → cancelled; missing recommendation → pauses). Enhanced idea is a sidecar — `vars.idea` is not overwritten.
- **Design package (`--skip-design` only):**

  | Flags           | Feature satellite (`system-design`) | Task `### Design` in batch                |
  | --------------- | ----------------------------------- | ----------------------------------------- |
  | (default)       | seam / `needs_design` signal        | **author `design` on each batch item**    |
  | `--skip-design` | skip (keep brainstorm summary)      | **omit `design`** — refine fallback later |

  Ties lean design — when the signal is ambiguous, `system-design` runs. Task Design defaults on
  unless `--skip-design`. Plan path uses the same package contract (no `--design` force flag).

- **Operator gates:** every pause is one `AskUserQuestion` [decision brief](decision-brief.md) — recommended option first; see the gate table in `commands/dev-idea.md` and the `hitl.confirm` rule in [inline-pipeline-driver.md](inline-pipeline-driver.md).

### 17. refactor

- **Purpose:** Lens-routed refactoring with a preservation contract — route a scope through taste lenses (api / architect / tests / ui, auto-detected by path), classify findings on the shared `refactor-finding` schema, and apply via the fix ladder without breaking preserved behavior.
- **Inputs:** `[<description>]` free-text steering, `--scope <path>` (default: working tree), `--focus <lens>` (default: auto), `--fix <policy>` (default: none), `--check <cmd>` (default: project gate), `--agent <selector>` (default: inline), `--auto` (default: off).
- **Backing:** `sp:code-refactoring` skill — the command carries zero orchestration logic (ADR-032); the skill owns focus auto-detection, lens dispatch, the P1–P4 severity map, objective/taste gates, and the fix ladder with revert-on-regression.
- **Behavior:** Green `--check` baseline → focus detection → lens dispatch → findings to `.spur/run/<run-id>-refactor-findings.json` + human report `.spur/run/<run-id>-refactor-report.md` (lens set, P1–P4 table, preservation summary, applied/reverted/deferred). `--fix blockers-first` auto-applies P1/P2 `auto`-eligible findings; `--fix all` extends to `operator`-eligible P3/P4; every fix re-runs `--check` and reverts on regression. Tests are never removed or weakened by an `auto` fix.
- **Operator taste gates:** every `cutting` or `breaking` finding pauses for an explicit operator answer in every mode — even `--auto` skips only objective gates. `--fix none` (the default) writes both artifacts with no edits.

---

## Inline operations

These define their procedure directly in the command file. No `Skill()` delegation — the command
is the procedure. The backing is a combination of git CLI, `spur` CLI, and agent reasoning.

### 8. changelog

- **Purpose:** Generate a structured changelog from git commits between two refs.
- **Inputs:** `<file>` (optional positional, e.g. `CHANGELOG.md`; default: stdout), `--since <ref>` (default: last tag), `--until <ref>` (default: `HEAD`), `--version <ver>` (default: auto-detect from latest tag).
- **Backing:** `inline` — git log + conventional-commit grouping.
- **Behavior:**
  1. Resolve `--since`: if not given, use the most recent tag (`git describe --tags --abbrev=0`). If no tags exist, use the repo root commit.
  2. Run `git log --oneline <since>..<until>`.
  3. Parse each commit's conventional-commit prefix (`feat`, `fix`, `refactor`, `docs`, `chore`, `perf`, `test`, `style`, `ci`, `build`). Commits without a recognized prefix go under `Other`.
  4. Group commits by type. Within each group, list one bullet per commit: `- <summary> (<short-hash>)`.
  5. Format as markdown:
     - `keepachangelog` (default): `## [<version>] - <date>` header, then category headings per the keepachangelog convention — `### Added` / `### Fixed` / `### Changed` / `### Removed` / `### Other` — mapped from conventional-commit types.
     - `simple`: flat bulleted list grouped by type heading (`### feat`, `### fix`, …).
  6. Emit: with `<file>`, insert the section into that file above its newest `## [` release heading (or after its title when none exists) and touch nothing else in the file; without `<file>`, print it to stdout.
  7. Self-check before emitting: every short hash in `<since>..<until>` appears exactly once. Fix any miss or duplicate; do not report a verdict.
  8. Reply in at most three lines: the range, bullet counts per category, and the output target.
- **Invariants:** Output is derived from `git log` only. No quality gates — no lint/test/`spur-check`/rule runs, citation or manifest lookups, confidence ratings, or edits beyond the one inserted section. The file is left uncommitted.

### 9. gitmsg

- **Purpose:** Generate conventional commit message(s) for the current change set — one gather call → concern grouping → one message per concern; optionally commit. Git + POSIX shell only; no helper script.
- **Inputs:** `--scope <path>` (default: the whole change set) — path filter; an explicit `--scope` always wins over change-set auto-discovery. `--all` (default: off) — widen the change set past the index to every change in the tree: unstaged **and untracked** files. Omitted, the change set is the index only, which keeps pre-commit semantics stable. `--commit` (default: off) — commit the change set, one commit per concern. `--squash` (default: off) — collapse every concern into one message and one commit; implies `--commit`.
- **Backing:** `inline` — one bounded gather call + concern grouping + conventional commit formatting.
- **Behavior:**

  1. **Gather — exactly one Bash call.** Set the three variables from the flags and run the block
     verbatim. It resolves the change set, applies the empty-index rule, and prints everything the
     message needs; the guards run in shell, not in the model:

     ```bash
     bash <<'EOF'
     ALL=0 COMMIT=0 SCOPE=':/'   # --all → ALL=1 · --commit/--squash → COMMIT=1 · --scope <p> → SCOPE=<p>
     EX=(':!*.lock' ':!*lock.json' ':!*.lockb')
     untracked() { git ls-files -o --exclude-standard -- "$SCOPE" "${EX[@]}"; }
     if [ "$ALL" = 0 ] && git diff --cached --quiet -- "$SCOPE"; then
       t=$(git diff --name-only HEAD -- "$SCOPE" | wc -l | tr -d ' '); u=$(untracked | wc -l | tr -d ' ')
       [ "$COMMIT" = 1 ] && { echo "STOP index empty ($t tracked, $u untracked changed) — re-run with --all"; exit; }
       echo "NOTE index empty — reading the whole tree instead"; ALL=1
     fi
     [ "$ALL" = 1 ] && R=HEAD || R=--cached
     stream() {
       git diff $R -U0 --diff-filter=d -- "$SCOPE" "${EX[@]}"
       [ "$ALL" = 1 ] && untracked | while IFS= read -r f; do git diff --no-index -U0 -- /dev/null "$f"; done
     }
     [ -z "$(stream | head -c1)" ] && { echo "STOP no changes in $SCOPE"; exit; }
     echo "## context"; git rev-parse --abbrev-ref HEAD --git-dir --git-common-dir --show-superproject-working-tree
     echo "## recent subjects"; git log -12 --format=%s
     echo "## stat"; git diff $R --stat=100 --compact-summary -- "$SCOPE"
     [ "$ALL" = 1 ] && untracked | sed 's/^/ (untracked) /'
     [ "$ALL" = 0 ] && { echo "## partially staged"; comm -12 <(git diff --cached --name-only | sort) <(git diff --name-only | sort); }
     echo "## secret hits"
     stream | awk '/^\+\+\+ /{f=substr($0,7)} /^\+[^+]/{print f": "$0}' \
       | grep -E '(password|passwd|secret|api[_-]?key|access[_-]?token|auth[_-]?token)["'"'"']?[[:space:]]*[:=][[:space:]]*["'"'"'][^"'"'"'[:space:]]{12,}|BEGIN [A-Z ]*PRIVATE KEY|(ghp_[A-Za-z0-9]{36}|github_pat_[A-Za-z0-9_]{40,}|sk-[A-Za-z0-9_-]{20,}|AKIA[0-9A-Z]{16})' | head -5
     echo "## diff (-U0, ≤80 lines/file, ≤40 KB)"
     stream | awk '/^diff --git/{n=0} n++<80' | head -c 40000
     EOF
     ```

     What the block guarantees:
     - **Untracked files are read, not just named** — under `--all` each one is diffed against `/dev/null`, so a new file (often the main change) shapes the message.
     - **Every file gets a share** — the per-file 80-line cap runs before the 40 KB total cap, so one large file cannot starve the rest. Deleted files contribute only their `(gone)` stat line; lockfiles are excluded.
     - **Empty index, no `--all`:** a message-only run widens to the whole tree and says so (`NOTE`); a committing run prints `STOP` with the counts — re-print the exact re-run line (`/sp:dev-gitmsg <same flags> --all`) and stop. Committing untracked files is never inferred.
     - **`STOP no changes`** → report it and stop.

  2. **Stay inside the budget.** The block's output is the whole input. Never run a second, wider `git diff`, `git show`, or file `Read` to "see more"; never paste hunks into the output. A truncated file is typed from its stat line and path.

  3. **Group by concern.** A concern is one coherent change a reviewer would accept or revert as a unit:
     - Tests, docs, and registry/index updates travel **with the code they cover** — not as separate `test`/`docs` groups. A standalone `test`/`docs` group exists only when nothing else in the change set motivates it.
     - Behavior changes and pure formatting/refactor churn are **different** concerns.
     - Prefer fewer groups; a single group is the common case. Order groups by dependency (refactor before the feature that uses it).

  4. **Write each message.**
     - **Type** from the dominant change: `feat` · `fix` · `refactor` · `perf` · `docs` · `test` · `style` · `build` (deps, bundling) · `ci` (workflows, pipelines) · `chore` (other tooling/config) · `revert`.
     - **Scope** — reuse a scope that appears in `## recent subjects` for the same area (the repo's own vocabulary beats a guessed one); `--scope <path>` overrides. Omit the scope rather than invent one.
     - **Summary** — imperative, ≤72 chars, lowercase first word, no period; says what changed in user/maintainer terms, not which files.
     - **Body** — only when the *why* is not obvious from the summary: intent and consequence in 1–3 lines, never a restated diff or file list. `--squash` → one combined message (dominant type/scope, one body bullet per concern).

  5. **Report.** Print: one context line (branch; `linked worktree` when `--git-dir` ≠ `--git-common-dir` and the superproject line is empty), then each message in a fenced block. No per-file summaries, no restated diff. With neither `--commit` nor `--squash`, add one copy-paste `git commit` line per message and stop.

  6. **Commit (`--commit` / `--squash`) — one more Bash call.** `--squash` implies `--commit`, so both together is just `--squash`. Refuse before touching the index when:
     - `## secret hits` is non-empty → print each `file: line`, commit nothing;
     - `--commit` would split (more than one group) and `## partially staged` is non-empty → splitting would widen those `git add -p` stagings to whole files; print the paths and commit nothing (`--squash` is allowed — it commits the index as staged).

     Otherwise run the commits in one heredoc — `--all` first stages the scope (`git add -A -- "$SCOPE"`); a single group or `--squash` is one `git commit -F -`; multiple groups commit in dependency order:

     ```bash
     bash <<'EOF'
     git reset -q -- :/ && git add -A -- <group-1 paths> && git commit -q -F - <<'MSG'
     <group-1 message>
     MSG
     # …repeat per group…
     git log --oneline -<n>; git status --short
     EOF
     ```

     Hooks stay enabled; a failing hook stops the run with its output — never `--no-verify`.

- **Invariants:** Git and POSIX shell only — no helper script, no temp file. At most two Bash calls: gather, then (only when committing) commit. With neither `--commit` nor `--squash`, never runs `git commit` — message only. Neither flag commits across a secret hit, and `--commit` never splits across a partial staging. Without `--all` the change set is the index, so plain `/sp:dev-gitmsg` keeps pre-commit semantics; only `--all` reaches unstaged and untracked files, and only a committing run stages them. The empty-index widen is read-only and always announced — a committing run never widens its own scope. An explicit `--scope <path>` always bounds the change set, with or without `--all`. One bounded, context-free capture per run — never a second, wider read.

### 10. fixall

- **Purpose:** Fix all lint, type, and test errors systematically across the working tree.
- **Inputs:** `--scope <path>` (default: entire working tree) — limits fixes to a file or directory. `--gate-log <path>` (R3, task 0482) — before fixing, read this captured validation-run log and start at the `file:line` anchors its findings name, rather than re-deriving the failure from a fresh gate run. `--findings <anchors>` (R3, task 0482) — space-separated `file:line` anchors already extracted from that log by the `test` hop; when present these ARE the failing set, so fix them in order and do not run the gate to discover what broke.
- **Backing:** `inline` — lint + test fix loop.
- **Behavior:** 0. **Start at the anchors, never at a discovery run.** If `--findings <anchors>` is given, that space-separated `file:line` list IS the failing set — open those locations first, in order, and fix them; do not run the gate to find out what broke. If only `--gate-log <path>` is given, read that log first and identify the failing findings (lint/test errors with their `file:line` anchors) before running the loop — the captured log is the authoritative source. Either way the first action of this hop is a read, not a gate run (R3, task 0482).
  1. Inspect the project's formatter command, then settle formatter-only diffs. Without `--scope`, use the project formatter (here `bun run format`). With `--scope`, use a formatter invocation whose only path operands are inside the selected scope — for Biome, `bunx biome check --write "$SCOPE"`. Never append a path to a script already containing `.`: `biome check . --write <path>` still writes across the repository. Preserve quoted paths and apply the same scope to every later formatting pass. If no scoped formatter is available, report that limitation and leave out-of-scope files untouched. Here `bun run lint` checks formatting without rewriting it and also runs typecheck; formatting errors fail that check.
  2. Run the project's read-only lint/type check (here `bun run lint`). Collect all errors. A repository-wide check may report outside-scope errors; report them without widening the authorized fix scope.
  3. **Surface-change sweep (before any fix).** If the failing set is a **surface/parity** change — CLI noun/verb/flag surface, reference-file structure, or a renamed/moved symbol — do one upfront `rg` sweep across ALL test dirs + docs for stale references to the changed symbols (e.g. `rg -l "<old-noun>|<old-file>.md|Tier C" apps/*/tests plugins/sp/tests plugins/sp/skills docs`), and fix every in-scope pinned test/docs file in that sweep; report outside-scope matches without editing them. A surface change is pinned in **multiple independent test files** (each with its own hardcoded noun→reference map); discovering them one-by-one via full-suite probes is the dominant waste — each wave costs a suite run and a fresh edit loop (task 0436 R2 lesson). One sweep produces the complete edit set upfront.
  4. If lint is clean, skip to step 6.
  5. **Lint fix loop:** for each in-scope error, diagnose the root cause and apply the smallest fix. **Use targeted probes to verify each fix** (`bunx tsc --noEmit` on the affected package, `bunx biome check <file>`) — do NOT re-run the full gate after every batch. Loop until lint is green, or report outside-scope blockers without editing them.
  6. For standalone execution, run `bun run test` and collect all failures. With `--gate-log`, use its failing set and targeted tests instead of running the full suite here.
  7. If tests are green, proceed to the applicable standalone confirmation or pipeline handoff below.
  8. **Test fix loop:** for each in-scope failure, diagnose (test bug vs implementation bug), apply the fix, re-run the **failing test only** (`bun test <file> --test-name-pattern "<test>"`). Report outside-scope blockers without editing them. Do NOT re-run the full suite per fix — it is the dominant loop cost (task 0436 R2).
  9. **Confirming run — standalone invocation only (at most once).** After all fixes, repeat the scope-safe formatting invocation from step 1, then run the selected validation command **at most once** to confirm (here the default project gate is `bun run spur-check`). If it passes, the hop is done. **Skip this step entirely when `--gate-log` is set** (see step 10) — under the pipeline nothing consumes its verdict.
  10. **Pipeline-awareness (R4, task 0483; confirming run dropped 2026-08-31).** `--gate-log` is set only by the pipeline's `test-fix` hop, so treat it as the pipeline signal. There, `test-recheck` runs the full `${vars.qualityGateCmd}` gate immediately after this hop returns — that is the **deciding** run, the only one that writes PASS to `.spur/run/<wbs>-test-gate.status`. A confirming run inside this hop decides nothing and costs a second full gate (~105 s here) to answer a question `test-recheck` is about to answer anyway. So under `--gate-log`: **run no full gate at all.** Your self-check is what step 8 already gives you — the failing tests you re-ran individually — plus **one `bun run lint`** (~7 s: Biome + typecheck) to catch type or lint breakage your fixes introduced. Then return and let `test-recheck` judge. `test-recheck` opens with the same cheap `${vars.gateProbeCmd}` probe, so a still-red tree is caught in seconds rather than by a full suite. Historical anti-pattern this replaces: 0482 ran the gate 3× plus a standalone `bun run test`, and `test-recheck` then ran it a 5th time.
  11. Report: list what was fixed (file + one-line summary per fix). If any error could not be resolved, report it explicitly — do not suppress.
- **Invariants:** Never bypass with `--no-verify`, `--force`, or new `biome-ignore`/`eslint-disable` suppressions. Never skip or `.skip` a test to make the suite green. Fix the root cause, not the symptom. Here lint checks formatting and types; it does not prove that the full test gate passed. Keep every write inside `--scope`. **Never re-run the full gate more than once per confirming pass** (R4) — use targeted probes during the fix loops and let the pipeline's `test-recheck` state be the deciding run.
- **MANDATORY Exit Condition — standalone only.** At step 9, execute the following once; do not add another confirming run:
  1. Run validation command: `eval "$VALIDATION_CMD"`
  2. Capture exit code: `EXIT_CODE=$?`
  3. Output: `echo "EXIT_CODE=$EXIT_CODE"`
  4. **EXIT_CODE must equal 0**

  If EXIT_CODE != 0: NOT completed. Continue the bounded fix loop for in-scope failures; report outside-scope blockers.

  **Pipeline exit condition (`--gate-log` set):** return the fixes and the targeted-test/lint evidence from step 10 to `test-recheck`. Do not run the standalone validation command or claim a full-gate PASS; `test-recheck` owns that verdict.

  **Hallucination Red Flags — STOP if you think:**
  - "The errors look fixed" — check exit code, not appearance
  - "Most tests pass" — partial success = FAILURE
  - "Good enough for now" — 0 is the ONLY acceptable exit code

- **7-Phase Workflow:**

  ```text
  ┌─────────────────────────────────────────────────┐
  │ RETRY LOOP (max --max-retry iterations)         │
  │                                                 │
  │  → Phase 1: Detect validation command           │
  │  → Phase 2: Capture validation output           │
  │  → Phase 3: Auto-fix (biome check --write)      │
  │  → Phase 4: Parse and categorize errors         │
  │  → Phase 5: Root cause diagnosis                │
  │  → Phase 6: Fix by error type group             │
  │  → Phase 7: Validate (check EXIT_CODE)          │
  │                                                 │
  │  If EXIT_CODE = 0: SUCCESS, exit loop           │
  │  If EXIT_CODE != 0: continue                    │
  │                                                 │
  │  If counter >= MAX_RETRY:                       │
  │    Ask user: [Continue / Stop]                  │
  └─────────────────────────────────────────────────┘
  ```

  The 7 phases describe standalone execution: Phases 1–2 capture the gate, Phase 3 settles auto-fixable formatting within scope, Phases 4–6 are the per-group root-cause fix loops, Phase 7 is the final verification run. With `--gate-log`, use the supplied evidence instead of capturing the gate again, and hand off to `test-recheck` instead of running Phase 7's full validation.

- **Fix Priority:**

  | Priority | Type          | Rationale                         |
  | -------- | ------------- | --------------------------------- |
  | 1        | Build/compile | Blocks everything downstream      |
  | 2        | Import/module | May cause cascading type failures |
  | 3        | Type errors   | Often reveals logic bugs          |
  | 4        | Test failures | Confirms behavior correctness     |
  | 5        | Lint warnings | Code quality (lowest priority)    |

  **Critical Rule**: If THREE fixes fail consecutively, STOP. This signals architectural problems.

- **Error Patterns — TypeScript:**

  | Issue               | Root Cause Approach                                  |
  | ------------------- | ---------------------------------------------------- |
  | `any` type          | Trace where untyped data enters; add types at source |
  | Unused variable     | Check if removal breaks anything                     |
  | Missing return type | Read function to understand actual return            |
  | Type mismatch       | Compare expected vs. actual; find divergence         |

- **Bun/V8 Coverage Quirk.** Bun uses V8's function coverage which does NOT count implicit class constructors:

  ```typescript
  // biome-ignore lint/complexity/noUselessConstructor: V8 function coverage requires explicit constructor
  constructor() {}
  ```

### 11. handover

- **Purpose:** Generate a structured handover document when blocked — captures goal, progress, blocker, rejected approaches, and next steps.
- **Inputs:** `"<blocker description>"` (required, positional) — what is blocking progress.
- **Backing:** `inline` — structured doc generation from task context.
- **Behavior:**
  1. Identify the current task context: read the active task file (if any) via `spur task list --status wip --json` to find the WIP task. If a WBS was given as part of the blocker or is otherwise known, use it; otherwise work from the current conversation.
  2. Gather context:
     - **Goal:** what the task is trying to accomplish (from the task's `## Background` / `## Requirements`).
     - **Progress:** what has been done so far (from the task's `## Solution`, `## Testing`, `## Review` sections, and the current conversation).
     - **Blocker:** the `"<blocker description>"` argument — what is stuck and why.
     - **Rejected approaches:** what was tried and why it didn't work (from the conversation + any prior handover).
     - **Next steps:** concrete actions the next agent should take.
  3. Format as a markdown document:

     ```markdown
     # Handover — <task WBS / title>

     ## Goal

     <one-sentence goal>

     ## Progress

     - <what was done — reference existing artifacts by path, don't restate their content>

     ## Blocker

     <blocker description>

     ## Rejected Approaches

     - <approach> — <why it failed>

     ## Suggested Skills

     - <sp:skill-name> — <why the next agent should invoke it here>

     ## Next Steps

     1. <concrete action>
     ```

  4. Write the document & associate task:
     - Always write the standalone handover document to `docs/handover/<YYYY-MM-DD>-<slug>.md` (create `docs/handover/` if absent). This document is the durable SSOT.
     - If a task context exists, append a pointer link (`- Handover: [docs/handover/<YYYY-MM-DD>-<slug>.md](docs/handover/<YYYY-MM-DD>-<slug>.md) — <blocker summary>`) into the task's `## References` section (or non-destructively append to `## Notes` if `References` is unavailable), preserving any pre-existing content without replacing or clobbering it.
  5. Print the path to the handover document.

- **Suggested Skills section:** Name the `sp:*` skill(s) the next agent should invoke to continue —
  inferred from the task's remaining Requirements/AC and the blocker itself (e.g. a design
  disagreement suggests `sp:sys-architecture`; an unmet AC suggests `sp:code-verification`). Omit
  the section only when plain continuation is more relevant than any specific skill.
- **Redaction rule.** Never write secrets, API keys, tokens, credentials, or PII into the handover
  document — not in the Goal/Progress/Blocker prose, not in a pasted error message or log excerpt.
  Redact with `<REDACTED>` and note what kind of value was removed; a handover is a durable file
  that may be read by a different session, agent, or human than the one that hit the blocker.
- **No-duplication rule.** Reference existing artifacts — task sections (`## Solution`,
  `## Testing`, `## Review`), verdict files (`.spur/run/<wbs>-verdict.json`), diffs, and docs — by
  **path**, not by pasting their content into the handover body. The handover is a pointer document;
  restating content it can instead link to makes it stale the moment the source changes.
- **Invariants:** The handover is honest — rejected approaches are recorded so the next agent doesn't retry them. The blocker is specific, not "it doesn't work."
