@gobing-ai/spur 0.4.33 → 0.4.34
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.
- package/.claude-plugin/marketplace.json +1 -1
- package/config/config.global.yaml +1 -4
- package/config/decisions/task-pipeline.yaml +1 -29
- package/config/rules/boundary/sp-runtime-path.yaml +0 -2
- package/config/rules/strict/runtime-boundaries.yaml +2 -12
- package/config/rules/structure/protected-files.yaml +0 -3
- package/config/rules/surface/check-cli-surface.yaml +1 -2
- package/config/workflow-candidates.json +1 -1
- package/config/workflows/idea-pipeline.yaml +1 -1
- package/config/workflows/task-pipeline.yaml +53 -185
- package/package.json +1 -1
- package/plugins/sp/agents/super-reviewer.md +18 -60
- package/plugins/sp/commands/dev-fixall.md +0 -7
- package/plugins/sp/commands/dev-review.md +1 -1
- package/plugins/sp/commands/dev-run.md +8 -3
- package/plugins/sp/commands/dev-runall.md +7 -4
- package/plugins/sp/commands/dev-verify.md +0 -10
- package/plugins/sp/commands/dev-verifyall.md +0 -5
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/skills/code-implementation/SKILL.md +1 -3
- package/plugins/sp/skills/code-verification/SKILL.md +11 -41
- package/plugins/sp/skills/code-verification/references/verdict-schema.md +18 -119
- package/plugins/sp/skills/issue-finding/SKILL.md +1 -1
- package/plugins/sp/skills/next-router/references/routing-table.md +0 -7
- package/plugins/sp/skills/spec-decomposition/references/decomposition.md +1 -6
- package/plugins/sp/skills/spur-cli/references/decision.md +3 -6
- package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +0 -28
- package/plugins/sp/skills/spur-cli/references/tasks.md +3 -6
- package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +5 -12
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +2 -3
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +4 -4
- package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +4 -5
- package/plugins/sp/skills/spur-dev/references/execution-batch-report.md +9 -5
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +4 -5
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +1 -1
- package/plugins/sp/skills/spur-dev/references/execution-worktree-landing.md +34 -0
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +14 -1
- package/spur.js +1408 -4406
- package/web/_astro/{BoardApp.CuCuw0lw.js → BoardApp.BzY_krKQ.js} +1 -1
- package/web/_astro/{BoardApp.BGGDrfHl.js → BoardApp.CIImQFjG.js} +3 -3
- package/web/_astro/{TaskDetail.DWXct9_X.js → TaskDetail.c48Pnba6.js} +1 -1
- package/web/_astro/{arc.BxG3NS1o.js → arc.CpU6Cddr.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.BxaiM2Hv.js → architectureDiagram-3BPJPVTR.CaXT9ZEz.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.DJ3r6SdD.js → blockDiagram-GPEHLZMM.Cnv3IsW9.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.BkzpXBQs.js → c4Diagram-AAUBKEIU.VO_hjv9n.js} +1 -1
- package/web/_astro/channel.DrtdR7d_.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.DI7UanTc.js → chunk-2J33WTMH.BOunhbrU.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.C2uLhAlQ.js → chunk-4BX2VUAB.Brg-Gmb2.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.KwNI2kxL.js → chunk-55IACEB6.BqF9dxiC.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.CHZUthkg.js → chunk-727SXJPM.CEIGJZdc.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.DLr4QNJo.js → chunk-AQP2D5EJ.BxXI0bx9.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.B1G8WrnE.js → chunk-FMBD7UC4.CveXCF83.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.CzsA-SkD.js → chunk-ND2GUHAM.DwKjp403.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.DAvBQYli.js → chunk-QZHKN3VN.DgwjHrXx.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.Cddmz8Ze.js → classDiagram-4FO5ZUOK.BcVv8Qmo.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.Cddmz8Ze.js → classDiagram-v2-Q7XG4LA2.BcVv8Qmo.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.CKEu7KRX.js → cose-bilkent-S5V4N54A.28xfMBER.js} +1 -1
- package/web/_astro/{cynefin-OW5HDTMX.-B4Cy_Vl.js → cynefin-OW5HDTMX.BAFHBcJj.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.bLxFvI-t.js → dagre-BM42HDAG.DzR6wa9Z.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.DAHU0t5h.js → diagram-2AECGRRQ.IpFlr4yd.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.DFciwCNk.js → diagram-5GNKFQAL.DGNU2pOL.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.BvH0dGId.js → diagram-KO2AKTUF.D_wP6t4w.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.BgVlskRO.js → diagram-LMA3HP47.B0DMC97s.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.BpurMISo.js → diagram-OG6HWLK6.DQXmNEBs.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.SDj5bUMU.js → erDiagram-TEJ5UH35.BZ0VPjjp.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.Bm5U58FE.js → flowDiagram-I6XJVG4X.zu5gJs9Z.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.CnMnds77.js → ganttDiagram-6RSMTGT7.DYy6LDqD.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.BQUwwyWo.js → gitGraphDiagram-PVQCEYII.C6c_wPdO.js} +1 -1
- package/web/_astro/index.C4tUn4AU.css +1 -0
- package/web/_astro/{infoDiagram-5YYISTIA.BiSKdORH.js → infoDiagram-5YYISTIA.C3bQPQl8.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.Br69sBTI.js → ishikawaDiagram-YF4QCWOH.Cc1D58oG.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.C39WX1W8.js → journeyDiagram-JHISSGLW.CY51-lNM.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.DppWcbSX.js → kanban-definition-UN3LZRKU.D_3v92y6.js} +1 -1
- package/web/_astro/{linear.DeivTDuc.js → linear.C6BrJ38s.js} +1 -1
- package/web/_astro/{mermaid.core.Dixrjrnj.js → mermaid.core.DO9lF20B.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.BWIQ2MWG.js → mindmap-definition-RKZ34NQL.BMiM91P6.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.vvtHpfT7.js → pieDiagram-4H26LBE5.CcgIgRlR.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.9c-T6qCy.js → quadrantDiagram-W4KKPZXB.CM1CzrHl.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.9ZuRw-kn.js → requirementDiagram-4Y6WPE33.CQvQ1E8r.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.CTIWteEl.js → sankeyDiagram-5OEKKPKP.D-b1ONCV.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.DEvu4vLL.js → sequenceDiagram-3UESZ5HK.BQzFGYtH.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.Bxvsgk-_.js → stateDiagram-AJRCARHV.DiCukZ7I.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.CVuog5yY.js → stateDiagram-v2-BHNVJYJU.4Iut-DMk.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.CpPItB3E.js → timeline-definition-PNZ67QCA.BKQiLF24.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.C7eKaLRK.js → vennDiagram-CIIHVFJN.CyeSCofx.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.DWXHT_CW.js → wardleyDiagram-YWT4CUSO.B140ei48.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.DOsrNQOF.js → xychartDiagram-2RQKCTM6.DjPyVoO1.js} +1 -1
- package/web/index.html +2 -2
- package/config/rules/structure/scratch-evidence-pointer.yaml +0 -35
- package/web/_astro/channel.CYWRkoDI.js +0 -1
- package/web/_astro/index.CKtaGArK.css +0 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
description: Run a task — full pipeline (precheck→implement→test→review→approve→verify→record→done) or single-step (implement)
|
|
3
3
|
requires: [cli:spur, local-fs]
|
|
4
4
|
role: coder
|
|
5
|
-
argument-hint: "<wbs> [--mode <full|implement>] [--agent <inline|auto|name>] [--auto] [--next] [--wrap] [--continue] [--worktree [<name>]] [--no-summary]"
|
|
5
|
+
argument-hint: "<wbs> [--mode <full|implement>] [--agent <inline|auto|name>] [--auto] [--next] [--wrap] [--wrap-pr] [--continue] [--worktree [<name>]] [--no-summary]"
|
|
6
6
|
allowed-tools: ["Bash", "Read", "Write", "Edit", "Skill"]
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -19,7 +19,8 @@ Wraps the **sp:spur-dev** and **sp:code-implementation** skills.
|
|
|
19
19
|
| `--agent` `<inline\|auto\|name>` | Who runs the model-bearing stages. omit and explicit `--agent inline` resolve identically (task 0687): eligible stages dispatch once to a native subagent with host-session fallback (0508 eligibility); otherwise every stage executes in the invoking session. `auto` or a name keeps subprocess dispatch.. The opt-in `fleet` selector (0942) maps the run to `executor: 'fleet'` so `agent.run` stages dispatch through the fleet control plane (ADR-126) instead of a subprocess. | omit |
|
|
20
20
|
| `--auto` | Skip objective HITL confirmations. | off |
|
|
21
21
|
| `--next` | Chain-to-completion via the next-router. | off |
|
|
22
|
-
| `--wrap` | Run the wrap hop after the main step. The `--agent` selector is preserved into the `/sp:dev-wrap <wbs>` handoff when supplied; omission remains omission. The wrap hop is workflow-backed and reports its trigger-3 subprocess override. | off |
|
|
22
|
+
| `--wrap` | Run the wrap hop after the main step. The `--agent` selector is preserved into the `/sp:dev-wrap <wbs>` handoff when supplied; omission remains omission. The wrap hop is workflow-backed and reports its trigger-3 subprocess override. Mutually exclusive with `--wrap-pr`. | off |
|
|
23
|
+
| `--wrap-pr` | Run the wrap hop after the main step, commit close-out writes, push the worktree branch to remote origin, and open a Pull Request targeting the base ref (WT-PR). Mutually exclusive with `--wrap`. Full mode only; requires `--worktree` or a dedicated non-base branch. | off |
|
|
23
24
|
| `--continue` | Resume an interrupted task from its checkpoint. | off |
|
|
24
25
|
| `--worktree` `[<name>]` | Run the task pipeline in an isolated git worktree; FF-merge on success, retain on failure. Bare `--worktree` creates a fresh tree; `--worktree <name>` adopts an existing worktree by name/path/branch. Full mode only. | off |
|
|
25
26
|
| `--no-summary` | Skip the measured execution summary (per-stage time, wait, tool calls, total / non-cached tokens) printed after a full-mode run. | off (summary printed) |
|
|
@@ -28,7 +29,7 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
|
|
|
28
29
|
|
|
29
30
|
## Usage
|
|
30
31
|
|
|
31
|
-
/sp:dev-run <wbs> [--mode <full|implement>] [--agent <inline|auto|name>] [--auto] [--next] [--wrap] [--continue] [--worktree [<name>]] [--no-summary]
|
|
32
|
+
/sp:dev-run <wbs> [--mode <full|implement>] [--agent <inline|auto|name>] [--auto] [--next] [--wrap] [--wrap-pr] [--continue] [--worktree [<name>]] [--no-summary]
|
|
32
33
|
|
|
33
34
|
## Implementation
|
|
34
35
|
|
|
@@ -64,6 +65,10 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
|
|
|
64
65
|
`.spur/run/<wbs>-question.md` and exits 0 — the pipeline's `escalate` hop surfaces the question,
|
|
65
66
|
the operator answers via `spur workflow continue --answer-text`, and the guard appends the Q/A
|
|
66
67
|
pair to this transcript before re-entering implement, where the agent reads it and resumes.
|
|
68
|
+
- `--wrap-pr` (run wrap hop, push branch, and create PR) — runs the wrap hop on `$BRANCH`, commits close-out
|
|
69
|
+
writes, pushes the branch to `origin`, and opens a Pull Request targeting `$BASE_REF`
|
|
70
|
+
(`WT-PR`, execution-worktree-landing.md). Mutually exclusive with `--wrap`: passing both exits 2. Full mode only;
|
|
71
|
+
requires `--worktree` or execution on a dedicated non-base branch (refuses execution directly on `main`).
|
|
67
72
|
|
|
68
73
|
`--worktree` `[<name>]` (run the task's pipeline in an isolated git worktree — FF-merge onto the
|
|
69
74
|
base ref on full success, retain intact on any failure/halt/non-FF; bare form creates a fresh tree,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
description: Run a batch of tasks through their pipelines in dependency-correct order — resolve a set, topo-sort, run each via task-pipeline.yaml, emit a batch report
|
|
3
3
|
requires: [cli:spur, local-fs]
|
|
4
4
|
role: planner
|
|
5
|
-
argument-hint: "--tasks <selector> [--feature <id>] [--mode <sequential|parallel|auto>] [--concurrency <n>] [--keep-going] [--auto] [--agent <inline|auto|name>] [--json] [--wrap] [--next] [--continue] [--worktree [<name>]] [--no-summary] [--defer-gate]"
|
|
5
|
+
argument-hint: "--tasks <selector> [--feature <id>] [--mode <sequential|parallel|auto>] [--concurrency <n>] [--keep-going] [--auto] [--agent <inline|auto|name>] [--json] [--wrap] [--wrap-pr] [--next] [--continue] [--worktree [<name>]] [--no-summary] [--defer-gate]"
|
|
6
6
|
allowed-tools: ["Bash", "Read", "Skill"]
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -21,7 +21,8 @@ Wraps the **sp:spur-dev** skill.
|
|
|
21
21
|
| `--auto` | Skip objective HITL gates, and treat the batch as unattended: `--auto` implies `--keep-going` (a failed task is `failed`, its in-batch dependents `skipped`, independents keep running). | off |
|
|
22
22
|
| `--agent` `<inline\|auto\|name>` | Who runs each task's pipeline stages. Interactive sequential omit/`inline` uses the host-session driver with unified inline semantics (task 0687 — see below). `auto`, a name, parallel mode, and headless invocation use subprocesses; `auto` is resolved **once per batch** — the first run's implement `result.executor` is pinned for every later task, and only a `failed-agent` ending re-resolves it, exactly once (1318 R2/R3). The opt-in `fleet` selector (0942) maps each task run to `executor: 'fleet'` so `agent.run` stages dispatch through the fleet control plane (ADR-126) instead of a subprocess. | omit |
|
|
23
23
|
| `--json` | Emit structured JSON. | off |
|
|
24
|
-
| `--wrap` | Run the wrap hop **once for the batch** over the `done` subset only (Step 6 of execution-batch.md): `vars.feature` is passed only when every frozen task is `done`/`cancelled`; an empty done subset skips the wrap with a reason. The `--agent` selector is preserved into the `/sp:dev-wrap` handoff when supplied; omission remains omission. | off |
|
|
24
|
+
| `--wrap` | Run the wrap hop **once for the batch** over the `done` subset only (Step 6 of execution-batch.md): `vars.feature` is passed only when every frozen task is `done`/`cancelled`; an empty done subset skips the wrap with a reason. The `--agent` selector is preserved into the `/sp:dev-wrap` handoff when supplied; omission remains omission. Mutually exclusive with `--wrap-pr`. | off |
|
|
25
|
+
| `--wrap-pr` | Run the wrap hop **once for the batch** over the `done` subset, commit close-out writes, push the worktree branch to remote origin, and open a Pull Request targeting the base ref (WT-PR). Mutually exclusive with `--wrap`. Requires `--worktree` or a dedicated non-base branch. | off |
|
|
25
26
|
| `--next` | Chain-to-completion via the next-router. | off |
|
|
26
27
|
| `--continue` | Resume an interrupted batch. | off |
|
|
27
28
|
| `--worktree` `[<name>]` | Run the batch in an isolated git worktree; FF-merge on success, retain on failure. Bare `--worktree` creates a fresh tree; `--worktree <name>` adopts an existing worktree by name/path/branch. | off |
|
|
@@ -34,7 +35,7 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
|
|
|
34
35
|
## Usage
|
|
35
36
|
|
|
36
37
|
```
|
|
37
|
-
/sp:dev-runall --tasks <selector> [--feature <id>] [--mode <sequential|parallel|auto>] [--concurrency <n>] [--keep-going] [--auto] [--agent <inline|auto|name>] [--json] [--wrap] [--next] [--continue] [--worktree [<name>]] [--no-summary] [--defer-gate]
|
|
38
|
+
/sp:dev-runall --tasks <selector> [--feature <id>] [--mode <sequential|parallel|auto>] [--concurrency <n>] [--keep-going] [--auto] [--agent <inline|auto|name>] [--json] [--wrap] [--wrap-pr] [--next] [--continue] [--worktree [<name>]] [--no-summary] [--defer-gate]
|
|
38
39
|
```
|
|
39
40
|
|
|
40
41
|
Flags: `--tasks <selector>` (required — explicit WBS list, status pseudo-list, `feature:<id>`,
|
|
@@ -57,7 +58,9 @@ unattended, so it also implies `--keep-going`), `--agent <inline|auto|name>`
|
|
|
57
58
|
`auto` or a name is merged into each per-task `vars.agent` and `vars.implementAgent`; `fleet` maps each task run to `executor: 'fleet'` instead (fleet dispatch, 0942); parallel mode
|
|
58
59
|
retains isolated subprocesses, ADR-047), `--json` (emit the
|
|
59
60
|
report as JSON), `--wrap` (trigger
|
|
60
|
-
`wrapup-pipeline.yaml` after the batch completes), `--
|
|
61
|
+
`wrapup-pipeline.yaml` after the batch completes; mutually exclusive with `--wrap-pr`), `--wrap-pr`
|
|
62
|
+
(run batch wrap hop, commit close-out writes, push worktree branch to remote origin, and open a Pull Request
|
|
63
|
+
targeting the base ref; mutually exclusive with `--wrap`), `--next`
|
|
61
64
|
(chain each task to terminal status, then run the wrap hop **once for the batch** — see below),
|
|
62
65
|
`--worktree` `[<name>]` (run the batch in an isolated git worktree —
|
|
63
66
|
FF-merge onto the base ref on full success, retain intact on any failure/halt/non-FF; bare form
|
|
@@ -41,16 +41,6 @@ See `sp:code-verification` § Shippable readiness gate.
|
|
|
41
41
|
|
|
42
42
|
- Apply the [inline-default execution-surface contract](../skills/spur-dev/references/cross-cutting.md#inline-default-execution-surface).
|
|
43
43
|
- `Skill(skill="sp:code-verification", args="verify $ARGUMENTS")`
|
|
44
|
-
- **Residual sweep (F96 R1, post-record since 0987):** after `task verdict` derives
|
|
45
|
-
`.spur/run/<wbs>-verdict.json` and `spur task record` has flipped the verdict-proven R/AC boxes,
|
|
46
|
-
run `spur task residual <wbs> scan` + `fold` (observe-only; folds the verdict's `residual-sweep` check,
|
|
47
|
-
PASS → PARTIAL when a blocking residual exists) — under every `--fix` mode — then, only on a
|
|
48
|
-
downgrade, re-run `spur task record <wbs> --verdict-file .spur/run/<wbs>-verdict.json` so Testing
|
|
49
|
-
carries the final verdict. Same order as the pipeline `done` state's record close (0983): scanning before
|
|
50
|
-
record reads unticked-but-proven boxes and folds a clean PASS to PARTIAL. When the task reaches
|
|
51
|
-
`done` through `--next`, run `spur task residual <wbs> settle` (best-effort). On a folded PARTIAL: the bounded remediation loop has
|
|
52
|
-
already run — a residual-failed task is routed to router C6 (HITL STOP), never another
|
|
53
|
-
automatic fix loop.
|
|
54
44
|
|
|
55
45
|
**Flags:**
|
|
56
46
|
|
|
@@ -73,8 +73,3 @@ Without `--fix all`, shippable is not evaluated (optional note: use `--fix all`
|
|
|
73
73
|
- Batch orchestration: `Skill(skill="sp:spur-dev", args="verifyall $ARGUMENTS")`
|
|
74
74
|
- Per-task verification (inner): `Skill(skill="sp:code-verification", args="verify <wbs> $SHARED_FLAGS")`
|
|
75
75
|
- Shippable gate: once after the batch (same skill § Shippable readiness gate)
|
|
76
|
-
- **Residual sweep (F96 R1, per task, post-record since 0987):** same contract as
|
|
77
|
-
`/sp:dev-verify` — after each task's verdict artifact is derived and `spur task record` has
|
|
78
|
-
flipped its verdict-proven boxes, run `spur task residual <wbs> scan` + `fold` (under every
|
|
79
|
-
`--fix` mode), and re-record only on a downgrade; on reaching `done` via `--next`, run
|
|
80
|
-
`spur task residual <wbs> settle`.
|
package/plugins/sp/plugin.json
CHANGED
|
@@ -84,9 +84,7 @@ not have and work you were not asked to do.
|
|
|
84
84
|
prerequisite. If the target genuinely cannot proceed without it, stop and say so — a blocked task
|
|
85
85
|
is a cheap finding; a two-task diff costs the reverts.
|
|
86
86
|
- **Flip the target's `## Plan` boxes as each step completes.** They are this pass's progress
|
|
87
|
-
ledger
|
|
88
|
-
downgrades the verdict to PARTIAL and closes the `done` gate
|
|
89
|
-
(`docs/design/task-residual-sweep.md`), which costs a remediation cycle and a manual re-record.
|
|
87
|
+
ledger.
|
|
90
88
|
Leave every finished step ticked through `spur task update <wbs> --section Plan --from-file`, and
|
|
91
89
|
if you deliberately skipped one, say so in the Solution change map.
|
|
92
90
|
|
|
@@ -161,12 +161,10 @@ Evidence: @gobing-ai/ts-llm-jsonl-importer `src/mappers.ts` line 481 — omp cal
|
|
|
161
161
|
```
|
|
162
162
|
|
|
163
163
|
Use this form ONLY when the evidence genuinely lives outside `spur`'s working tree (a `@gobing-ai/ts-*`
|
|
164
|
-
source under `~/xprojects/ts-libs`, or a gitignored `.spur/run/**` artifact).
|
|
165
|
-
|
|
166
|
-
that lives in this repo — in-repo evidence MUST use the repo-relative backtick form
|
|
167
|
-
`` `path:line` `` / `` `path:start-end` ``, and citing it in the external form still reports (R2).
|
|
164
|
+
source under `~/xprojects/ts-libs`, or a gitignored `.spur/run/**` artifact). In-repo evidence uses the
|
|
165
|
+
repo-relative backtick form `` `path:line` `` / `` `path:start-end` ``.
|
|
168
166
|
|
|
169
|
-
**Concrete anchors
|
|
167
|
+
**Concrete anchors:** existing `file:line`s only, never globs or basenames, always repo-root-relative (`references/verdict-schema.md`).
|
|
170
168
|
|
|
171
169
|
### Step 5 — Acceptance Criteria guard
|
|
172
170
|
|
|
@@ -275,7 +273,7 @@ completion gate (`PARTIAL`/`FAIL` route the pipeline to `failed`).
|
|
|
275
273
|
Assemble the evidence and **emit the canonical verdict artifact** — verification writes no task
|
|
276
274
|
section (F92 0593 R1). Under the pipeline **you** write
|
|
277
275
|
`.spur/run/<wbs>-verify-answer.txt` (0726 R3: host `expectFile`, never captured/overwritten); a
|
|
278
|
-
deterministic shell step
|
|
276
|
+
deterministic shell step derives `.spur/run/<wbs>-verdict.json`, and `record`
|
|
279
277
|
transcribes `## Testing` from it.
|
|
280
278
|
|
|
281
279
|
**Standalone** (`/sp:dev-verify` outside the pipeline), write the artifact yourself, then invoke
|
|
@@ -284,40 +282,14 @@ the deterministic Testing writer `spur task record` (section authorship never ha
|
|
|
284
282
|
```bash
|
|
285
283
|
# write .spur/run/<wbs>-verdict.json (shape in references/verdict-schema.md), then:
|
|
286
284
|
spur task record <wbs> --verdict-file .spur/run/<wbs>-verdict.json # renders ## Testing, flips proven boxes
|
|
287
|
-
# F96 residual sweep (observe-only): scan + fold AFTER record, under every --fix mode (0987).
|
|
288
|
-
spur task residual <wbs> scan
|
|
289
|
-
spur task residual <wbs> fold
|
|
290
|
-
# Downgrade only: re-record so Testing carries the final (folded) verdict.
|
|
291
|
-
[ "$(jq -r .verdict .spur/run/<wbs>-verdict.json)" = PASS ] \
|
|
292
|
-
|| spur task record <wbs> --verdict-file .spur/run/<wbs>-verdict.json
|
|
293
285
|
```
|
|
294
286
|
|
|
295
|
-
> **Residual fold (F96).** `scan` reads `.spur/run/` artifacts and the post-record task file and
|
|
296
|
-
> writes `residuals.json` + `residual-report.md`; `fold` rewrites the verdict artifact's
|
|
297
|
-
> `residual-sweep` check in place (PASS → PARTIAL when a blocking residual exists), and the
|
|
298
|
-
> downgrade-only re-record transcribes it — a manual verify cannot certify what the pipeline would
|
|
299
|
-
> reject. The sweep runs after `record` (same order as the pipeline, 0983/0987): before it, a
|
|
300
|
-
> verdict-proven box is still unticked and a clean PASS would fold to PARTIAL. The sweep is the
|
|
301
|
-
> `spur task residual` verb (no plugin script to resolve). When the task reaches `done` through
|
|
302
|
-
> `--next`, run `spur task residual <wbs> settle` (files the follow-up task; best-effort).
|
|
303
|
-
|
|
304
287
|
> **Corrections: the answer file is the source of truth.** `spur task record` re-transcribes
|
|
305
288
|
> `## Testing` from the verdict artifact — direct `--section Testing` writes are futile. Fix
|
|
306
289
|
> `.spur/run/<wbs>-verify-answer.txt` → `spur task verdict <wbs> --from-answer <file>` → re-record.
|
|
307
290
|
|
|
308
|
-
> **
|
|
309
|
-
>
|
|
310
|
-
> (`Scenario: <title>` / `AC-N` keys with MET status), **copy those rows into the new artifact**
|
|
311
|
-
> keyed the same way — record re-transcribes `## Testing` wholesale, so a fresh artifact keyed by
|
|
312
|
-
> bare `R1`-style ids drops the scenario keys `spur feature check` needs for satisfaction
|
|
313
|
-
> (`L4.scenario-unverified` regresses; 0921/D63). Since 0936, `record` warns on stderr (exit 0)
|
|
314
|
-
> for each dropped MET-matched scenario key and when the new rows match no feature scenario —
|
|
315
|
-
> treat those warnings as a re-key instruction, not noise.
|
|
316
|
-
|
|
317
|
-
> **Keying rule for feature-linked tasks (1086/1089 re-audits).** Key AC rows by the exact feature
|
|
318
|
-
> scenario title (`R1 — …`): feature `Scenario:` titles are declared identities and satisfy L4
|
|
319
|
-
> scenario matching directly. Bare `AC1` fails `ac-identity` on Gherkin AC sections, and checklist
|
|
320
|
-
> labels truncate at the first colon (a `(req: …)` suffix), so the task's own AC title may not resolve.
|
|
291
|
+
> **Keying rule for feature-linked tasks.** Key AC rows by the exact feature scenario title
|
|
292
|
+
> (`R1 — …`) or `AC-N`, so `record` can tick the aliased AC line.
|
|
321
293
|
|
|
322
294
|
> **Do not write `## Review` directly, ever.** The `## Review` section is owned by the
|
|
323
295
|
> `review` coordinator (`/sp:dev-review` → `sp:super-reviewer`), which merges
|
|
@@ -358,20 +330,18 @@ Verdict: PASS
|
|
|
358
330
|
```
|
|
359
331
|
|
|
360
332
|
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 |`.
|
|
361
|
-
|
|
362
|
-
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.
|
|
333
|
+
Cite a source for external API/library claims in the SAME evidence cell (repo `path:line`, the external named-origin form, or a URL) — reviewer-enforced, not linted.
|
|
363
334
|
**MUST NOT:** place a `Severity` column between `Req` and `Status`. The parser tolerates variants
|
|
364
335
|
as defense-in-depth; this contract is canonical.
|
|
365
336
|
|
|
366
337
|
Under the pipeline, the verifier owns the answer file `.spur/run/<wbs>-verify-answer.txt` (0726
|
|
367
338
|
R3): `Verdict: PARTIAL` first, append one row at a time, replace the verdict line only when all
|
|
368
|
-
rows are certified — interruptions leave
|
|
369
|
-
Host: `spur task verdict --from-answer`
|
|
370
|
-
`spur task check` (R9). Vocabularies
|
|
371
|
-
rejection classes, and the AC identity rule: `references/verdict-schema.md`. Sections follow the
|
|
339
|
+
rows are certified — interruptions leave usable partial rows; retries fill only missing IDs.
|
|
340
|
+
Host: `spur task verdict --from-answer` derives the verdict from the answer file, then runs
|
|
341
|
+
`spur task check` (R9). Vocabularies and the AC identity rule: `references/verdict-schema.md`. Sections follow the
|
|
372
342
|
Step 10 contract.
|
|
373
343
|
|
|
374
|
-
**Standalone** (outside the pipeline — no host
|
|
344
|
+
**Standalone** (outside the pipeline — no host derive step), write the answer file and
|
|
375
345
|
artifact yourself; shape and field-by-field contract in
|
|
376
346
|
[references/verdict-schema.md](references/verdict-schema.md):
|
|
377
347
|
|
|
@@ -40,38 +40,6 @@ interface VerifyVerdict {
|
|
|
40
40
|
}
|
|
41
41
|
```
|
|
42
42
|
|
|
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.
|
|
66
|
-
|
|
67
|
-
**A review run carries two answer artifacts, one `Confidence:` line each (1254).** The `## Review`
|
|
68
|
-
section states the disposition-derived level (`deriveReviewConfidence`); the captured answer handed
|
|
69
|
-
to `spur task verdict --from-answer` states the evidence-derived level (`deriveVerifyConfidence`)
|
|
70
|
-
under the table above and carries exactly one `Confidence:` line. The two legitimately disagree — a
|
|
71
|
-
PASS with executable AC and one carried P4 is section `MEDIUM`, answer `HIGH` — so the captured
|
|
72
|
-
answer must not repeat the section's line (`confidence-duplicate` rejects the whole answer). The
|
|
73
|
-
review stage's prompt owns that instruction; this schema owns the shape it must produce.
|
|
74
|
-
|
|
75
43
|
## Compatibility alias: `scenario` row key
|
|
76
44
|
|
|
77
45
|
Task 0410 hardened the verdict reader. Producers SHOULD use the canonical `id` field for every
|
|
@@ -81,17 +49,7 @@ as a compatibility alias for the row identifier, with these rules:
|
|
|
81
49
|
- Row with `id` only → canonical; accepted as-is.
|
|
82
50
|
- Row with `scenario` only → accepted; normalized to `{ id: scenario, … }`.
|
|
83
51
|
- Row with both `id` and `scenario` where they are EQUAL → `id` is authoritative; accepted.
|
|
84
|
-
- Row with both `id` and `scenario` where they DIFFER or
|
|
85
|
-
(conflict); the rejected row
|
|
86
|
-
count and invalid fields surface as a bounded `L4.malformed-verdict-artifact` warning naming the
|
|
87
|
-
task WBS and artifact path.
|
|
88
|
-
- Row missing both `id` and `scenario`, or missing `status`, or not an object → rejected and warned.
|
|
89
|
-
|
|
90
|
-
Empty `requirements` / `acceptanceCriteria` arrays are valid and produce no warning. The required
|
|
91
|
-
`requirements` array being absent, either coverage field being a non-array value, a missing artifact,
|
|
92
|
-
malformed JSON, and a non-object JSON root are distinct diagnostic outcomes. Each emits one bounded
|
|
93
|
-
`L4.malformed-verdict-artifact` warning per task/artifact whose message names the failure mode;
|
|
94
|
-
optional `acceptanceCriteria` may remain absent.
|
|
52
|
+
- Row with both `id` and `scenario` where they DIFFER, or a row missing both → ignored.
|
|
95
53
|
|
|
96
54
|
Canonical producers and docs continue to use `id`. The `scenario` alias exists so older or
|
|
97
55
|
third-party verdict emitters keyed on scenario titles are not silently dropped.
|
|
@@ -144,65 +102,28 @@ For answer files, emit a matching parseable table:
|
|
|
144
102
|
|
|
145
103
|
**Authoring contract under the pipeline (0726 R3).** The verifier owns the answer file: write
|
|
146
104
|
`Verdict: PARTIAL` first, append one complete row at a time, and replace the first verdict line only
|
|
147
|
-
after every row is certified. `spur task verdict --from-answer`
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
`
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
by a bare checklist ordinal (`AC1`) passes the `spur task verdict` answer lint — it resolves to the task's AC
|
|
161
|
-
checklist label — but `feature-check.rowMatchesScenario` credits a linked feature scenario only by the
|
|
162
|
-
scenario's normalized title or its `AC-N` ordinal alias. Such a row therefore carries a PASS verdict
|
|
163
|
-
while crediting no scenario, and the feature's `verifying → done` gate denies with
|
|
164
|
-
`L4.scenario-unverified` / `L4.verdict-rows-match-no-scenario`. When the task has a linked feature,
|
|
165
|
-
key each AC row `AC-N` (1-based scenario ordinal, hyphenated) or by the exact scenario title.
|
|
166
|
-
A scenario-keyed row (`R3 — <title>`) ticks the task AC box whose line aliases that scenario
|
|
167
|
-
(`- [ ] AC1 — R3 — <title>`) during `spur task record` (0996); a scenario key no AC line aliases
|
|
168
|
-
ticks nothing, so alias every graduated scenario on its AC line.
|
|
169
|
-
|
|
170
|
-
**Concrete anchors only (task 0804 R9).** An evidence anchor must be a concrete existing `file:line`
|
|
171
|
-
(or `file:start-end`) path. A glob or directory summary (`src/services/*.ts`, `the retry
|
|
172
|
-
classifiers in task-pipeline.yaml`) is not an anchor: expand it into the specific cited files/ranges
|
|
173
|
-
the run actually verified. Since 0804 R9 the checker ignores complete parsed citation spans before
|
|
174
|
-
scanning for subjects, so a citation's filename (including snake_case paths) can never become a
|
|
175
|
-
false subject — a real absent symbol, nonexistent file, or invalid range still reports.
|
|
176
|
-
|
|
177
|
-
## Basename-only anchors are unresolved anchors (task 1110 R1)
|
|
178
|
-
|
|
179
|
-
`spur task verdict --from-answer` accepts the citation *shape*, but the `--as done` gate resolves
|
|
180
|
-
every Testing/Solution anchor against the repo root. A basename citation — `decision-events.ts:83`,
|
|
181
|
-
`task.test.ts:42` — reports `L4.anchor-unresolved` at **error** and blocks
|
|
182
|
-
`spur task update <wbs> done`, because the gate cannot tell which file the row meant. Write the
|
|
183
|
-
repo-root-relative form from the first pass:
|
|
105
|
+
after every row is certified. `spur task verdict --from-answer` derives the verdict from that file;
|
|
106
|
+
nothing lints the rows, so their accuracy is the verifier's responsibility. Vocabularies: status
|
|
107
|
+
`MET | PARTIAL | UNMET` (`N/A` additionally allowed for AC); evidence type `test | command |
|
|
108
|
+
static-ref | manual-review | llm-judge | n/a`, or a `+` compound. Interrupted runs keep the rows
|
|
109
|
+
already written and complete only the missing IDs on retry.
|
|
110
|
+
|
|
111
|
+
**Key AC rows so `record` can tick them.** A scenario-keyed row (`R3 — <title>`, `AC-N`, or the exact
|
|
112
|
+
scenario title) ticks the task AC box whose line aliases that scenario (`- [ ] AC1 — R3 — <title>`)
|
|
113
|
+
during `spur task record` (0996); a key no AC line aliases ticks nothing.
|
|
114
|
+
|
|
115
|
+
**Concrete anchors only.** Cite a concrete existing repo-root-relative `file:line` (or
|
|
116
|
+
`file:start-end`), never a glob, directory summary or basename. Nothing resolves anchors
|
|
117
|
+
mechanically — a reviewer who cannot open the cited line treats the row as unproven.
|
|
184
118
|
|
|
185
119
|
- Right: `packages/app/src/decision/decision-events.ts:83`, `apps/cli/tests/commands/task/verdict.test.ts:42`
|
|
186
120
|
- Wrong: `decision-events.ts:83`, `../services/foo.ts:12`, `@gobing-ai/ts-x/src/persistence.ts:108`
|
|
187
121
|
(a scoped package is never repo-relative — use the external named-origin form below)
|
|
188
122
|
|
|
189
|
-
The pipeline's implement stage also runs a scoped `spur task migrate-anchors --wbs <wbs>` pass
|
|
190
|
-
before the proof capture (task 1109), but it qualifies **unique** basenames only: an ambiguous
|
|
191
|
-
basename (two tracked files share it) is reported and left untouched, and line drift and
|
|
192
|
-
`L4.anchor-subject-mismatch` are never repaired by that pass — those remain the author's rows.
|
|
193
|
-
|
|
194
|
-
A **workspace-relative** path fails the same way, and is the easier mistake to make because the
|
|
195
|
-
command it came from is real. `(cd apps/cli && bun test tests/commands/builder/pr.test.ts)` is the
|
|
196
|
-
right way to run the suite, but `tests/commands/builder/pr.test.ts` does not resolve from the repo
|
|
197
|
-
root, so the AC-coverage guard reports `missing: <AC> — <path>` and refuses `done` (observed
|
|
198
|
-
2026-10-16, task 1215 — the repair was a fresh verify pass over the whole answer). Cite both halves:
|
|
199
|
-
the workspace-rooted command you ran, then the repo-root-relative anchor of the file it names
|
|
200
|
-
(`apps/cli/tests/commands/builder/pr.test.ts`). One anchor per cited file per cell is enough.
|
|
201
|
-
|
|
202
123
|
## Source citations for external claims (task 1070)
|
|
203
124
|
|
|
204
125
|
A Requirement/AC evidence cell that asserts an external API/library claim must carry a verifiable
|
|
205
|
-
citation in the SAME cell
|
|
126
|
+
citation in the SAME cell. Nothing machine-checks this — the reviewer enforces it.
|
|
206
127
|
|
|
207
128
|
- Claim markers (closed set): a scoped-package mention (`@scope/name`), a `node_modules/` reference,
|
|
208
129
|
a semver version claim (`x.y.z`), or a backticked function-call-shaped token (`` `name(args)` ``).
|
|
@@ -212,27 +133,6 @@ citation in the SAME cell, or lint rejects the row with `evidence-citation` (blo
|
|
|
212
133
|
- The rule is cell-local: a citation in another row or a "receipt above" cross-reference does not
|
|
213
134
|
satisfy it. Marker-free receipts (test counts, reviewed-log notes) need no citation. The check is
|
|
214
135
|
presence-only — which citation proves which claim is not deterministically decidable.
|
|
215
|
-
- The same two predicates (`hasClaimMarker` / `hasCitationForm` in
|
|
216
|
-
`packages/app/src/services/verify-answer-lint.ts`) gate the review report's findings table through
|
|
217
|
-
`spur task residual <wbs> review-gate` as the blocking `review-contract` category — one definition of
|
|
218
|
-
"external claim" and one set of accepted citation forms for both paths.
|
|
219
|
-
|
|
220
|
-
## Hedged evidence is rejected on MET rows
|
|
221
|
-
|
|
222
|
-
A MET row asserts the requirement is satisfied; evidence that hedges ("the guard likely prevents
|
|
223
|
-
the leak") contradicts the assertion the row is making. The lint rejects such rows with
|
|
224
|
-
`evidence-hedged`, naming the detected phrase, with two remedies: state the deterministic fact
|
|
225
|
-
with a concrete anchor, or downgrade the row to PARTIAL (which is what suspected-but-unproven
|
|
226
|
-
behavior actually is).
|
|
227
|
-
|
|
228
|
-
- Detected phrases (closed set, word-anchored, case-insensitive): `likely`, `unlikely`,
|
|
229
|
-
`probably`, `presumably`, `apparently`, `seems/seeming/seemingly to`, `appears to`. Modal verbs
|
|
230
|
-
(`might`/`may`/`could`/`should`) are deliberately out of set — they are constant in remediation
|
|
231
|
-
prose and would drown the signal.
|
|
232
|
-
- Only MET rows are scanned. Hedging a gap in an UNMET row ("the stale path likely still loads
|
|
233
|
-
the old bundle") is honest reporting and stays clean.
|
|
234
|
-
- Citation spans are stripped before scanning, so a filename or test name containing a hedge
|
|
235
|
-
word (`likely-match.test.ts`) cannot fire.
|
|
236
136
|
|
|
237
137
|
## Checks evidence
|
|
238
138
|
|
|
@@ -245,14 +145,13 @@ Wave C verification can emit the following additive `checks[]` rows:
|
|
|
245
145
|
| `evidence-rule-pass` | All behavior-bearing AC rows had executable evidence or were explicitly non-behavioral. |
|
|
246
146
|
| `evidence-rule-failed` | One or more MET behavior-bearing AC rows lacked `test` / `command` evidence and were downgraded to PARTIAL. |
|
|
247
147
|
| `cli-golden-path-present` | CLI-surface tasks supplied, or failed to supply, one golden-path command evidence row. |
|
|
248
|
-
| `residual-sweep` | Post-verdict residual scan (F96): `fail` when blocking leftovers exist (P1–P3 findings, added diff markers, unchecked boxes); evidence lists blocking/deferrable/advisory/housekeeping counts plus blocking and deferrable item ids. A `fail` downgrades an otherwise-PASS verdict to PARTIAL via the fold step. |
|
|
249
148
|
|
|
250
149
|
## How the gate reads it
|
|
251
150
|
|
|
252
151
|
In `task-pipeline.yaml` the `review` state writes this artifact: `spur task verdict <wbs>
|
|
253
|
-
--from-answer`
|
|
254
|
-
writes `.spur/run/<wbs>-review.status` = PASS only when the typed verdict is PASS
|
|
255
|
-
`verdict` is PASS (`jq -r '.verdict // empty'`)
|
|
152
|
+
--from-answer` derives `.spur/run/<wbs>-verdict.json` from the review answer. A fold step then
|
|
153
|
+
writes `.spur/run/<wbs>-review.status` = PASS only when the typed verdict is PASS and the artifact's
|
|
154
|
+
own `verdict` is PASS (`jq -r '.verdict // empty'`).
|
|
256
155
|
The `review → done` guard reads that status **and** the approval decision point's token:
|
|
257
156
|
|
|
258
157
|
```yaml
|
|
@@ -316,7 +316,7 @@ spur task check <wbs> --json
|
|
|
316
316
|
```
|
|
317
317
|
|
|
318
318
|
Must return `pass: true` with 0 errors. Warnings may be acceptable on meta tasks
|
|
319
|
-
(e.g. `
|
|
319
|
+
(e.g. `uncovered-task-scenario`).
|
|
320
320
|
|
|
321
321
|
## Output
|
|
322
322
|
|
|
@@ -119,13 +119,6 @@ token, deterministic).
|
|
|
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 …` |
|
|
122
|
-
| C6 | A4/A5 | `.spur/run/<wbs>-verdict.json` has a failing (PARTIAL/FAIL) `residual-sweep` check — residual blockers survived the pipeline sweep (F96) | folded verdict artifact | **HITL STOP** — print `.spur/run/<wbs>-residual-report.md` and the recovery command `/sp:dev-run <wbs>`; never auto-dispatch a fix (repeating the loop unattended burns quota without new information) | continue |
|
|
123
|
-
|
|
124
|
-
**C-row precedence note (F96):** C6 outranks C2/C3/C5 for the same task — a residual-sweep failure
|
|
125
|
-
means the workspace holds unfinished task residue, so fixall/unit reruns would either clean it
|
|
126
|
-
unintentionally or re-certify a folded verdict. C6 fires before any fix/unit dispatch; recovery is
|
|
127
|
-
the operator re-running the pipeline (`/sp:dev-run <wbs>`), which re-enters the normal
|
|
128
|
-
gate ⇄ remediate budget.
|
|
129
122
|
|
|
130
123
|
**Explicit non-probes in v1:** no freeform chat history; no always-on full `bun run test` for every
|
|
131
124
|
call; no git dirtiness as a route (optional advisory print only).
|
|
@@ -562,12 +562,7 @@ schema before emitting.
|
|
|
562
562
|
|
|
563
563
|
**Pass the deterministic task check.** Each `acceptance_criteria` bullet must be an exact feature
|
|
564
564
|
scenario title (L4.uncovered-task-scenario); add task-local checks as prose after the bullets, not
|
|
565
|
-
as extra bullets.
|
|
566
|
-
`capstone` as standalone words in any case (L4.gate-language) — dotted action kinds such as
|
|
567
|
-
`hitl.confirm` are fine, a bare `hitl` count is not; ambiguous words (`approval`, `approved`,
|
|
568
|
-
`merged`) warn only with a gating cue (`until`, `after`, `once`, `before`, `pending`, `blocked`,
|
|
569
|
-
`wait for`, `requires`) in the same sentence, so plain composition prose stays silent — say
|
|
570
|
-
"operator answer" / "accepted" instead, and keep enum values out of that list too.
|
|
565
|
+
as extra bullets.
|
|
571
566
|
|
|
572
567
|
**The order sidecar.** Also emit the private task-order sidecar at
|
|
573
568
|
`.spur/run/<runId>-idea-task-order.json`: a JSON array (one entry per batch item) of
|
|
@@ -25,7 +25,7 @@ Decisions resolve first-wins across three layers:
|
|
|
25
25
|
| `registered` | folders listed in config `decisions.paths` | Operator-added catalogs |
|
|
26
26
|
| `shared` | `decisions/` under the bundled config root | Shipped catalogs (`config/decisions/` in-repo) |
|
|
27
27
|
|
|
28
|
-
The bundled shared catalog ships `
|
|
28
|
+
The bundled shared catalog ships `failure-class`,
|
|
29
29
|
`gate-evidence`, `idea-recommendation`, `needs-design`, `anatomy-validation-verdict` and
|
|
30
30
|
`maker-liveness` (the last served only by `spur decision status --probe`; no workflow references
|
|
31
31
|
it). Layers win **per file basename** (a project `gates.yaml` replaces the shipped `gates.yaml`
|
|
@@ -84,8 +84,7 @@ row lands in `system_events` beside `decision.end`, on the same `run_id`, so the
|
|
|
84
84
|
**Scoring one.** `decisions.outcomeMap` in config (project or global layer) holds Spur's reading of
|
|
85
85
|
Spur's own artifacts — per decision id, which recorded outcomes count as correct for each served
|
|
86
86
|
value (`String(value)` keys, so a yes/no decision uses `"true"`/`"false"`). The shipped defaults
|
|
87
|
-
score `failure-class` (`fix` → `fixed`, `stop` → `not-fixed`)
|
|
88
|
-
(`"false"` → `none`/`p4`/`p3`, `"true"` → `p1`/`p2`).
|
|
87
|
+
score `failure-class` (`fix` → `fixed`, `stop` → `not-fixed`).
|
|
89
88
|
|
|
90
89
|
`spur decision status --reliability` then reports, per (decision × maker) group:
|
|
91
90
|
|
|
@@ -237,9 +236,7 @@ guards: [decision/lifecycle.md](decision/lifecycle.md) §1, §3.
|
|
|
237
236
|
|
|
238
237
|
```bash
|
|
239
238
|
spur decision list --json | jq -r '.[].id'
|
|
240
|
-
spur decision show
|
|
241
|
-
spur decision run task-semantic-risk --param wbs=1093 \
|
|
242
|
-
--evidence .spur/run/1093-diffstat.json --evidence docs/tasks/1093_*.md --json
|
|
239
|
+
spur decision show failure-class # inspect contract before serving
|
|
243
240
|
spur decision run failure-class --param wbs=1093 \
|
|
244
241
|
--evidence .spur/run/<runId>-test-output.txt # redacted evidence -> instructions
|
|
245
242
|
spur decision status --json | jq '.loadErrors' # audit catalog health
|
|
@@ -256,32 +256,6 @@ the active tasks folder (or `--folder`).
|
|
|
256
256
|
| `--folder <path>` | Custom tasks folder. |
|
|
257
257
|
| `--json` | Machine-readable report envelope. |
|
|
258
258
|
|
|
259
|
-
## `migrate-anchors`
|
|
260
|
-
|
|
261
|
-
Qualify in-repo evidence anchors to repo-relative paths across the task corpus. Run
|
|
262
|
-
`--dry-run` first: unambiguous matches are reported in `qualified`, multiple matches in `ambiguous`
|
|
263
|
-
without rewriting, and schema-incompatible files in `skipped`. The write path uses the planning
|
|
264
|
-
service rather than raw file edits.
|
|
265
|
-
|
|
266
|
-
**`done_reason` scratch pointers are retargeted** (task 1140, ADR-131): a `.spur/run/<wbs>-verdict.json`
|
|
267
|
-
or `.spur/run/<wbs>/verdict.json` substring becomes `.spur/memory/evidence/<wbs>-verdict.json` when
|
|
268
|
-
that copy exists, else `tracked Testing section (scratch verdict not retained)` when Testing is
|
|
269
|
-
non-empty; otherwise the value is left unchanged and reported in `doneReasonUnresolved`. Each
|
|
270
|
-
`doneReasons` row carries `kind` (`absolute-path` | `durable-evidence` | `tracked-testing`). This is
|
|
271
|
-
the repair for the `no-scratch-verdict-pointer` rule.
|
|
272
|
-
|
|
273
|
-
**`--wbs <wbs>` scopes the pass to one task file** (task 1109 R1) — the wbs is resolved through the
|
|
274
|
-
task locator and exactly that file is scanned, so the pipeline's implement stage can auto-repair a
|
|
275
|
-
task's unique basename anchors without the corpus-wide pass rewriting unrelated files (the unscoped
|
|
276
|
-
apply rewrote 119 on 2026-10-07). An unknown wbs exits `1` with an actionable message and writes
|
|
277
|
-
nothing. Ambiguous basenames are still reported and left untouched in scoped mode.
|
|
278
|
-
|
|
279
|
-
```bash
|
|
280
|
-
spur task migrate-anchors --dry-run --json
|
|
281
|
-
spur task migrate-anchors --json
|
|
282
|
-
spur task migrate-anchors --wbs 1109 --json # one task file only
|
|
283
|
-
```
|
|
284
|
-
|
|
285
259
|
## `resolve <file-path>`
|
|
286
260
|
|
|
287
261
|
Map a file path to its **owning task** — returns the WBS + task file. Strategies, in order: direct
|
|
@@ -454,7 +428,6 @@ spur task sections <wbs> <init|add|list> [name] [--folder] [--json]
|
|
|
454
428
|
spur task list [--status <s>] [--phase <p>] [--parent <wbs>] [--feature <id>] [--folder] [--json]
|
|
455
429
|
spur task refresh [--folder] [--json]
|
|
456
430
|
spur task migrate [--dry-run] [--folder] [--json]
|
|
457
|
-
spur task migrate-anchors [--wbs <wbs>] [--dry-run] [--json]
|
|
458
431
|
spur task refresh-roster <wbs> [--folder] [--json]
|
|
459
432
|
spur task batch-create --file <path> [--skip-ready | --agent <selector>] [--folder] [--json]
|
|
460
433
|
spur task record <wbs> [--verdict-file <p>] [--solution-from-diff] [--transition <s>] [--folder] [--json]
|
|
@@ -466,7 +439,6 @@ spur task path <wbs> [--folder] [--json]
|
|
|
466
439
|
spur task run-link <wbs> [--source <src>] [--run-id <id>] [--json]
|
|
467
440
|
spur task scaffold-tests <wbs> [--file <path>] [--folder] [--json]
|
|
468
441
|
spur task gate <wbs> <run|recheck|light|deferred|status> [--cmd <c>] [--probe-cmd <c>] [--run-id <id>]
|
|
469
|
-
spur task residual <wbs> <scan|review-gate|fold|settle|report> [--root <dir>] [--tmp-dir <dir>] [--folder]
|
|
470
442
|
spur task diffstat <wbs>
|
|
471
443
|
```
|
|
472
444
|
|
|
@@ -89,7 +89,6 @@ content up front — not to accumulate more into one oversized task.
|
|
|
89
89
|
| `list` | List tasks, filtered | `--status <s>` `--phase <p>` `--parent <wbs>` `--feature <id>` `--folder` `--json` |
|
|
90
90
|
| `refresh` | Re-scan the corpus and report counts (**`kanban.md` retired** — web Task Kanban is SSOT) | `--folder` `--json` |
|
|
91
91
|
| `migrate` | One-time A17 corpus normalization pass | `--dry-run` `--folder` `--json` |
|
|
92
|
-
| `migrate-anchors` | Qualify in-repo evidence anchors to repo-relative paths (0583 R1–R3); `--wbs` scopes to one task file (1109 R1); retargets scratch `done_reason` verdict pointers (1140) | `--wbs` `--dry-run` `--json` |
|
|
93
92
|
| `refresh-roster <wbs>` | Regenerate a parent task's sub-task roster block in `## Plan` | `--folder` `--json` |
|
|
94
93
|
| `batch-create` | Create many tasks from a validated JSON array | `--file <path>` `--skip-ready` `--agent <selector>` `--folder` `--json` |
|
|
95
94
|
| `batch-plan <mode>` | Batch plan projection: `waves` / `order` (JSON on stdout; the batch driver's visible plan) | `--tasks <file>` `--concurrency <n>` |
|
|
@@ -105,13 +104,11 @@ content up front — not to accumulate more into one oversized task.
|
|
|
105
104
|
| `verifyall-aggregate` | Aggregate per-task verify outcomes into a batch verdict (NOT-STARTED excluded) | `--from-file <path>` `--json` |
|
|
106
105
|
| `scaffold-tests <wbs>` | Generate BDD test stubs from task Acceptance Criteria | `--file <path>` `--folder` `--json` |
|
|
107
106
|
| `gate <wbs> <mode>` | Task-pipeline quality gate (`run`, `recheck`, `light`, `deferred`, `status`); mode-specific exits and git-tree-keyed receipts (see `sp:spur-check`) | `--cmd <c>` `--probe-cmd <c>` `--run-id <id>` |
|
|
108
|
-
| `residual <wbs> <step>` | F96 residual sweep step (`scan`, `review-gate`, `fold`, `settle`, `report`) | `--root <dir>` `--tmp-dir <dir>` `--folder` |
|
|
109
107
|
| `diffstat <wbs>` | Write the triage diffstat artifact against the run base (fails safe to `sensitive: true`) | — |
|
|
110
108
|
|
|
111
109
|
Use only the flags listed for the selected verb. `batch-plan` emits JSON without `--json`;
|
|
112
|
-
`wrapup`, `gate
|
|
113
|
-
`run-link
|
|
114
|
-
`residual` accepts `--folder` but no `--json`. Do not append shared flags to every command.
|
|
110
|
+
`wrapup`, `gate` and `diffstat` use their operation-specific stdout/artifact contracts.
|
|
111
|
+
`run-link` and `verifyall-aggregate` accept `--json` but no `--folder`. Do not append shared flags to every command.
|
|
115
112
|
General exit codes are `0` success, `1` error, `2` invalid usage; consult the operation contract
|
|
116
113
|
for soft gate modes and specialized refusal codes.
|
|
117
114
|
|
|
@@ -203,7 +200,7 @@ refused (ready-set resolver and pipeline preflight), and a live dependent is rep
|
|
|
203
200
|
reported, never rewritten.
|
|
204
201
|
|
|
205
202
|
Writes that stay **permitted** on a `deprecated` task (each edits the record rather than declaring
|
|
206
|
-
the work resumable): `spur task record
|
|
203
|
+
the work resumable): `spur task record` and verdict writes, and
|
|
207
204
|
`spur task update <wbs> --section <any>` — the section write lands and returns a freeze warning.
|
|
208
205
|
|
|
209
206
|
**`--no-lifecycle`** suppresses lifecycle workflow *run record* creation (use during pipeline-driven
|