@gobing-ai/spur 0.4.11 → 0.4.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/config.example.yaml +22 -0
  3. package/config/rules/quality/coverage-gate.yaml +2 -2
  4. package/config/rules/surface/check-cli-surface.yaml +4 -0
  5. package/config/workflows/feature-verification.yaml +14 -5
  6. package/config/workflows/idea-pipeline.yaml +92 -12
  7. package/config/workflows/task-pipeline.yaml +456 -830
  8. package/config/workflows/wayfinder-resolution.yaml +20 -3
  9. package/config/workflows/wrapup-pipeline.yaml +22 -9
  10. package/package.json +1 -1
  11. package/plugins/sp/README.md +2 -2
  12. package/plugins/sp/agents/super-planner.md +2 -2
  13. package/plugins/sp/agents/super-reviewer.md +17 -8
  14. package/plugins/sp/bunfig.toml +3 -3
  15. package/plugins/sp/commands/dev-changelog.md +1 -1
  16. package/plugins/sp/commands/dev-gitmsg.md +2 -2
  17. package/plugins/sp/commands/dev-handover.md +1 -1
  18. package/plugins/sp/commands/dev-idea.md +23 -13
  19. package/plugins/sp/commands/dev-job-dump.md +1 -1
  20. package/plugins/sp/commands/dev-plan.md +17 -6
  21. package/plugins/sp/commands/dev-review.md +1 -1
  22. package/plugins/sp/commands/dev-run.md +7 -6
  23. package/plugins/sp/commands/dev-runall.md +1 -1
  24. package/plugins/sp/plugin.json +1 -1
  25. package/plugins/sp/skills/code-implementation/SKILL.md +7 -7
  26. package/plugins/sp/skills/code-refactoring/SKILL.md +1 -1
  27. package/plugins/sp/skills/code-verification/SKILL.md +1 -1
  28. package/plugins/sp/skills/code-verification/references/secu-review.md +1 -1
  29. package/plugins/sp/skills/code-verification/references/verdict-schema.md +23 -10
  30. package/plugins/sp/skills/doc-evolve/SKILL.md +1 -1
  31. package/plugins/sp/skills/next-router/references/routing-table.md +1 -1
  32. package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +7 -7
  33. package/plugins/sp/skills/spec-decomposition/references/decomposition.md +4 -4
  34. package/plugins/sp/skills/spur-check/SKILL.md +9 -8
  35. package/plugins/sp/skills/spur-cli/SKILL.md +2 -2
  36. package/plugins/sp/skills/spur-cli/references/self.md +37 -2
  37. package/plugins/sp/skills/spur-cli/references/tasks/l3-guard-cheatsheet.md +1 -1
  38. package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +3 -3
  39. package/plugins/sp/skills/spur-cli/references/tasks.md +1 -1
  40. package/plugins/sp/skills/spur-cli/references/workflows.md +5 -3
  41. package/plugins/sp/skills/spur-dev/SKILL.md +3 -3
  42. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +9 -8
  43. package/plugins/sp/skills/spur-dev/references/dev-operations.md +11 -11
  44. package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +4 -3
  45. package/plugins/sp/skills/spur-dev/references/execution-batch-report.md +4 -4
  46. package/plugins/sp/skills/spur-dev/references/execution-batch.md +13 -11
  47. package/plugins/sp/skills/spur-dev/references/execution-workflow.md +31 -22
  48. package/plugins/sp/skills/spur-dev/references/execution-worktree-landing.md +5 -5
  49. package/plugins/sp/skills/spur-dev/references/execution-worktree-setup.md +4 -4
  50. package/plugins/sp/skills/spur-dev/references/gate-checklists.md +4 -4
  51. package/schemas/spur-config.schema.json +19 -1
  52. package/spur.js +31541 -31955
  53. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +0 -997
  54. package/plugins/sp/skills/spur-dev/references/structured-trace-emission.md +0 -178
@@ -37,6 +37,8 @@ vars:
37
37
  agent: "auto"
38
38
  stepTimeoutMs: "1800000"
39
39
  approval: "required"
40
+ # Accepted/deferred status the approve gate's decision binding writes (1236 R2).
41
+ approvalStatus: ""
40
42
  resolutionMode: "research"
41
43
  evidencePolicy: "spur-cli-first"
42
44
  __hitlAnswer: ""
@@ -157,14 +159,29 @@ states:
157
159
  timeoutMs: ${vars.stepTimeoutMs}
158
160
 
159
161
  - id: approve
160
- description: "Human review gate unless the caller explicitly selects auto approval."
161
- pause: true
162
+ description: "Human review gate unless the caller explicitly selects auto approval (vars.approval=auto)."
162
163
  onEnter:
163
164
  - kind: hitl.confirm
164
165
  options:
165
166
  prompt: "Approve research resolution for task ${vars.wbs}?"
167
+ # Interactive always prompts the operator; profile=auto answers from the
168
+ # verifier's recorded evidence (1236 R1/R2). No `pause: true` — an evidence
169
+ # binding cannot live in a paused state (0911 D2).
166
170
  decision:
167
- mode: never
171
+ mode: evidence
172
+ statusVar: approvalStatus
173
+ evidenceNodes:
174
+ - verify
175
+ # A deferred/absent answer is the denial today's headless responder gave.
176
+ - kind: shell
177
+ options:
178
+ command: >-
179
+ mkdir -p .spur/run; a="$__hitlAnswer"; [ -n "$a" ] || a=no;
180
+ printf '%s\n' "$a" > ".spur/run/$__runId-wayfinder-approve-answer.txt"
181
+ - kind: file.read.into-var
182
+ options:
183
+ path: .spur/run/${vars.__runId}-wayfinder-approve-answer.txt
184
+ var: __hitlAnswer
168
185
 
169
186
  - id: record
170
187
  description: >
@@ -98,7 +98,7 @@
98
98
  "$schema": "@gobing-ai/spur/schemas/state-machine-workflow.schema.json"
99
99
  kind: state-machine
100
100
  name: wrapup-pipeline
101
- version: "9"
101
+ version: "11"
102
102
  description: "Post-execution wrap-up: doc-sync (doc drift + learning capture), metrics, feature-transition, branch-cleanup"
103
103
  iterationBound: 10
104
104
  initialState: start
@@ -123,14 +123,18 @@ vars:
123
123
  # TRUSTED CONFIG ONLY — this string is executed via `sh -c` (same surface as
124
124
  # task-pipeline's qualityGateCmd). Never interpolate untrusted input into it.
125
125
  featureGateCmd: '$spurBin feature check "$feature"'
126
- # Repo-wide tripwire over the wrap diff (1037): runs `bun run test-repo-wide`
127
- # only when package.json declares the script, so other projects no-op. Callers
126
+ # Repo-wide tripwire over the wrap diff (1037): runs `$spurBin self exec test-repo-wide`
127
+ # only when that action is bound (a project declares it as a custom action), so other
128
+ # projects no-op — loudly: the skip prints one stderr note naming the missing binding, so a
129
+ # silently-dead tripwire cannot masquerade as a green wrap (task 1229). Callers
128
130
  # can override it with --vars; an empty string disables the check (the hop
129
131
  # still writes PASS).
130
132
  # TRUSTED CONFIG ONLY — this string is executed via `sh -c` (same surface as
131
133
  # featureGateCmd). Never interpolate untrusted input into it.
132
- docTripwireCmd: 'if jq -e ''.scripts["test-repo-wide"]'' package.json >/dev/null 2>&1; then bun run test-repo-wide; fi'
134
+ docTripwireCmd: 'if $spurBin self exec --list --json 2>/dev/null | jq -e ''.[] | select(.name == "test-repo-wide" and .source != "unbound")'' >/dev/null 2>&1; then $spurBin self exec test-repo-wide; else echo "wrapup: doc tripwire skipped — the test-repo-wide action is unbound; declare builder.actions.test-repo-wide to enable it" >&2; fi'
133
135
  __hitlAnswer: ""
136
+ # Accepted/deferred status the branch-cleanup gate's decision binding writes (1236 R2).
137
+ branchCleanupStatus: ""
134
138
 
135
139
  states:
136
140
  - id: start
@@ -265,6 +269,12 @@ states:
265
269
  role: coder
266
270
  answerFile: .spur/run/${vars.__runId}-wrapup-learnings.md
267
271
  expectFile: .spur/run/${vars.__runId}-wrapup-learnings.md
272
+ # The task-resolve state writes this list through `spur task wrapup resolve`,
273
+ # so the path never appears in a YAML shell and the static scan cannot see the
274
+ # production — declare it as the stage's input instead (1233 R2).
275
+ inputs:
276
+ - path: .spur/run/${vars.__runId}-wrapup-tasks.json
277
+ kind: artifact
268
278
  timeoutMs: ${vars.stepTimeoutMs}
269
279
  # (1147 R1) post-doc-sync write-scope guard: the script diffs the working listing
270
280
  # against the entry snapshot and writes PASS or `scope-violation: <paths>` — the
@@ -454,16 +464,19 @@ states:
454
464
  Irreversible-operation HITL gate, consent-only (0770). If vars.merge=true,
455
465
  branch cleanup (merge or delete) is a candidate — but this gate records
456
466
  the operator decision and performs NO git operation itself; an operator
457
- or a separate approved surface executes any actual merge/delete. This
458
- gate ALWAYS pauses — even under --auto — because branch operations are
459
- irreversible (Auto-Decision Principle #6).
460
- pause: true
467
+ or a separate approved surface executes any actual merge/delete. Interactive
468
+ runs always ask the operator; profile=auto answers from the doc-sync stage's
469
+ recorded evidence and still records the decision (1236 R1/R2). Nothing is
470
+ auto-executed: both answers route to `done` (Auto-Decision Principle #6).
461
471
  onEnter:
462
472
  - kind: hitl.confirm
463
473
  options:
464
474
  prompt: "Branch cleanup for the validated task list (.spur/run/${vars.__runId}-wrapup-tasks.json). This is IRREVERSIBLE (merge or delete). Confirm to proceed?"
465
475
  decision:
466
- mode: never
476
+ mode: evidence
477
+ statusVar: branchCleanupStatus
478
+ evidenceNodes:
479
+ - doc-sync
467
480
 
468
481
  - id: done
469
482
  description: >
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobing-ai/spur",
3
- "version": "0.4.11",
3
+ "version": "0.4.12",
4
4
  "description": "Spur CLI — local-first harness for mainstream coding agents: constraint checking, workflow orchestration, agent health, and history analytics. Bun-native; exposes the `spur` command.",
5
5
  "keywords": [
6
6
  "spur",
@@ -242,7 +242,7 @@ plugins/sp/
242
242
  │ │ └── references/ # ac-style-guide, cross-cutting, decision-brief, dev-operations,
243
243
  │ │ done-housekeeping, execution-batch, execution-workflow,
244
244
  │ │ feature-link-helper, flag-glossary, gate-checklists, glossary,
245
- │ │ idea-evaluation, inline-pipeline-driver, planning-workflow,
245
+ │ │ idea-evaluation, execution-workflow, planning-workflow,
246
246
  │ │ product-planning, section-batching (16 files)
247
247
  │ ├── test-driven-development/ # TDD workflow companion (SKILL.md only)
248
248
  │ ├── reverse-engineering/ # Codebase reverse engineering / HLD / audit
@@ -354,7 +354,7 @@ surface or run one workflow. All skills target the same five core platforms: `cl
354
354
  | `session-review` | 1.1 | Inline review of the active coding-agent session — compact outcomes, evidence-backed resolved/open issue classification, proposal-only improvements, and next actions; no workflow, import, delegation, or mutation |
355
355
  | `spur-composer` | 1.0 | Cross-noun composition — workflow catalog selection, the ephemeral→project→shared ladder, ADR-115 budgets, trace-driven rule tuning; applies accepted `spur-doctor` proposals through `spur` verbs; never judges its own output and never runs a recurring loop |
356
356
  | `spur-doctor` | 1.0 | Cross-noun evaluation — read-only CLI evidence per noun (task/feature/rule/workflow/agent spec), reflection over `history-anatomy` findings through a closed action-class map, and a proposal table; writes nothing; diagnoses artifacts, not runtime environments (`spur agent doctor`'s job) |
357
- | `spur-check` | 1.0 | Two-tier check primitive (ADR-124) — light changed-scope checks during development, the full `bun run spur-check` chain at the quality boundary, and the fingerprint-bound `<wbs>-check-receipt.json` with the `status` reuse rule; composes with `/sp:dev-fixall --gate-log` |
357
+ | `spur-check` | 1.0 | Two-tier check primitive (ADR-124) — light changed-scope checks during development, the full `spur self exec check` chain at the quality boundary, and the fingerprint-bound `<wbs>-check-receipt.json` with the `status` reuse rule; composes with `/sp:dev-fixall --gate-log` |
358
358
  | `redesign-web-ui` | 1.0 | Existing-UI visual upgrade — audit generic AI fingerprints, apply in-stack polish against `DESIGN.md` / live tokens, verify behavior and viewports; does not migrate frameworks |
359
359
  | `taste-refactoring-api` | 1.0 | API design and refactoring for REST/HTTP, RPC/gRPC, GraphQL, event contracts, and CLI surfaces; compatibility, security, and migration review |
360
360
  | `taste-refactoring-ui` | 1.0 | UI design and refactoring with visual hierarchy, typography, spacing, color, and interaction review |
@@ -288,8 +288,8 @@ With `--json`, emit the same shape as a JSON object for machine consumption.
288
288
 
289
289
  The parent host owns the visible plan: apply the § 2.7 Visible batch plan updates in the parent
290
290
  session's native todo list (`execution-batch.md` § 2.7; the frozen status mapping lives in
291
- [inline-pipeline-driver.md](../skills/spur-dev/references/inline-pipeline-driver.md) § Host todo
292
- update styles). Subagents own code and evidence — subagents never render the visible list and todo
291
+ [cross-cutting.md](../skills/spur-dev/references/cross-cutting.md#shared-startup-contract-task-0814-r1r3r4r6r7r8) § Publish the
292
+ generated plan). Subagents own code and evidence — subagents never render the visible list and todo
293
293
  tools are not available to them; at each **stage boundary** (implement, test, review, verify) a
294
294
  subagent returns `{wbs, state, outcome}` (+ optional `next`), and the parent marks the matching rows
295
295
  with the reported outcome. Keep letters/digits from the projection identical across both layers so
@@ -225,14 +225,23 @@ FAIL, PARTIAL, a missing line, a line split across two lines — routes the run
225
225
  `review-fail-triage` and its bounded repair hop. Keep it on one line, in that shape, in every
226
226
  review answer; never restate it as prose only.
227
227
 
228
- **No confidence line (F511, task 1207).** Review reports do not state, and no gate reads, an
229
- asserted `Confidence: HIGH | MEDIUM | LOW`. A model that can write a PASS can write `HIGH`, so the
230
- gate grades what is checkable instead: the recorded section's presence and vocabulary, and the
231
- findings disposition — an open P1–P3 row blocks the edge exactly as before. What a reviewer would
232
- formerly have compressed into a level belongs in the report body: name the evidence gaps and the
233
- assumptions explicitly, so a reader can re-check them. (The derived confidence family is
234
- untouched: feature-verification receipts under ADR-131, the decision subsystem threshold, and
235
- history-anatomy reading.)
228
+ **State `Confidence: HIGH | MEDIUM | LOW` — the gate derives it from your dispositions (ADR-141).**
229
+ The review report carries exactly one top-level `Confidence:` line, and it is **cross-checked**: a
230
+ stated level that disagrees with the table is a blocking `review-contract` violation, so a PASS
231
+ carrying citation-free or untested claims cannot launder itself as `HIGH`.
232
+
233
+ | Derived | When the table says so |
234
+ | --- | --- |
235
+ | `LOW` | the verdict is not PASS, or an open (or undispositioned) P1–P3 row survives |
236
+ | `HIGH` | PASS with every finding closed (`RESOLVED` / `FIXED` / `DONE`) and no carried residual |
237
+ | `MEDIUM` | PASS with carried residuals only — `DEFER(...)`, `ACCEPTED`, or an open P4 |
238
+
239
+ Derivation: `packages/app/src/services/answer-confidence.ts` (shared with the verify answer). This
240
+ does not revive the retired self-grade: the level records **evidence composition** — what a reader
241
+ would otherwise have to re-derive from the rows — and the gate recomputes it rather than trusting it.
242
+ No verdict-artifact field, no receipt level, no per-finding grade, and no operator ack var exists
243
+ (ADR-138 stands for every other carrier). Evidence gaps still belong in the report body: name them,
244
+ then let the dispositions decide the level.
236
245
 
237
246
  **Source citations for external claims (one claim contract, 2026-10-12).** A Finding cell or a
238
247
  Functional Traceability `Evidence` cell that asserts an external API/library claim carries a
@@ -4,8 +4,8 @@
4
4
  # tests off the operator's real ~/.config/spur/ config, projects registry and slash-command catalog).
5
5
  # Coverage stays gated by the root bunfig (bun run test).
6
6
  #
7
- # Historical: this comment once justified the preload by a host-wide `full-gate.lock` wait. That lock
8
- # was deleted in `refactor(gate): remove gate-lock mechanism and simplify quality-gate`; the preload
9
- # is still required, for the reasons above (task 1173 R5).
7
+ # The preload also carries the host-wide `full-gate.lock` isolation (tests/setup.ts gives every test
8
+ # process its own SPUR_GATE_LOCK_DIR), so an in-process gate never queues behind a real one. The
9
+ # preload stays required for the reasons above even without it (task 1173 R5; lock restored by 1235).
10
10
  [test]
11
11
  preload = ["../../tests/setup.ts"]
@@ -26,5 +26,5 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
26
26
 
27
27
  ## Implementation
28
28
 
29
- Follow the inline procedure in [dev-operations.md](../skills/spur-dev/references/dev-operations.md#8-changelog) (changelog). This is a docs-only generator: run no quality gates (`bun run gate`, lint, typecheck, tests, `spur-check`, rules) — a generic "verify before finishing" rule does not apply here. The generator's own claim-verification pass is part of the procedure, not a gate, and carries one required check per claim bullet (dev-operations §8, step 7): a **source citation** — an anchor naming a URL or a repo `path:line` — held in the bullet's `<!-- src: … -->` comment and re-verified by step 8's self-check. No confidence level is recorded (ADR-138).
29
+ Follow the inline procedure in [dev-operations.md](../skills/spur-dev/references/dev-operations.md#8-changelog) (changelog). This is a docs-only generator: run no quality gates (`spur self exec autofix|check|lint`, typecheck, tests, rules) — a generic "verify before finishing" rule does not apply here. The generator's own claim-verification pass is part of the procedure, not a gate, and carries one required check per claim bullet (dev-operations §8, step 7): a **source citation** — an anchor naming a URL or a repo `path:line` — held in the bullet's `<!-- src: … -->` comment and re-verified by step 8's self-check. No confidence level is recorded (ADR-138).
30
30
 
@@ -17,7 +17,7 @@ Implements an inline procedure — see [dev-operations.md](../skills/spur-dev/re
17
17
  | `--squash` | Collapse every concern into one message and one commit; implies `--commit`. | off |
18
18
  | `--all` | Widen the change set past the index to every change in the tree — unstaged **and untracked**. | off |
19
19
  | `--scope` `<path>` | Path filter on the change set; always wins over change-set auto-discovery. | the whole change set |
20
- | `--check` `<cmd>` | Run `<cmd>` (e.g. `"bun run gate"`) once before committing; non-zero → commit nothing. | off |
20
+ | `--check` `<cmd>` | Run `<cmd>` (e.g. `"spur self exec check"`) once before committing; non-zero → commit nothing. The example is `check`, not the `autofix` + `check` that `gate` maps to: a pre-commit check must not rewrite the tree. | off |
21
21
 
22
22
  For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag-glossary.md).
23
23
 
@@ -36,6 +36,6 @@ commit per concern, split automatically, so the operator is never asked to re-st
36
36
  `--squash` → one commit for everything. An empty index widens to the whole tree only on a
37
37
  message-only run, and says so; a committing run stops there and prints the exact `--all` re-run line
38
38
  instead of guessing.
39
- No quality gate (`bun run gate`, lint, typecheck, tests, `spur-check`) runs unless `--check <cmd>`
39
+ No quality gate (`spur self exec autofix|check|lint`, typecheck, tests) runs unless `--check <cmd>`
40
40
  names one — then it runs once, before any commit, and a failure commits nothing. Gate → auto-fix →
41
41
  commit is `/sp:dev-gtd --no-push`.
@@ -24,5 +24,5 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
24
24
  ## Implementation
25
25
 
26
26
  Follow the inline procedure in [dev-operations.md](../skills/spur-dev/references/dev-operations.md#11-handover) (handover).
27
- Run no quality gate (`bun run gate`, lint, typecheck, tests, `spur-check`); cite results already on record.
27
+ Run no quality gate (`spur self exec autofix|check|lint`, typecheck, tests); cite results already on record.
28
28
 
@@ -17,7 +17,7 @@ contract below maps to that workflow's transitions.
17
17
  | `"<idea>"` | Vague idea to turn into a feature with AC and tasks. | required (or `--from-file`) |
18
18
  | `--from-file` `<path>` | Read the idea from a file instead of the positional argument. Mutually exclusive with `"<idea>"` — exactly one must be present. The file's contents become the verbatim idea text (trimmed of surrounding whitespace only). Useful for long or multiline asks that are awkward to quote. | off |
19
19
  | `--skip-design` | Omit system-design (and its approval gate) and per-task Design. | off |
20
- | `--agent` `<inline\|auto\|name>` | Who runs the model-bearing ideation. Omission and `inline` drive `idea-pipeline.yaml` in this session with zero external agent/workflow processes; `auto` tier-resolves an executor and a name pins one, both through the async workflow worker. | inline |
20
+ | `--agent` `<inline\|auto\|name>` | Who runs the model-bearing ideation. Omission and `inline` run `idea-pipeline.yaml` on the engine with `executor=host`, so each stage pauses with a work item this session performs; `auto` tier-resolves an executor and a name pins one, both dispatched as child processes. | inline |
21
21
  | `--auto` | Accept the pipeline's recommendation at every operator gate (see below). | off |
22
22
 
23
23
  For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag-glossary.md).
@@ -36,9 +36,11 @@ There is **no** `--design` force flag. Design is default-on; only `--skip-design
36
36
  **Removed flags:** `--approve-taste`, `--idea-approved`, and `--design-approved` are folded into
37
37
  `--auto`. If passed, ignore them with a one-line notice; do not treat them as `--auto`.
38
38
 
39
- **Operator gates.** Every gate is asked as one `AskUserQuestion` [decision brief](../skills/spur-dev/references/decision-brief.md):
40
- the recommended option first, then options with their reasoning. The operator picks; they never
41
- type a yes/no. `--auto` takes the recommended option at each gate without asking.
39
+ **Operator gates.** Every gate is a decision point: interactively the gate asks the operator one
40
+ [decision brief](../skills/spur-dev/references/decision-brief.md) — the recommended option first, then
41
+ options with their reasoning; the operator picks, they never type a yes/no. Under `--auto`
42
+ (`profile=auto`) the recorded guard route or the gate's declared evidence binding decides, and the
43
+ trace records the answering source. `--auto` takes the recommended option at each gate.
42
44
 
43
45
  | Gate | Pauses when | Recommendation comes from | `--auto` takes |
44
46
  | --- | --- | --- | --- |
@@ -56,17 +58,25 @@ Flag → vars: `--auto` sets `profile=auto`, `idea_approved=true`, `design_appro
56
58
  reading any reference — is `spur workflow show idea-pipeline.yaml --no-logo --format todo --json`
57
59
  (the CLI resolves the project→registered→shared layer); then publish every `.plan` row's `text`
58
60
  verbatim as the host todo list (the `steps[]` inventory when `.plan` is `null`) before the
59
- pipeline's first stage — [inline pipeline driver](../skills/spur-dev/references/inline-pipeline-driver.md)
60
- run setup step 5.
61
- - Apply the [inline-default execution-surface contract](../skills/spur-dev/references/cross-cutting.md#inline-default-execution-surface).
62
- - Omitted/`inline`: drive `idea-pipeline.yaml` through the [inline pipeline driver](../skills/spur-dev/references/inline-pipeline-driver.md). Do not launch `spur workflow run`, `spur agent run`, or a native subagent unless the operator explicitly requests delegation.
63
- - `auto`/name: launch `spur workflow run idea-pipeline.yaml --async`, observe with one `workflow trace --follow`, and only report cancellation as stopped when `workflow cancel --json` returns `killed: true`.
61
+ pipeline's first stage.
62
+ - **The loop is three moves** (D65 / ADR-140, design `workflow-execution-foundation` §3):
63
+ `spur workflow run` → perform the returned work item → `spur workflow continue`. The engine owns
64
+ every guard, transition and deterministic action; this session never re-executes them.
65
+ - Omitted/`inline` — the run dispatches to this host session:
66
+ `spur workflow run idea-pipeline.yaml --vars '{"idea":"<idea>","executor":"host",...}' --json`.
67
+ A host stage returns `{status: "paused", pause: {workItem: {runId, state, skill, prompt, inputs,
68
+ expectFiles, ownedSections}}}`. Perform that work item natively (or through a native subagent), write
69
+ its receipt, and advance with `spur workflow continue <run-id> --answer-text <receipt> --json`;
70
+ repeating the same receipt is refused as not-paused, so the resume is idempotent. Repeat until the
71
+ run is terminal.
72
+ - `auto`/name — same definition, no `executor` var: the subprocess executor runs each work item.
73
+ Launch `spur workflow run idea-pipeline.yaml --async`, observe with one `workflow trace --follow`,
74
+ and only report cancellation as stopped when `workflow cancel --json` returns `killed: true`.
64
75
  - `Skill(skill="sp:spur-dev", args="idea $ARGUMENTS")`
65
76
  - Pass the idea text through every hop **verbatim** — never paraphrase or shorten it in the nested
66
77
  `Skill` call or stage prompts; long ideas lose their trailing asks when summarized at the hop.
67
- - Before executing the pipeline's `start` state, persist the operator's idea argument (or the
68
- `--from-file` contents) **unmodified** to `.spur/run/<run-id>-idea-input.md` (0887 R1); every
69
- model-bearing stage prompt treats that file as the authoritative ask, and the precheck fails
70
- the run when it is empty or missing.
78
+ - The `start` state persists the operator's idea argument (or the `--from-file` contents)
79
+ **unmodified** to `.spur/run/<run-id>-idea-input.md` (0887 R1); every model-bearing stage prompt
80
+ treats that file as the authoritative ask, and the precheck fails the run when it is empty or missing.
71
81
  - Stage contract (discovery → idea-eval → feature-create → AC → feature-check → system-design →
72
82
  decompose → batch-create → ready-prepare → handoff): `plugins/sp/skills/spur-dev/references/dev-operations.md` § idea.
@@ -25,6 +25,6 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
25
25
 
26
26
  Follow [job-dump](../skills/spur-dev/references/dev-operations.md#11a-job-dump), using the shared
27
27
  handoff template to capture the current job and its remaining work. Run no quality gate
28
- (`bun run gate`, lint, typecheck, tests, `spur-check`); copy existing gate results or write `not run`.
28
+ (`spur self exec autofix|check|lint`, typecheck, tests); copy existing gate results or write `not run`.
29
29
 
30
30
  Skill(skill="sp:spur-dev", args="job-dump $ARGUMENTS")
@@ -16,7 +16,7 @@ Wraps the **sp:spur-dev** skill.
16
16
  | `"<description>"` | Feature description to plan. | required |
17
17
  | `--feature` `<id>` | Attach to an existing feature. | omitted |
18
18
  | `--parent` `<feature-id>` | Create under a parent feature. | omitted |
19
- | `--agent` `<inline\|auto\|name>` | Who runs the model-bearing planning. Omission and `inline` drive `idea-pipeline.yaml` in this session with zero external agent/workflow processes; `auto` tier-resolves an executor and a name pins one, both through the async workflow worker. | inline |
19
+ | `--agent` `<inline\|auto\|name>` | Who runs the model-bearing planning. Omission and `inline` run `idea-pipeline.yaml` on the engine with `executor=host`, so each stage pauses with a work item this session performs; `auto` tier-resolves an executor and a name pins one, both dispatched as child processes. | inline |
20
20
  | `--skip-design` | Omit the system-design hop. | off |
21
21
  | `--auto` | Accept the pipeline's recommendation at every operator gate (same gate table as `/sp:dev-idea`). | off |
22
22
 
@@ -45,10 +45,21 @@ contract as `/sp:dev-idea`). If passed, ignore them with a one-line notice.
45
45
  reading any reference — is `spur workflow show idea-pipeline.yaml --no-logo --format todo --json`
46
46
  (the CLI resolves the project→registered→shared layer); then publish every `.plan` row's `text`
47
47
  verbatim as the host todo list (the `steps[]` inventory when `.plan` is `null`) before the
48
- pipeline's first stage — [inline pipeline driver](../skills/spur-dev/references/inline-pipeline-driver.md)
49
- run setup step 5.
50
- - Apply the [inline-default execution-surface contract](../skills/spur-dev/references/cross-cutting.md#inline-default-execution-surface).
51
- - Omitted/`inline`: drive `idea-pipeline.yaml` through the [inline pipeline driver](../skills/spur-dev/references/inline-pipeline-driver.md). Do not launch `spur workflow run`, `spur agent run`, or a native subagent unless the operator explicitly requests delegation.
52
- - `auto`/name: launch `spur workflow run idea-pipeline.yaml --async`, observe with one `workflow trace --follow`, and only report cancellation as stopped when `workflow cancel --json` returns `killed: true`.
48
+ pipeline's first stage.
49
+ - **The loop is three moves** (D65 / ADR-140, design `workflow-execution-foundation` §3):
50
+ `spur workflow run` → perform the returned work item → `spur workflow continue`. The engine owns
51
+ every guard, transition and deterministic action; this session never re-executes them.
52
+ - Omitted/`inline` — the run dispatches to this host session:
53
+ `spur workflow run idea-pipeline.yaml --vars '{"executor":"host",...}' --json` (plus `idea`, or
54
+ `--from-file`; `--feature`/`--parent` as the flag table says, `--skip-design` → `design=skip`,
55
+ `--auto` → `profile=auto` + `idea_approved=true` + `design_approved=true`).
56
+ A host stage returns `{status: "paused", pause: {workItem: {runId, state, skill, prompt, inputs,
57
+ expectFiles, ownedSections}}}`. Perform that work item natively (or through a native subagent), write
58
+ its receipt, and advance with `spur workflow continue <run-id> --answer-text <receipt> --json`;
59
+ repeating the same receipt is refused as not-paused, so the resume is idempotent. Repeat until the
60
+ run is terminal.
61
+ - `auto`/name — same definition, no `executor` var: the subprocess executor runs each work item.
62
+ Launch `spur workflow run idea-pipeline.yaml --async`, observe with one `workflow trace --follow`,
63
+ and only report cancellation as stopped when `workflow cancel --json` returns `killed: true`.
53
64
  - `Skill(skill="sp:spur-dev", args="plan $ARGUMENTS")`
54
65
  - Full Design package + batch `design` field contract: `plugins/sp/skills/spur-dev/references/dev-operations.md` § plan and `planning-workflow.md` Step 5.5.
@@ -43,7 +43,7 @@ Put the target first: a bare token after `--worktree` is read as the worktree na
43
43
  - **WBS mode (per task target):** `Skill(skill="sp:functional-review", args="<wbs> $FLAGS")` + `Skill(skill="sp:code-verification", args="review <wbs> $FLAGS")` + `Skill(skill="sp:code-improvement", args="<wbs> $FLAGS")` (functional traceability + SECUA framework + architectural depth — each skill receives its one resolved WBS exactly once plus `$FLAGS` = `$ARGUMENTS` minus the selector (`--tasks`/`--feature`/`--scope` or positional) and its value, never the raw selector, and returns a review fragment only — F92 0593 R1)
44
44
  - **Task fan-out (`--tasks` / `--feature`).** One WBS-mode review per task in the frozen set. Tasks in `backlog`/`todo`/`blocked` are reported NOT-STARTED and skipped (§ 3a outcome vocabulary); a per-task failure does not stop the remaining tasks. Each implemented task gets its own merged `## Review`; the run ends with a combined summary table (WBS, verdict, P1/P2 counts).
45
45
  - Coordinator = this session. No `sp:super-reviewer` subagent is dispatched: act as the review coordinator defined in [agents/super-reviewer.md](../agents/super-reviewer.md) — merge the fragments per its Output Format (native `P1`–`P4` priority cells, section-relative headings) and, for every task target (standalone or pipeline), write that task's combined `## Review` via `spur task update <wbs> --section Review --from-file`. Path mode emits advisory output only.
46
- - **Answer contract (pipeline dispatches).** The captured review answer (`.spur/run/<runId>-review-answer.txt`) must carry exactly one `Verdict: PASS|FAIL` line; the PASS edges grep it before the review gate runs. No confidence line exists and none is graded (F511, task 1207): model-asserted confidence is not verification — the gate's job is the findings disposition, and an open P1–P3 finding blocks the edge on its own.
46
+ - **Answer contract (pipeline dispatches).** The captured review answer (`.spur/run/<runId>-review-answer.txt`) must carry exactly one `Verdict: PASS|FAIL` line **and** the requirement traceability table `| Req | Status | Evidence |` (D65 1239: `verify` merged into `review`, so this answer is the pipeline's only verification record). It also carries exactly one `Confidence: HIGH|MEDIUM|LOW` line whose level its own findings derive (ADR-141 — no open P1–P3 and no carried residual is HIGH, a carried residual is MEDIUM, an open P1–P3 or a non-PASS verdict is LOW); the gate recomputes the level and rejects a disagreement, so stating a level the dispositions do not support fails the review. `spur task verdict --from-answer` owns the parse — it lints the table and the level, writes the canonical `.spur/run/<wbs>-verdict.json` that `spur task record` reads for box flips and `## Testing`, and a non-zero exit fails the review stage; never re-implement the parse in shell. On a feature-linked task, key each AC row to its feature scenario (scenario title, `AC-N` alias, `(feature R<n>)` or `[R<n>]`) — a row keyed only by a task requirement id credits no scenario at the feature done gate.
47
47
  - **Path mode (per path target):** `Skill(skill="sp:code-verification", args="review <path> $FLAGS")` + `Skill(skill="sp:code-improvement", args="<path> $FLAGS")` (advisory SECUA quality + architectural depth — one normalized path forwarded once plus `$FLAGS`; performs no task mutation). Under `--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`); each surviving path gets a sub-review (Step 3p path scope), eligible for native-subagent dispatch per [dispatch-surface.md](../skills/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** advisory report. No task mutation.
48
48
  - **Positional alias (deprecated).** A positional `<wbs|path>` is accepted for one release: a `^\d{4}$` token with a resolvable task behaves as `--tasks <wbs>`; an existing path as `--scope <path>`; otherwise exit 2. Print a deprecation warning naming the replacement selector; removal is a follow-up.
49
49
  - `--triage`: after the review returns, run the triage protocol in [dev-operations.md § 2. review](../skills/spur-dev/references/dev-operations.md#2-review) **inline in this session** — the review skills and `sp:super-reviewer` stay report-only. With multiple targets, bucket the findings across all targets once (identical `file:line` findings deduped before bucketing). `Edit`/`Write` in `allowed-tools` exist only for these direct fixes.
@@ -38,14 +38,15 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
38
38
  `.plan` row's `text` verbatim as the host todo list (the `steps[]` inventory when `.plan` is
39
39
  `null`) before readiness, Git, or isolation work —
40
40
  [shared startup contract](../skills/spur-dev/references/cross-cutting.md#shared-startup-contract-task-0814-r1r3r4r6r7r8)
41
- step 1 / [inline pipeline driver](../skills/spur-dev/references/inline-pipeline-driver.md) run
42
- setup step 5.
41
+ step 1 / [engine run setup](../skills/spur-dev/references/cross-cutting.md#shared-startup-contract-task-0814-r1r3r4r6r7r8) step 5.
43
42
  - Apply the [inline-default execution-surface contract](../skills/spur-dev/references/cross-cutting.md#inline-default-execution-surface).
44
43
  - Apply the [shared startup contract](../skills/spur-dev/references/cross-cutting.md#shared-startup-contract-task-0814-r1r3r4r6r7r8) — publish the generated plan first, quick readiness before isolation, digest binding, comprehensive checks at their owning boundaries (task 0814 R1/R3/R4/R7/R8; 1105 R1).
45
- - Full pipeline (default `--mode full`): interactive omit/`--agent inline` uses the
46
- [inline pipeline driver](../skills/spur-dev/references/inline-pipeline-driver.md) via
47
- `Skill(skill="sp:spur-dev", args="run-inline $ARGUMENTS")`; `--agent auto` or a named executor
48
- uses `Skill(skill="sp:spur-dev", args="run $ARGUMENTS")` and the workflow subprocess path.
44
+ - Full pipeline (default `--mode full`): interactive omit/`--agent inline` runs
45
+ [the engine loop](../skills/spur-dev/references/cross-cutting.md#inline-default-execution-surface)
46
+ with `executor=host` — `spur workflow run` returns a work item, this session performs it, and
47
+ `spur workflow continue <run-id> --answer-text <receipt>` advances the run; `--agent auto` or a
48
+ named executor runs the same definition as a child process. Both go through
49
+ `Skill(skill="sp:spur-dev", args="run $ARGUMENTS")`.
49
50
  - Implement step only (`--mode implement`): `Skill(skill="sp:code-implementation", args="$ARGUMENTS")`
50
51
  - After a full-mode run settles (done, failed or paused), print the
51
52
  [execution summary](../skills/spur-dev/references/dev-operations.md#execution-summary) unless `--no-summary`.
@@ -105,7 +105,7 @@ full distinction.
105
105
  freeze/order and digit children from `spur task batch-plan task-children` at task start —
106
106
  [execution-batch.md](../skills/spur-dev/references/execution-batch.md#27-visible-batch-plan-1105-r3)
107
107
  § 2.7 Visible batch plan.
108
- - Apply the [inline-default execution-surface contract](../skills/spur-dev/references/cross-cutting.md#inline-default-execution-surface). Interactive sequential omit/`inline` keeps the orchestrator in the host session through the [inline pipeline driver](../skills/spur-dev/references/inline-pipeline-driver.md); the resolved selector applies uniformly — eligible `agent.run` stages dispatch once to a native subagent with host fallback (0508). `--agent auto`, a name, or parallel mode retains the isolated per-task workflow boundary.
108
+ - Apply the [inline-default execution-surface contract](../skills/spur-dev/references/cross-cutting.md#inline-default-execution-surface). Interactive sequential omit/`inline` keeps the orchestrator in the host session through the engine loop (`spur workflow run --vars '{"executor":"host"}'` → work item → `spur workflow continue`); the resolved selector applies uniformly — eligible `agent.run` stages dispatch once to a native subagent with host fallback (0508). `--agent auto`, a name, or parallel mode retains the isolated per-task workflow boundary.
109
109
  - Apply the [shared startup contract](../skills/spur-dev/references/cross-cutting.md#shared-startup-contract-task-0814-r1r3r4r6r7r8) — publish the generated plan first, quick readiness before isolation, digest binding, comprehensive checks at owning boundaries (task 0814 R1/R3/R4/R7/R8; 1105 R1).
110
110
  - Interactive sequential omit/inline, and `--mode auto` without an explicit executor: `Skill(skill="sp:spur-dev", args="runall-inline $ARGUMENTS")` — auto resolves in the host after freeze/order (§ 2.4a) and hands a parallel resolution to the `runall` path with the frozen explicit WBS list.
111
111
  - Explicit executor (any mode, including `auto`) or parallel mode: `Skill(skill="sp:spur-dev", args="runall $ARGUMENTS")` → `sp:super-planner` agent.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "sp",
3
- "version": "0.4.11",
3
+ "version": "0.4.12",
4
4
  "description": "Spur — a local-first harness engineering toolkit that wraps mainstream coding agents with constraint checking, workflow orchestration, and history analytics."
5
5
  }
@@ -104,7 +104,7 @@ surfaces is what keeps that gate quiet.
104
104
  ## Implement scope: do not run the project quality gate
105
105
 
106
106
  During implement, the pipeline's `test` hop runs `${vars.qualityGateCmd}` (the full project gate:
107
- `bun run spur-check`) immediately after this step and is the gate that actually
107
+ `spur self exec check`) immediately after this step and is the gate that actually
108
108
  decides pass/fail. Running it inside implement is pure redundancy — it cannot change the outcome and
109
109
  only burns wall clock and context budget.
110
110
 
@@ -117,7 +117,7 @@ only burns wall clock and context budget.
117
117
  against a different tree. Same rule for the working directory: each shell call starts fresh, so
118
118
  re-select the execution tree inside the call (`cd -- "$TREE"` plus the identity check) instead of
119
119
  relying on a `cd` a previous call left behind.
120
- - **NEVER run** `bun run test`, `bun run spur-check`, `bun run check`, or any other full-suite /
120
+ - **NEVER run** `spur self exec test`, `spur self exec check`, `bun run check`, or any other full-suite /
121
121
  project-gate command from inside implement. These belong to the pipeline's `test` hop.
122
122
  - **Full-suite budget: at most 2 per task** (task 0436 R2) — counted across the whole task run
123
123
  (implement probes + the pipeline `test` hop + verify/recheck), not per step. When a check fails,
@@ -153,7 +153,7 @@ changed no public surface, report the single line
153
153
  `env-var-hygiene` rule, and its siblings);
154
154
  - `bun run script-contract-check` when a plugin script was touched (a stale generated `.mjs` twin);
155
155
  - the paired-script parity test when `package.json` changed (a half-updated `spur-check` /
156
- `spur-check-new` chain).
156
+ `spur-check:full` chain).
157
157
 
158
158
  The single full project check stays the pipeline `test` hop's job (see the section above); these are
159
159
  changed-path checks, not that gate.
@@ -163,8 +163,8 @@ changed-path checks, not that gate.
163
163
  "Run the narrow test first" needs a second half: *which* narrow tests, when a change to a shared
164
164
  surface can break a downstream consumer. The matrix below is dependency-aware — domain → app →
165
165
  CLI — so a shared change verifies its consumers without recreating the full project check inside
166
- implement. **It augments narrow behavior tests; it never authorizes `bun run spur-check`,
167
- `bun run test`, or another full project check inside implement** — the pipeline's `test` hop owns
166
+ implement. **It augments narrow behavior tests; it never authorizes `spur self exec check`,
167
+ `spur self exec test`, or another full project check inside implement** — the pipeline's `test` hop owns
168
168
  that single full gate.
169
169
 
170
170
  **Worker iteration check order (task 1142 R3):**
@@ -192,10 +192,10 @@ Neither step takes the full project gate. The full gate is named only for the pi
192
192
  `test` hop (`task-pipeline.yaml` `${vars.qualityGateCmd}`).
193
193
  - **Mirrored surfaces: an edit lands on all of them.** When the change is one instance of a repeated
194
194
  pattern — the same wiring rule on two runbooks, a signature in both a generator and its generated
195
- `.d.mts`, a command chain in both `spur-check` and `spur-check-new` — grep for the siblings and
195
+ `.d.mts`, a command chain in both `spur-check` and `spur-check:full` — grep for the siblings and
196
196
  update each in this pass. Two H1-batch cycles (2026-10-08) were spent re-finding exactly this:
197
197
  task 1129 fixed the guard wiring on one runbook and left its sibling, and task 1127 changed
198
- `spur-check` while `spur-check-new`'s chain-parity assertion still expected the old chain.
198
+ `spur-check` while its own chain-parity assertion still expected the old chain.
199
199
 
200
200
  ## Behavior
201
201
 
@@ -42,7 +42,7 @@ contracts, §11 invariants).
42
42
  | `--scope <path>` | Path bound; no edit may land outside it. | working tree (recent changes) |
43
43
  | `--focus <api\|architect\|tests\|ui\|auto>` | Lens set; comma list allowed. | `auto` |
44
44
  | `--fix <none\|blockers-first\|all>` | Apply policy. | `none` |
45
- | `--check <cmd>` | Baseline and per-fix verification command. | project gate (`bun run spur-check` when present) |
45
+ | `--check <cmd>` | Baseline and per-fix verification command. | project gate (`spur self exec check` when bound) |
46
46
  | `--auto` | Skips **objective** gates only. | off |
47
47
  | free-text description | Steering for the lenses (e.g. "pagination consistency"). | — |
48
48
 
@@ -357,7 +357,7 @@ Verdict: PASS
357
357
  ```
358
358
 
359
359
  The per-requirement traceability table MUST use `| Req | Status | Evidence |` (exactly this header, no `R#`/`R`/`Requirement` variant — `Status` in column 2 — and no extra columns between Req and Status). The Acceptance Criteria table MUST use `| AC | Status | Evidence Type | Evidence |`.
360
- The answer carries no `Confidence:` line (F511, task 1207): model-asserted confidence is not verification — a verifier that can write a PASS can write `HIGH`. What the old level compressed now lives in the evidence cells themselves: cite fresh executable evidence and name residual gaps explicitly. Legacy answers that still carry a confidence line parse (the value is ignored); no lint code reads it and the artifact and recorded `## Testing` section carry no confidence value.
360
+ The answer MUST carry exactly one top-level `Confidence: HIGH|MEDIUM|LOW` line (ADR-141): the lint *derives* the level from your own rows and rejects a mismatch (`confidence-missing` / `-duplicate` / `-mismatch`), so state the level your evidence earns — `HIGH` needs every AC row MET on `test`/`command`, a citation-only row makes it `MEDIUM`. Full rule: [verdict-schema](references/verdict-schema.md).
361
361
  The answer MUST cite a source for external API/library claims in Requirement/AC evidence cells: a cell asserting a scoped-package (`@scope/name`), `node_modules/`, semver-version (`x.y.z`), or backticked function-call (`` `name(args)` ``) claim is rejected with `evidence-citation` unless the SAME cell carries a citation — a repo `path:line(-end)` (backticked or bare), the external named-origin form (@origin `path` line N), or a URL. Cross-cell references ("receipt above") do not count; marker-free receipts ("bun test 398 pass / 0 fail") need no citation.
362
362
  **MUST NOT:** place a `Severity` column between `Req` and `Status`. The parser tolerates variants
363
363
  as defense-in-depth; this contract is canonical.
@@ -83,7 +83,7 @@ verdict artifact so quality failures are not lost behind a requirements-only PAS
83
83
  Before declaring a task `done`, run this lightweight checklist. It catches the most common oversights that survive the formal pipeline gates:
84
84
 
85
85
  - [ ] Check receipt `.spur/run/<wbs>-check-receipt.json` reports `reuse: true` for the current
86
- digest via `spur task gate <wbs> status`; run `bun run spur-check` only when it reports stale or
86
+ digest via `spur task gate <wbs> status`; run `spur self exec check` only when it reports stale or
87
87
  missing (0940).
88
88
  - [ ] No `TODO` or `FIXME` without a linked task WBS.
89
89
  - [ ] `git status` shows only intentional changes (no debug artifacts, no temp files).
@@ -40,16 +40,29 @@ interface VerifyVerdict {
40
40
  }
41
41
  ```
42
42
 
43
- ## No asserted confidence (F511, task 1207)
44
-
45
- Verdict artifacts carry no `confidence` field and verify answers no `Confidence:` line. The
46
- 1068/1133 machinery that required, linted and coherence-checked a model-asserted
47
- `HIGH | MEDIUM | LOW` was retired: a verifier that can write a PASS can write `HIGH`, so the grade
48
- verifies nothing. What the level compressed belongs in the evidence cells — cite fresh executable
49
- evidence and name residual gaps explicitly. The done gate no longer denies a confidence-less PASS:
50
- it checks the proof digests, which are the part a hand-edited artifact cannot fake. The DERIVED
51
- confidence family is a different thing and stays: feature-verification receipts (ADR-131, 1196),
52
- the decision subsystem threshold, history-anatomy reading.
43
+ ## Answer confidence is derived and cross-checked (ADR-141, superseding F511 for answers)
44
+
45
+ A verify answer carries exactly one top-level `Confidence: HIGH|MEDIUM|LOW` line — conventionally
46
+ right after `Verdict:`, and legal anywhere at top level. The label is **not** a self-assessment: the
47
+ lint recomputes it from the answer's own rows and rejects a disagreement.
48
+
49
+ | Derived | When the answer's rows say so |
50
+ | --- | --- |
51
+ | `LOW` | the verdict is not PASS, or any requirement/AC row is PARTIAL/UNMET |
52
+ | `HIGH` | PASS, and every AC row is MET on executable evidence (`test`/`command`; compounds allowed) |
53
+ | `MEDIUM` | PASS with every AC MET, but at least one row rests on `static-ref`, `manual-review`, `llm-judge` or `N/A` |
54
+
55
+ Rejections (`spur task verdict --from-answer`, exit 1, no artifact): `confidence-missing`,
56
+ `confidence-duplicate`, `confidence-mismatch` — the last names both the stated and the derived level
57
+ plus the clause the rows turn on. Derivation lives once, in
58
+ `packages/app/src/services/answer-confidence.ts`; the review lane uses the same module for its own
59
+ dispositions.
60
+
61
+ Still retired and not revived by this: **verdict artifacts** carry no `confidence` field (the answer
62
+ stays the record of truth, and a test pins the field's absence), feature-verification receipts keep
63
+ no level (ADR-131, 1196), no operator `ackLowConfidence`-style var exists, and history-anatomy
64
+ findings carry no per-finding grade. A verifier that can write a PASS can still write a wrong
65
+ `HIGH` — which is exactly why the gate derives the level instead of trusting it.
53
66
 
54
67
  ## Compatibility alias: `scenario` row key
55
68
 
@@ -77,7 +77,7 @@ project's actual stack and scope. Invoked by `sp:spur-init` after scaffolding.
77
77
  routing Need keys — see `apps/cli/tests/fixtures/agents-md-portable-contract.ts`).
78
78
 
79
79
  **Done when:** no residual `{project-name}` / `{project-description}` in AGENTS.md; stack/build
80
- stubs filled or deliberately documented; `bun run lint` passes where applicable.
80
+ stubs filled or deliberately documented; `spur self exec lint` passes where applicable.
81
81
 
82
82
  ## drift-audit (§7)
83
83
 
@@ -115,7 +115,7 @@ token, deterministic).
115
115
  | Order | When evaluated | Probe | Signal | Redirect dispatch | Else |
116
116
  | --- | --- | --- | --- | --- | --- |
117
117
  | C1 | A1, A3, A5 (pre-implement / refine path) | `spur task check <wbs> --json` | Any **L3** finding on sections ∈ {Background, Requirements, Acceptance Criteria, Design, Plan} | Force `/sp:dev-refine <wbs> --auto` (**without** `--next` if already mid-refine; with `--next` only when status was backlog/todo and operator wants chain — default: keep `--next` for A1/A3) | continue |
118
- | C2 | A3, A5 after C1 clean | Cheap workspace health: `bun run lint` (or project lint) exit ≠ 0 **and** scope inferable from task Solution/Plan paths or default repo | lint/type failures | `/sp:dev-fixall` (optional `--scope` if single package known) | continue |
118
+ | C2 | A3, A5 after C1 clean | Cheap workspace health: `spur self exec lint` exit ≠ 0 **and** scope inferable from task Solution/Plan paths or default repo | lint/type failures | `/sp:dev-fixall` (optional `--scope` if single package known) | continue |
119
119
  | C3 | A5/A6 when Testing empty/N/A **and** verify would fail for missing tests — only if prior implement claims code exists | Coverage/test signal: `bun test` fail attributed to task paths OR explicit "insufficient tests" in prior verify verdict artifact `.spur/run/<wbs>-verdict.json` | test fail / coverage gap | `/sp:dev-unit <wbs> --auto` | continue |
120
120
  | C4 | A3/A5/A6 when operator or task tags mention rules, OR `spur rule run` last report dirty in `.spur/` if present | `spur rule run` (default project preset) non-zero with findings | rule findings | **HITL STOP** — print rule summary; suggest `/sp:rule-scan` or `rule-add`/`rule-refine` (do not auto-author rules) | continue |
121
121
  | C5 | A6 only | Existing `.spur/run/<wbs>-verdict.json` with FAIL and findings pointing at coverage | verdict artifact | `/sp:dev-unit <wbs>` then re-verify on next invocation (`--once` friendly) | `/sp:dev-verify …` |