@gobing-ai/spur 0.4.0 → 0.4.1

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 (154) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/decisions/gates.yaml +36 -0
  3. package/config/decisions/history-anatomy.yaml +35 -0
  4. package/config/decisions/idea-pipeline.yaml +38 -0
  5. package/config/plugin-scripts.json +15 -0
  6. package/config/rules/docs/sourced-api-claims.yaml +60 -0
  7. package/config/rules/recommended-pre-check.yaml +8 -3
  8. package/config/rules/structure/scratch-evidence-pointer.yaml +35 -0
  9. package/config/script-placement-baseline.json +2 -2
  10. package/config/workflows/feature-lifecycle.yaml +9 -2
  11. package/config/workflows/history-anatomy.yaml +22 -0
  12. package/config/workflows/idea-pipeline.yaml +75 -0
  13. package/config/workflows/task-pipeline.yaml +216 -57
  14. package/config/workflows/wrapup-pipeline.yaml +106 -13
  15. package/package.json +9 -9
  16. package/plugins/sp/README.md +11 -1
  17. package/plugins/sp/agents/super-planner.md +11 -0
  18. package/plugins/sp/agents/super-reviewer.md +14 -0
  19. package/plugins/sp/bunfig.toml +8 -0
  20. package/plugins/sp/commands/dev-brainstorm.md +29 -16
  21. package/plugins/sp/commands/dev-find-way.md +80 -0
  22. package/plugins/sp/commands/dev-idea.md +6 -0
  23. package/plugins/sp/commands/dev-parallel.md +8 -2
  24. package/plugins/sp/commands/dev-plan.md +6 -0
  25. package/plugins/sp/commands/dev-review-session.md +3 -1
  26. package/plugins/sp/commands/dev-run.md +12 -2
  27. package/plugins/sp/commands/dev-runall.md +18 -10
  28. package/plugins/sp/hooks/context-session-start.ts +1 -1
  29. package/plugins/sp/lib/idea-handoff.generated.mjs +41 -5
  30. package/plugins/sp/lib/inline-run-app.ts +28 -0
  31. package/plugins/sp/lib/inline-run.generated.d.mts +5 -0
  32. package/plugins/sp/lib/inline-run.generated.mjs +333 -45
  33. package/plugins/sp/lib/plan-projection.generated.d.mts +28 -0
  34. package/plugins/sp/lib/plan-projection.generated.mjs +255 -0
  35. package/plugins/sp/lib/quality-gate.generated.d.mts +47 -1
  36. package/plugins/sp/lib/quality-gate.generated.mjs +30489 -82
  37. package/plugins/sp/lib/residual-scan.generated.d.mts +19 -0
  38. package/plugins/sp/lib/residual-scan.generated.mjs +66 -0
  39. package/plugins/sp/lib/run-summary-core.ts +561 -0
  40. package/plugins/sp/lib/transcript.ts +121 -6
  41. package/plugins/sp/plugin.json +1 -1
  42. package/plugins/sp/references/roles.md +1 -1
  43. package/plugins/sp/scripts/batch-plan.mjs +335 -0
  44. package/plugins/sp/scripts/batch-plan.ts +100 -0
  45. package/plugins/sp/scripts/batch-preflight.mjs +51 -3
  46. package/plugins/sp/scripts/batch-preflight.ts +72 -1
  47. package/plugins/sp/scripts/commit-guard.mjs +216 -0
  48. package/plugins/sp/scripts/commit-guard.ts +249 -0
  49. package/plugins/sp/scripts/inline-run-dispatch.mjs +130 -0
  50. package/plugins/sp/scripts/inline-run-dispatch.ts +135 -0
  51. package/plugins/sp/scripts/inline-run-setup.mjs +551 -80
  52. package/plugins/sp/scripts/inline-run-setup.ts +52 -78
  53. package/plugins/sp/scripts/persist-out-check.mjs +90 -41
  54. package/plugins/sp/scripts/persist-out-check.ts +112 -57
  55. package/plugins/sp/scripts/quality-gate.mjs +30407 -73
  56. package/plugins/sp/scripts/quality-gate.ts +21 -5
  57. package/plugins/sp/scripts/residual-scan.mjs +86 -31
  58. package/plugins/sp/scripts/residual-scan.ts +28 -30
  59. package/plugins/sp/scripts/run-summary.mjs +421 -14
  60. package/plugins/sp/scripts/run-summary.ts +41 -177
  61. package/plugins/sp/scripts/session-timeline.mjs +109 -12
  62. package/plugins/sp/scripts/session-timeline.ts +71 -19
  63. package/plugins/sp/scripts/wrapup-steps.mjs +150 -2
  64. package/plugins/sp/scripts/wrapup-steps.ts +203 -1
  65. package/plugins/sp/skills/brainstorm/SKILL.md +9 -47
  66. package/plugins/sp/skills/branch-workflow/SKILL.md +1 -0
  67. package/plugins/sp/skills/branch-workflow/references/worktree-patterns.md +1 -0
  68. package/plugins/sp/skills/code-implementation/SKILL.md +48 -1
  69. package/plugins/sp/skills/code-verification/SKILL.md +3 -4
  70. package/plugins/sp/skills/code-verification/references/secu-review.md +3 -0
  71. package/plugins/sp/skills/code-verification/references/verdict-schema.md +68 -0
  72. package/plugins/sp/skills/fleet-join/SKILL.md +1 -1
  73. package/plugins/sp/skills/session-review/SKILL.md +38 -7
  74. package/plugins/sp/skills/source-driven-development/SKILL.md +5 -0
  75. package/plugins/sp/skills/spec-decomposition/references/decomposition.md +5 -3
  76. package/plugins/sp/skills/spur-cli/SKILL.md +5 -2
  77. package/plugins/sp/skills/spur-cli/references/agent.md +20 -15
  78. package/plugins/sp/skills/spur-cli/references/decision.md +7 -6
  79. package/plugins/sp/skills/spur-cli/references/message.md +7 -7
  80. package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +19 -3
  81. package/plugins/sp/skills/spur-cli/references/tasks.md +10 -7
  82. package/plugins/sp/skills/spur-cli/references/workflows/authoring-workflows.md +7 -0
  83. package/plugins/sp/skills/spur-cli/references/workflows.md +7 -2
  84. package/plugins/sp/skills/spur-composer/SKILL.md +1 -1
  85. package/plugins/sp/skills/spur-dev/SKILL.md +18 -14
  86. package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +6 -3
  87. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +49 -14
  88. package/plugins/sp/skills/spur-dev/references/dev-operations.md +37 -16
  89. package/plugins/sp/skills/spur-dev/references/execution-batch-continuation.md +68 -0
  90. package/plugins/sp/skills/spur-dev/references/execution-batch-report.md +194 -0
  91. package/plugins/sp/skills/spur-dev/references/execution-batch.md +113 -1020
  92. package/plugins/sp/skills/spur-dev/references/execution-parallel-isolation.md +130 -0
  93. package/plugins/sp/skills/spur-dev/references/execution-workflow.md +6 -0
  94. package/plugins/sp/skills/spur-dev/references/execution-worktree-landing.md +471 -0
  95. package/plugins/sp/skills/spur-dev/references/execution-worktree-setup.md +379 -0
  96. package/plugins/sp/skills/spur-dev/references/flag-glossary.md +35 -5
  97. package/plugins/sp/skills/spur-dev/references/glossary.md +2 -2
  98. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +343 -163
  99. package/plugins/sp/skills/spur-dev/references/structured-trace-emission.md +178 -0
  100. package/plugins/sp/skills/wayfinder/SKILL.md +10 -14
  101. package/schemas/state-machine-workflow.schema.json +23 -0
  102. package/spur.js +20728 -16630
  103. package/web/_astro/{BoardApp.VeoxxLBy.js → BoardApp.D66k_s_T.js} +1 -1
  104. package/web/_astro/{BoardApp.Bzr4OXrW.js → BoardApp.D6sjAJr_.js} +173 -173
  105. package/web/_astro/{TaskDetail.LAyR_Pvn.js → TaskDetail.BynLnMNc.js} +1 -1
  106. package/web/_astro/{arc.f4e0OYLg.js → arc._BUadrdH.js} +1 -1
  107. package/web/_astro/{architectureDiagram-3BPJPVTR.SSIvxi-Z.js → architectureDiagram-3BPJPVTR.Dh7xS1Pp.js} +1 -1
  108. package/web/_astro/{blockDiagram-GPEHLZMM.DSXIHOFf.js → blockDiagram-GPEHLZMM.DFDVpfXm.js} +1 -1
  109. package/web/_astro/{c4Diagram-AAUBKEIU.DG9Ubu85.js → c4Diagram-AAUBKEIU.V7_3_glh.js} +1 -1
  110. package/web/_astro/channel.DZVfto-r.js +1 -0
  111. package/web/_astro/{chunk-2J33WTMH.C7QU88Qh.js → chunk-2J33WTMH.De1yx7Jz.js} +1 -1
  112. package/web/_astro/{chunk-4BX2VUAB.26Z94xBj.js → chunk-4BX2VUAB.BDhHFuxx.js} +1 -1
  113. package/web/_astro/{chunk-55IACEB6.DYRiBkqw.js → chunk-55IACEB6.DDLkWnmC.js} +1 -1
  114. package/web/_astro/{chunk-727SXJPM.D5Vfv5pe.js → chunk-727SXJPM.CwfiLnA7.js} +1 -1
  115. package/web/_astro/{chunk-AQP2D5EJ.DXHV47bN.js → chunk-AQP2D5EJ.CtGDmUnM.js} +1 -1
  116. package/web/_astro/{chunk-FMBD7UC4.D1suAfOs.js → chunk-FMBD7UC4.BOLjpw73.js} +1 -1
  117. package/web/_astro/{chunk-ND2GUHAM.D6BmdHEY.js → chunk-ND2GUHAM.BDhQls6O.js} +1 -1
  118. package/web/_astro/{chunk-QZHKN3VN.rnPU-Ak-.js → chunk-QZHKN3VN.76qBynDF.js} +1 -1
  119. package/web/_astro/{classDiagram-4FO5ZUOK.CvEfXIo1.js → classDiagram-4FO5ZUOK.N0mpPHT0.js} +1 -1
  120. package/web/_astro/{classDiagram-v2-Q7XG4LA2.CvEfXIo1.js → classDiagram-v2-Q7XG4LA2.N0mpPHT0.js} +1 -1
  121. package/web/_astro/{cose-bilkent-S5V4N54A.DkMisLSm.js → cose-bilkent-S5V4N54A.CKknFfjB.js} +1 -1
  122. package/web/_astro/{cynefin-OW5HDTMX.C77Q-pF6.js → cynefin-OW5HDTMX.Cw3ZWBAh.js} +1 -1
  123. package/web/_astro/{dagre-BM42HDAG.YaV8ce27.js → dagre-BM42HDAG.D3yIKCRD.js} +1 -1
  124. package/web/_astro/{diagram-2AECGRRQ.CUyGEKge.js → diagram-2AECGRRQ.D51dO83Z.js} +1 -1
  125. package/web/_astro/{diagram-5GNKFQAL.CRgd8dgj.js → diagram-5GNKFQAL.Bb-FViDj.js} +1 -1
  126. package/web/_astro/{diagram-KO2AKTUF.Bmzys9hq.js → diagram-KO2AKTUF.D3mN8S6x.js} +1 -1
  127. package/web/_astro/{diagram-LMA3HP47.BvmJY4Lw.js → diagram-LMA3HP47.dMMyPcbJ.js} +1 -1
  128. package/web/_astro/{diagram-OG6HWLK6.0hEhD30d.js → diagram-OG6HWLK6.AzbvzY4C.js} +1 -1
  129. package/web/_astro/{erDiagram-TEJ5UH35.Bjt8lrnm.js → erDiagram-TEJ5UH35.BR5I4OZb.js} +1 -1
  130. package/web/_astro/{flowDiagram-I6XJVG4X.CJZTjRDV.js → flowDiagram-I6XJVG4X.DFqvhGkn.js} +1 -1
  131. package/web/_astro/{ganttDiagram-6RSMTGT7._VqoVafc.js → ganttDiagram-6RSMTGT7.ByJbhH6J.js} +1 -1
  132. package/web/_astro/{gitGraphDiagram-PVQCEYII.CEDb7tVo.js → gitGraphDiagram-PVQCEYII.CInHjQR3.js} +1 -1
  133. package/web/_astro/index.COh_kBxN.css +1 -0
  134. package/web/_astro/{infoDiagram-5YYISTIA.CgwifPpK.js → infoDiagram-5YYISTIA.Cm0dGVjJ.js} +1 -1
  135. package/web/_astro/{ishikawaDiagram-YF4QCWOH.B99wx2J1.js → ishikawaDiagram-YF4QCWOH.C3nOP6Sj.js} +1 -1
  136. package/web/_astro/{journeyDiagram-JHISSGLW.2hRwJbEo.js → journeyDiagram-JHISSGLW.4IvLa2MW.js} +1 -1
  137. package/web/_astro/{kanban-definition-UN3LZRKU.BahJkKNC.js → kanban-definition-UN3LZRKU.DS87Cl-k.js} +1 -1
  138. package/web/_astro/{linear.DguUUe6V.js → linear.MzmRrNER.js} +1 -1
  139. package/web/_astro/{mermaid.core.CvgfmqVr.js → mermaid.core.fK-WNswS.js} +4 -4
  140. package/web/_astro/{mindmap-definition-RKZ34NQL.B3qEA3x9.js → mindmap-definition-RKZ34NQL.BqipOHhY.js} +1 -1
  141. package/web/_astro/{pieDiagram-4H26LBE5.FlWA-_ru.js → pieDiagram-4H26LBE5.0nBiPqFG.js} +1 -1
  142. package/web/_astro/{quadrantDiagram-W4KKPZXB.9bVn35X7.js → quadrantDiagram-W4KKPZXB.Szj7Zpx5.js} +1 -1
  143. package/web/_astro/{requirementDiagram-4Y6WPE33.ChykIhct.js → requirementDiagram-4Y6WPE33.D4UR6TWo.js} +1 -1
  144. package/web/_astro/{sankeyDiagram-5OEKKPKP.Z2Y3hkYb.js → sankeyDiagram-5OEKKPKP.DAE7BdOs.js} +1 -1
  145. package/web/_astro/{sequenceDiagram-3UESZ5HK.J7JsHWDt.js → sequenceDiagram-3UESZ5HK.BP9ZVq25.js} +1 -1
  146. package/web/_astro/{stateDiagram-AJRCARHV.DAPbiCSS.js → stateDiagram-AJRCARHV.BQW7mIxk.js} +1 -1
  147. package/web/_astro/{stateDiagram-v2-BHNVJYJU.D2jvSi0q.js → stateDiagram-v2-BHNVJYJU.PbK4nDih.js} +1 -1
  148. package/web/_astro/{timeline-definition-PNZ67QCA.psW2ci29.js → timeline-definition-PNZ67QCA.Ci_GvUpo.js} +1 -1
  149. package/web/_astro/{vennDiagram-CIIHVFJN.DlILYVmg.js → vennDiagram-CIIHVFJN.DNw1Y5qx.js} +1 -1
  150. package/web/_astro/{wardleyDiagram-YWT4CUSO.xNWwLJnn.js → wardleyDiagram-YWT4CUSO.CwlkaaNe.js} +1 -1
  151. package/web/_astro/{xychartDiagram-2RQKCTM6.EU_BuH7V.js → xychartDiagram-2RQKCTM6.MI6ZuiH_.js} +1 -1
  152. package/web/index.html +2 -2
  153. package/web/_astro/channel.CUFdtWhm.js +0 -1
  154. package/web/_astro/index.Dg_3bOaJ.css +0 -1
@@ -35,9 +35,43 @@ interface VerifyVerdict {
35
35
  status: 'pass' | 'fail' | 'warn';
36
36
  evidence: string;
37
37
  }>;
38
+ /** Verifier confidence (task 1068 R3). REQUIRED for PASS — the done gate denies
39
+ * a confidence-less PASS. Accepted case-insensitively, normalized to uppercase. */
40
+ confidence?: 'HIGH' | 'MEDIUM' | 'LOW';
38
41
  }
39
42
  ```
40
43
 
44
+ ## Confidence level (task 1068 R3)
45
+
46
+ A PASS verdict must state the verifier's confidence: `"confidence": "HIGH" | "MEDIUM" | "LOW"`.
47
+ The value is case-insensitive on read (normalized to uppercase), but a present value outside the
48
+ enum invalidates the artifact, and a PASS with the field absent is denied at the `* → done`
49
+ transition with a remediation naming the field (`--force-done` remains the documented escape).
50
+ The verify answer's `Confidence:` lint rule (producer side) already guarantees the field for
51
+ pipeline-produced artifacts; this closes the hand-authored / pre-1068 artifact hole.
52
+
53
+ ### Coherence: the level must be earned (task 1133)
54
+
55
+ Presence and vocabulary are not enough — the level has to match the rows in the same answer, so the
56
+ lint rejects a level that contradicts its own evidence. Two rejection classes, both addressed to the
57
+ `Confidence:` line and both capped by the shared `ANSWER_LINT_MAX_FINDINGS` budget:
58
+
59
+ - `confidence-unwarranted` — `HIGH` while any requirement row normalizes to `PARTIAL`/`UNMET`, any
60
+ acceptance-criteria row does not normalize to `MET`, or any `MET` row's evidence is hedged.
61
+ A `HIGH` claim says the evidence needs no re-check; a non-MET or hedged row says the opposite.
62
+ - `confidence-understated` — `LOW` while at least one requirement row exists and every requirement
63
+ and acceptance-criteria row normalizes to `MET`. The evidence already did the work, so `LOW`
64
+ misreports the state as unproven.
65
+
66
+ `MEDIUM` carries no coherence rule in either direction: it is the level a verifier uses for a caveat
67
+ with no row to point at, and closing it would force either an overclaimed `HIGH` or an unusable
68
+ `LOW`. The level is normalized to uppercase before the decision, so `high` is judged as `HIGH`.
69
+
70
+ Set the level from the rows, not the mood: all rows `MET` with fresh evidence is `HIGH`; a
71
+ `PARTIAL`/`UNMET` row or a hedge means `MEDIUM`, not `HIGH`. An unwarranted level does not merely
72
+ warn — the lint rejects the answer and no verdict artifact is written, so the level is worth
73
+ choosing deliberately before the verdict line is finalized.
74
+
41
75
  ## Compatibility alias: `scenario` row key
42
76
 
43
77
  Task 0410 hardened the verdict reader. Producers SHOULD use the canonical `id` field for every
@@ -138,6 +172,23 @@ the run actually verified. Since 0804 R9 the checker ignores complete parsed cit
138
172
  scanning for subjects, so a citation's filename (including snake_case paths) can never become a
139
173
  false subject — a real absent symbol, nonexistent file, or invalid range still reports.
140
174
 
175
+ ## Basename-only anchors are unresolved anchors (task 1110 R1)
176
+
177
+ `spur task verdict --from-answer` accepts the citation *shape*, but the `--as done` gate resolves
178
+ every Testing/Solution anchor against the repo root. A basename citation — `decision-events.ts:83`,
179
+ `task.test.ts:42` — reports `L4.anchor-unresolved` at **error** and blocks
180
+ `spur task update <wbs> done`, because the gate cannot tell which file the row meant. Write the
181
+ repo-root-relative form from the first pass:
182
+
183
+ - Right: `packages/app/src/decision/decision-events.ts:83`, `apps/cli/tests/commands/task.test.ts:42`
184
+ - Wrong: `decision-events.ts:83`, `../services/foo.ts:12`, `@gobing-ai/ts-x/src/persistence.ts:108`
185
+ (a scoped package is never repo-relative — use the external named-origin form below)
186
+
187
+ The pipeline's implement stage also runs a scoped `spur task migrate-anchors --wbs <wbs>` pass
188
+ before the proof capture (task 1109), but it qualifies **unique** basenames only: an ambiguous
189
+ basename (two tracked files share it) is reported and left untouched, and line drift and
190
+ `L4.anchor-subject-mismatch` are never repaired by that pass — those remain the author's rows.
191
+
141
192
  ## Source citations for external claims (task 1070)
142
193
 
143
194
  A Requirement/AC evidence cell that asserts an external API/library claim must carry a verifiable
@@ -152,6 +203,23 @@ citation in the SAME cell, or lint rejects the row with `evidence-citation` (blo
152
203
  satisfy it. Marker-free receipts (test counts, reviewed-log notes) need no citation. The check is
153
204
  presence-only — which citation proves which claim is not deterministically decidable.
154
205
 
206
+ ## Hedged evidence is rejected on MET rows
207
+
208
+ A MET row asserts the requirement is satisfied; evidence that hedges ("the guard likely prevents
209
+ the leak") contradicts the assertion the row is making. The lint rejects such rows with
210
+ `evidence-hedged`, naming the detected phrase, with two remedies: state the deterministic fact
211
+ with a concrete anchor, or downgrade the row to PARTIAL (which is what suspected-but-unproven
212
+ behavior actually is).
213
+
214
+ - Detected phrases (closed set, word-anchored, case-insensitive): `likely`, `unlikely`,
215
+ `probably`, `presumably`, `apparently`, `seems/seeming/seemingly to`, `appears to`. Modal verbs
216
+ (`might`/`may`/`could`/`should`) are deliberately out of set — they are constant in remediation
217
+ prose and would drown the signal.
218
+ - Only MET rows are scanned. Hedging a gap in an UNMET row ("the stale path likely still loads
219
+ the old bundle") is honest reporting and stays clean.
220
+ - Citation spans are stripped before scanning, so a filename or test name containing a hedge
221
+ word (`likely-match.test.ts`) cannot fire.
222
+
155
223
  ## Checks evidence
156
224
 
157
225
  Wave C verification can emit the following additive `checks[]` rows:
@@ -11,7 +11,7 @@ description: >-
11
11
  A guest is a session that **pulls** work: it is neither supervised nor restarted, it is addressed
12
12
  by concrete id only, and it never receives a stage (`requiresCapabilities` stages can never route
13
13
  to it — a guest carries no attestation). Joining registers an occupant row plus a heartbeat lease;
14
- leaving (or an expired lease) releases it and returns any claimed messages to `pending`.
14
+ leaving (or an expired lease) releases it and returns any claimed messages to `queued`.
15
15
 
16
16
  ## Join
17
17
 
@@ -2,7 +2,7 @@
2
2
  name: session-review
3
3
  description: "Review the active coding-agent session: separate resolved from open issues with evidence, propose bounded improvements. With --fix auto (alias --triage), apply pure-doc / 1–2-line fixes inline and file the rest as tasks; with --fix all, fix every actionable finding inline and file none. Triggers: review this session, wrap-up, triage findings."
4
4
  license: Apache-2.0
5
- version: 1.2.0
5
+ version: 1.3.0
6
6
  metadata:
7
7
  author: spur
8
8
  platforms: "claude-code,codex,openclaw,opencode,antigravity,pi"
@@ -24,7 +24,9 @@ compact, evidence-backed report of outcomes, resolved issues, remaining risks, a
24
24
 
25
25
  Use this skill immediately after focused operations when the operator asks what happened, what was
26
26
  resolved, or how the session could improve. Use imported-history analysis for ended sessions,
27
- cross-agent windows, recurrence, trends, or quantitative performance forensics.
27
+ cross-agent windows, recurrence, trends, or quantitative performance forensics: on pi, run
28
+ `spur history analyze --source pi --session <file-stem>` where `<file-stem>` is the transcript
29
+ basename without `.jsonl` (e.g. `2026-10-07T22-44-33-625Z_01a1188a-…`), not the bare uuid.
28
30
 
29
31
  ## Arguments
30
32
 
@@ -92,7 +94,16 @@ issues with its evidence. Notes stay report-only.
92
94
  operator prompt, read-only from the host transcript. Run it once without `--group` to list the
93
95
  segments, then map them to stages (`"1-3,4,5-6"`). It splits each segment into `work` and
94
96
  operator `wait` (idle before the next prompt plus AskUserQuestion answer time) and counts tokens
95
- once per message id.
97
+ once per message id. On pi the transcript is `$PI_SESSION_FILE` (pass it as `--transcript` when
98
+ the run reports no host session id). **A measurement that returns `segments: []` with zero totals
99
+ while the session had operator prompts is an unreadable or stale adapter, not an empty session:**
100
+ compare the installed copy against this tree's `plugins/sp/scripts/session-timeline.mjs` and
101
+ refresh it with `superskill install sp` before reporting numbers; report `n/a` until then.
102
+ The transcript resolves from `--transcript`, else `CLAUDE_CODE_SESSION_ID`, else `PI_SESSION_FILE`
103
+ (the pi host sets it and no Claude session id); with none of them the measurement reports
104
+ `available:false` with a reason and the table renders `n/a` instead of guessing. A
105
+ skill-injected body (`<skill name="…">`) is counted as activity in `injectedPrompts`, never as a
106
+ segment — only the operator's own prompts segment the session.
96
107
  2. **Inventory outcomes.** List requested outcomes and classify each as completed, partial, blocked,
97
108
  or not attempted. Collapse repeated attempts into one outcome.
98
109
  3. **Classify issues.** For every material issue, distinguish resolved, open, or attempted. Record
@@ -140,10 +151,30 @@ step 4 excludes. Use `n/a` for any value not supported by the measurement.
140
151
  | --- | --- | --- | --- | --- |
141
152
 
142
153
  Evidence names the tool result, verification command, or concrete repository state visible in the
143
- session. Do not list ordinary implementation steps as issues. **Confidence** is `HIGH`, `MEDIUM`, or
144
- `LOW` for that row's claim, with its grounds in the cell (a level without grounds is not
145
- verification); any API/library statement in a row cites the installed source as `path:line` or a URL,
146
- and a claim the session could not ground is written `LOW` with the missing evidence named.
154
+ session. Do not list ordinary implementation steps as issues.
155
+
156
+ **Confidence** is `HIGH`, `MEDIUM`, or `LOW` for that row's claim. The level is **derived from the
157
+ check that produced the claim, never assessed from how the row reads**, and the cell carries that
158
+ verifier (e.g. `HIGH — gate exit 0, /tmp/g0.log re-run this session`). Add the row's **falsifier**
159
+ when the level is not `HIGH`: what would have made it fail, or what moves it up. The same ladder
160
+ grades this report's Open-issues table.
161
+
162
+ | Level | Verifies when | Not this |
163
+ | --- | --- | --- |
164
+ | `HIGH` | An executed check in this session produced the result and its raw output is reachable (command + exit code, test counts, query row, gate log). Re-runnable now. | The code or change "looks correct"; a claim asserted only in prose. |
165
+ | `MEDIUM` | The claim is inferred from observed facts, rests on prior-session or delegated evidence, or names state that moved after the check (stale by construction). Name which of the three. | Presenting an inference as an observation. |
166
+ | `LOW` | No executable check was run. Name the missing evidence **and** the command that would ground it. | Dropping the row instead of marking it. |
167
+
168
+ Two guards against level inflation:
169
+
170
+ - Evidence that cannot be re-run, or that is only the agent's own summary, **caps the row at
171
+ `MEDIUM`** — a re-run is what promotes it.
172
+ - An all-`HIGH` multi-finding review is a signal the ladder was not applied, not a clean session.
173
+ Where every row genuinely is `HIGH`, the cells show distinct check results rather than repeated
174
+ phrasing.
175
+
176
+ Any API/library statement in a row cites the installed source as `path:line` or a URL, and a claim
177
+ the session could not ground is written `LOW` with the missing evidence named.
147
178
 
148
179
  ### Open issues and risks
149
180
 
@@ -101,6 +101,11 @@ line: `Verification: HIGH|MEDIUM|LOW — <first failing check and deviation, or
101
101
  - **Honest confidence** — the stated HIGH/MEDIUM/LOW matches the evidence: HIGH requires a check against the pinned source this session; MEDIUM/LOW items are labeled, and LOW is never presented as fact.
102
102
  - **HIGH** — all three checks pass. **MEDIUM** — coverage intact but some citations are off-version (latest docs for a pinned dependency) or secondary-source only. **LOW** — an API/library claim lacks any citation, or a LOW-confidence claim was asserted as fact.
103
103
 
104
+ Deterministic backstop: the `cited-version-strings` / `cited-api-claims` rules
105
+ (`.spur/rules/docs/sourced-api-claims.yaml`, run in `recommended-pre-check`) flag markdown lines that
106
+ assert version strings or time-anchored API claims with no citation anchor on the same line. They
107
+ are an info-severity advisory backstop for this contract (they do not gate; the checks above and the SECUA checklist are the enforcement points).
108
+
104
109
  ## Common Rationalizations
105
110
 
106
111
  | Rationalization | Reality |
@@ -562,9 +562,11 @@ 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. No section body may use `HITL`, `approval`/`approved`, `merged`/`merge event`,
566
- `content-gate`, `GATED`, or `capstone` as standalone words (L4.gate-language) — say "operator
567
- answer" / "accepted" instead, and keep enum values out of that list too.
565
+ as extra bullets. No section body may use `HITL`, `merge event`, `content-gate`, `GATED`, or
566
+ `capstone` as standalone words (L4.gate-language); ambiguous words (`approval`, `approved`,
567
+ `merged`) warn only with a gating cue (`until`, `after`, `once`, `before`, `pending`, `blocked`,
568
+ `wait for`, `requires`) in the same sentence, so plain composition prose stays silent — say
569
+ "operator answer" / "accepted" instead, and keep enum values out of that list too.
568
570
 
569
571
  **The order sidecar.** Also emit the private task-order sidecar at
570
572
  `.spur/run/<runId>-idea-task-order.json`: a JSON array (one entry per batch item) of
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: spur-cli
3
- description: "Reference and operate the complete `spur` CLI surface: task, feature, rule, workflow, builder, agent, message, self, history, and projects. Use for verb or flag lookup, machine-readable output and exit contracts, or CLI-gated corpus writes. Triggers: \"spur task\", \"spur history\", \"spur projects\", \"create a task\", \"task check\", and any Spur CLI convention. Not for planning or execution lifecycle orchestration (`sp:spur-dev`)."
3
+ description: "Reference and operate the complete `spur` CLI surface: task, feature, rule, workflow, builder, agent, message, decision, self, history, and projects. Use for verb or flag lookup, machine-readable output and exit contracts, or CLI-gated corpus writes. Triggers: \"spur task\", \"spur history\", \"spur projects\", \"spur decision\", \"spur agent join\", \"create a task\", \"task check\", and any Spur CLI convention. Not for planning or execution lifecycle orchestration (`sp:spur-dev`)."
4
4
  license: Apache-2.0
5
5
  metadata:
6
6
  author: spur
@@ -17,6 +17,7 @@ metadata:
17
17
  - builder
18
18
  - agent
19
19
  - message
20
+ - decision
20
21
  - self
21
22
  - history
22
23
  - projects
@@ -44,7 +45,7 @@ Pick the noun, read its reference. Each Tier A and Tier B reference owns that no
44
45
  | **Tier A** | **rule** | Constraint quality gate: run presets, author rules, fine-tune, validate rule files/presets, extend engine | [references/rules.md](references/rules.md) |
45
46
  | **Tier A** | **workflow** | Dual-mode workflow runtime: author state-machine / transition-flow workflows, validate, run, read traces | [references/workflows.md](references/workflows.md) |
46
47
  | **Tier A** | **builder** | Release plumbing: bump a package (or the `workspace:`-pinned set) with `bump-ver`, delete release tags with `drop-tags`, commit + tag + optional push | [references/builder.md](references/builder.md) |
47
- | **Tier B** | **agent** | Coding-agent execution surface: run prompts via detected/named agents, list agent specs, start/stop supervised processes, readiness check | [references/agent.md](references/agent.md) |
48
+ | **Tier B** | **agent** | Coding-agent execution surface: run prompts via detected/named agents, list agent specs (incl. `agent.fleet` members), start/stop supervised processes, fleet `report`/`join`/`leave`/`wait`/`trace`, readiness check | [references/agent.md](references/agent.md) |
48
49
  | **Tier B** | **message** | Durable inter-agent messaging: send, inbox, reply, watch | [references/message.md](references/message.md) |
49
50
  | **Tier B** | **self** | Self-management verbs: scaffold (`init`), database maintenance (`maintain`), schema migrations (`migrate`), local web server (`serve`), status overview (`status`); `self init` runs post-scaffold validation probes & layout classification | [references/self.md](references/self.md) |
50
51
  | **Tier B** | **history** | Import agent histories, aggregate forensic artifacts, render reports, and run the checkpoint-resumed daily pipeline | [references/history.md](references/history.md) |
@@ -142,6 +143,8 @@ and spreading it; full contract in `docs/04_DESIGN.md` §1.0.1.
142
143
  [dispatch-surface rule](../parallel-execution/references/dispatch-surface.md).
143
144
  - **[references/message.md](references/message.md)** - durable inter-agent messaging (`send`,
144
145
  `inbox`, `reply`, `watch`).
146
+ - **[references/decision.md](references/decision.md)** - decision catalog (`list`, `show`, `run`,
147
+ `status`); offline by default via the built-in `typesafe` maker.
145
148
  - **[references/self.md](references/self.md)** - `spur self init|maintain|migrate|serve|status` CLI verbs
146
149
  (the five legacy top-level nouns remain hidden aliases). `self init` runs post-scaffold init
147
150
  validation (Phase 1.5/1.6 probes).
@@ -22,19 +22,19 @@ that before using `run` for fan-out dispatch.
22
22
  | Verb | Purpose | Key flags |
23
23
  | ---- | ------- | --------- |
24
24
  | `run <prompt>` | Execute a prompt or slash command via a coding agent | `--agent <name>` `--spec <id>` `--model <name>` `--mode <mode>` `--continue` `--cwd <path>` `--drain` `--json` |
25
- | `wait [<specId>]` | Identity-pinned wait for an occupant run to reach a lifecycle state (G4 wave 2; `--role` selector per 0685) | `--role <name>` `--run <runId>` `--until <state>...` `--timeout <ms>` `--json` |
25
+ | `wait [<specId>]` | Identity-pinned wait for an occupant run to reach a lifecycle state (G4 wave 2; `--role` selector per 0685) | `--role <name>` `--run <runId>` `--until <state>...` `--timeout <ms>` `--inbox <id>` `--json` |
26
26
  | `trace <runId>` | Print one execution record's lineage — the run, its dispatch parents, agent session ids and streams (1076 R4, ADR-132) | `--follow` `--timeout <ms>` `--json` |
27
27
  | `list` | List detected coding agents, or agent specs with `--specs` (live run status + member session merged from `spur self serve`) | `--specs` `--server <url>` `--json` |
28
28
  | `report` | Report a fleet member lifecycle state (`working`/`idle`/`blocked`) from a host hook (G73 R1/R2, task 1080) | `--state <state>` `--seq <ns>` `--spec <id>` `--json` |
29
29
  | `join` | Join the fleet as a guest occupant — a live session that pulls its own work (G73 R2, task 1081) | `--role <name>` `--id <id>` `--session-id <sid>` `--pid <n>` `--executor <name>` `--json` |
30
- | `leave` | Leave the fleet: release the guest lease, retire the occupant, return claimed messages to pending | `[id]` `--session-id <sid>` `--json` |
30
+ | `leave` | Leave the fleet: release the guest lease, retire the occupant, return claimed messages to `queued` | `[id]` `--session-id <sid>` `--json` |
31
31
  | `status` | Agent specs with live process status and member session (requires `spur self serve`) | `--server <url>` `--json` |
32
32
  | `doctor [agent]` | Check agent readiness | `--json` `--probe-health` `--force-refresh` |
33
33
  | `usage` | Run-once provider usage capture (codexbar) → quota-owned availability refresh; scheduled externally | `--dry-run` `--source <name>` `--json` |
34
34
  | `start <spec-id>` | Start a supervised agent process (requires `spur self serve`) | `--server <url>` `--json` |
35
35
  | `stop <spec-id>` | Stop a supervised agent process (requires `spur self serve`) | `--server <url>` `--json` |
36
36
 
37
- `list`, `status`, `doctor`, `run`, `wait`, `trace`, `start`, and `stop` accept `--json` plus `--json-envelope`. The hidden
37
+ Every verb except `trace` accepts `--json` plus `--json-envelope`; `trace` is `--json` only. The hidden
38
38
  `loop` is a supervisor-internal process surface. **Exit codes:** `0` success, `1` failure, and `2`
39
39
  invalid usage; `run` can also propagate the invoked agent's non-zero result.
40
40
 
@@ -142,24 +142,27 @@ exits 2 naming the accepted vocabulary. Resolution collapses onto the same ident
142
142
 
143
143
  ```bash
144
144
  spur agent list # detected coding agents on this machine
145
- spur agent list --specs # agent specs under .spur/agents/
145
+ spur agent list --specs # agent specs: .spur/agents/*.yaml + agent.fleet members
146
146
  spur agent list --json # machine-readable
147
147
  ```
148
148
 
149
149
  Without `--specs`, lists coding agents detected on the host (by binary on `PATH`). With `--specs`,
150
- lists agent specs (`.spur/agents/*.yaml`) **with live run status merged from the server's
150
+ lists agent specs — hand-authored `.spur/agents/*.yaml` merged with the members declared under
151
+ `agent.fleet.members` (derived in memory, never written to disk; the fleet declaration wins on an
152
+ id clash; stale `fleet:generated` files are ignored) — **with live run status merged from the server's
151
153
  supervisor**: each row carries a trailing status column
152
154
  (`running` / `stopped` / `errored` / `unknown`), `pid=<n>` where a process exists, and the member
153
155
  session (0897): the session mode plus a shortened resume id (`resume id=3f9c2a1d`), or `-` when the
154
- member has no recorded session. When `spur self serve` is unreachable, the listing falls back to all
156
+ member has no recorded session. `--json` rows carry `source: file` (plus `path`) or `source: fleet`
157
+ (no backing file, so no `path`). When `spur self serve` is unreachable, the listing falls back to all
155
158
  `stopped` with a stderr warning. `--server <url>` targets the supervisor API; without it the URL is
156
159
  this project's serve — the port in the cwd's project-registry entry (`http://localhost:<port>/api`),
157
160
  falling back to `http://localhost:3000/api` only when the project has no live entry (1088 R1).
158
161
 
159
162
  ```bash
160
163
  spur agent list --specs
161
- # planner claude reviewer claude plans the work running pid=4132 resume id=3f9c2a1d
162
- # worker-1 pi worker pi implements stopped one-shot
164
+ # myapp-planner-1 claude planner claude orchestrator running pid=4132 resume id=3f9c2a1d
165
+ # myapp-coder-1 pi coder pi implements stopped one-shot
163
166
  ```
164
167
 
165
168
  ## `status` - live status + member session per spec
@@ -180,7 +183,7 @@ unreachable server reports every spec `stopped` with no session. `--server <url>
180
183
 
181
184
  ```bash
182
185
  spur agent report --state working --seq 1759665600000000000
183
- spur agent report --state blocked --seq 1759665600000000000 --spec proj-worker-1 --json
186
+ spur agent report --state blocked --seq 1759665600000000000 --spec myapp-coder-1 --json
184
187
  ```
185
188
 
186
189
  | Flag | Description |
@@ -215,7 +218,7 @@ concrete id only (role/executor selectors count declared members, so a guest is
215
218
  claim table (same TTL/heartbeat semantics as the write slot — R5) and writes
216
219
  `.spur/run/guests/<id>.json` so a host Stop hook can recognize its own session without a CLI call.
217
220
  `leave`, or lease expiry in the reconciler pass, releases the lease, marks the occupant exited,
218
- returns its claimed messages to `pending` and removes the record.
221
+ returns its claimed messages to `queued` and removes the record.
219
222
 
220
223
  | Flag | Description |
221
224
  | --- | --- |
@@ -296,8 +299,8 @@ buffer is only a live view.
296
299
  ## `start` - start a supervised process
297
300
 
298
301
  ```bash
299
- spur agent start worker-1
300
- spur agent start worker-1 --json
302
+ spur agent start myapp-coder-1
303
+ spur agent start myapp-coder-1 --json
301
304
  ```
302
305
 
303
306
  Posts to the `spur self serve` supervisor API
@@ -310,8 +313,8 @@ when the server is unreachable or the start fails.
310
313
  ## `stop` - stop a supervised process
311
314
 
312
315
  ```bash
313
- spur agent stop worker-1
314
- spur agent stop worker-1 --json
316
+ spur agent stop myapp-coder-1
317
+ spur agent stop myapp-coder-1 --json
315
318
  ```
316
319
 
317
320
  Posts to the supervisor API
@@ -388,7 +391,9 @@ one never re-sends settled work; only never-started deliveries release and redel
388
391
  **[dispatch-surface rule](../../parallel-execution/references/dispatch-surface.md)**, not this
389
392
  reference. This reference documents the verbs; that rule decides which surface carries a dispatch.
390
393
  - **Not the fleet orchestrator.** The `spur self serve` supervisor drives the lifecycle: `spur agent
391
- start` / `stop` manage supervised processes and `agent list --specs` reports live state.
394
+ start` / `stop` manage supervised processes and `agent list --specs` reports live state. Dispatch
395
+ policy (`agent.fleet.strategy` `rest|gtd`, the `orchestrator` member, `--agent fleet` routing)
396
+ lives in project config and the workflow executor, not in these verbs.
392
397
 
393
398
  ## See also
394
399
 
@@ -22,15 +22,15 @@ Decisions resolve first-wins across three layers:
22
22
  | Layer | Root | Notes |
23
23
  | ----- | ---- | ----- |
24
24
  | `project` | `<cwd>/.spur/decisions/*.yaml` | Highest precedence |
25
- | `registered` | programmatic catalog registrations | Agents register in-process |
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
28
  The bundled shared catalog ships `task-triage`, `failure-class`, and `review-failure-class` (all
29
29
  `choice` type, param `wbs`). Duplicate ids across layers keep the higher layer; duplicates inside
30
30
  one file are a load error.
31
31
 
32
- **Config keys** (under `decisions:` in `config.global.yaml` or project config):
33
- `paths` (extra catalog folders joined to the registered layer), `maker` (default DecisionMaker
32
+ **Config keys** (under `decisions:` in the global `~/.config/spur/config.yaml` or project `.spur/config.yaml`):
33
+ `paths` (extra catalog folders forming the `registered` layer), `maker` (default DecisionMaker
34
34
  for every decision point), `makers` (per-decision-id overrides). An unregistered maker name is a
35
35
  config error, never a silent fallback (design §3.6).
36
36
 
@@ -47,8 +47,9 @@ All verbs support `--json` (bare payload) and `--json-envelope` (`{ok, data|erro
47
47
  ADR-091). Failure output for `--json` commands uses the canonical error envelope only under
48
48
  `--json-envelope`; plain `--json` keeps the human message on stderr.
49
49
 
50
- **Exit codes:** `status` exits 1 on catalog load errors; `show` exits 1 on unknown id; `list` always
51
- exits 0 (design §3.4 — load errors surface via `status`).
50
+ **Exit codes:** `status` exits 1 on any catalog load error or maker-config error; `show` exits 1 on unknown id; `list` exits 0
51
+ (design §3.4 — load errors surface via `status`) except for an invalid `--layer` value (exit 1).
52
+ Error envelopes use `NOT_FOUND` for an unknown id and `VALIDATION_FAILED` for every other caller mistake.
52
53
 
53
54
  **Exit contract for `run` (design §3.4):** any backend-observed outcome — low confidence, model
54
55
  error surfaced as fallback, declined — is still a **successful serve** (exit 0, envelope carries
@@ -86,7 +87,7 @@ spur decision show task-triage # inspect contract before se
86
87
  spur decision run task-triage --param wbs=1093 --json
87
88
  spur decision run failure-class --param wbs=1093 \
88
89
  --evidence .spur/run/<runId>-test-output.txt # redacted evidence -> instructions
89
- spur decision status --json | jq '.data.errors' # audit catalog health
90
+ spur decision status --json | jq '.loadErrors' # audit catalog health
90
91
  ```
91
92
 
92
93
  ## References
@@ -31,10 +31,10 @@ All verbs accept `--json` and `--json-envelope`. `watch` applies the envelope pe
31
31
 
32
32
  ```bash
33
33
  spur message send "Please review PR 42" --to reviewer
34
- spur message send "Task 0040 is blocked" --to worker-1 --from operator
34
+ spur message send "Task 0040 is blocked" --to myapp-coder-1 --from operator
35
35
  spur message send "Done" --to planner --json
36
36
  spur message send "Review 0042" --to reviewer --wait --until invoke-exit --timeout 30000
37
- spur message send "Done" --to manager --request-key 0695-report-42 # retry-safe: same key replays the original receipt
37
+ spur message send "Done" --to myapp-planner-1 --request-key 0695-report-42 # retry-safe: same key replays the original receipt
38
38
  spur message send "Start the pass" --role reviewer # resolves to exactly one instance
39
39
  ```
40
40
 
@@ -66,9 +66,9 @@ wait; enqueue is **not** rolled back if the wait later fails.
66
66
  ## `inbox` - list addressed messages
67
67
 
68
68
  ```bash
69
- spur message inbox --agent worker-1
70
- spur message inbox --agent worker-1 --json
71
- spur message inbox --agent worker-1 --unresolved --json
69
+ spur message inbox --agent myapp-coder-1
70
+ spur message inbox --agent myapp-coder-1 --json
71
+ spur message inbox --agent myapp-coder-1 --unresolved --json
72
72
  ```
73
73
 
74
74
  Lists messages addressed to `--agent <id>`, oldest first. The body is truncated in plain-text output;
@@ -107,8 +107,8 @@ Threads a reply to a specific message id. The reply is addressable to the origin
107
107
  ## `watch` - follow an inbox live
108
108
 
109
109
  ```bash
110
- spur message watch --agent worker-1
111
- spur message watch --agent worker-1 --interval 1000 --json
110
+ spur message watch --agent myapp-coder-1
111
+ spur message watch --agent myapp-coder-1 --interval 1000 --json
112
112
  ```
113
113
 
114
114
  Polls the inbox and surfaces each **new** message exactly once as it arrives. `Ctrl-C` to exit. With
@@ -258,14 +258,28 @@ the active tasks folder (or `--folder`).
258
258
 
259
259
  ## `migrate-anchors`
260
260
 
261
- Qualify ambiguous in-repo evidence anchors to repo-relative paths across the task corpus. Run
261
+ Qualify in-repo evidence anchors to repo-relative paths across the task corpus. Run
262
262
  `--dry-run` first: unambiguous matches are reported in `qualified`, multiple matches in `ambiguous`
263
263
  without rewriting, and schema-incompatible files in `skipped`. The write path uses the planning
264
264
  service rather than raw file edits.
265
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
+
266
279
  ```bash
267
280
  spur task migrate-anchors --dry-run --json
268
281
  spur task migrate-anchors --json
282
+ spur task migrate-anchors --wbs 1109 --json # one task file only
269
283
  ```
270
284
 
271
285
  ## `resolve <file-path>`
@@ -358,7 +372,9 @@ and `prefixId` normalizes `AC<n>` so the box flips. A bare `AC-<i>` also does bo
358
372
  resolves it through the feature's scenario order to the AC line aliasing scenario *i*
359
373
  (`AC<k> — [R<n> — ]<scenario title>`) and flips that box — never the same-numbered `AC<i>`; with no
360
374
  aliasing line it flips nothing. A bare `AC<n>` credits no scenario; a title carrying the scenario's
361
- `R<n>` label matches neither.
375
+ `R<n>` label matches neither. When the task's AC section is a Gherkin fence (`Scenario: AC1 — …`
376
+ rows), there is no checklist label: cite each row by its exact scenario title — a bare `AC<i>`
377
+ matches nothing and the verdict is rejected.
362
378
 
363
379
  **Evidence rule (behavior-bearing AC):** an AC row with `status: MET` on a behavior-bearing id
364
380
  (no `[advisory]`/`[non-core]`/`[non-behavior]`/`[docs-only]` marker) MUST carry `test` or
@@ -436,7 +452,7 @@ spur task sections <wbs> <init|add|list> [name] [--folder] [--json]
436
452
  spur task list [--status <s>] [--phase <p>] [--parent <wbs>] [--feature <id>] [--folder] [--json]
437
453
  spur task refresh [--folder] [--json]
438
454
  spur task migrate [--dry-run] [--folder] [--json]
439
- spur task migrate-anchors [--dry-run] [--json]
455
+ spur task migrate-anchors [--wbs <wbs>] [--dry-run] [--json]
440
456
  spur task refresh-roster <wbs> [--folder] [--json]
441
457
  spur task batch-create --file <path> [--skip-ready | --agent <selector>] [--folder] [--json]
442
458
  spur task record <wbs> [--verdict-file <p>] [--solution-from-diff] [--transition <s>] [--folder] [--json]
@@ -23,7 +23,7 @@ does what*, this skill.
23
23
  Start from the WBS, not the corpus layout:
24
24
 
25
25
  ```bash
26
- spur task show <wbs> --json # metadata + full content + filePath
26
+ spur task show <wbs> --json # {wbs, name, status, frontmatter, content, filePath}; priority etc. under .frontmatter
27
27
  spur task get <wbs> --json # alias of `show` — same output, no separate code path
28
28
  spur task path <wbs> --json # absolute path only
29
29
  ```
@@ -38,15 +38,15 @@ re-reading or re-tokenizing the task.
38
38
 
39
39
  | Verb | Purpose | Key flags |
40
40
  | ---- | ------- | --------- |
41
- | `create <title>` | Allocate a new task (race-safe WBS) | `--feature <id>` `--parent <wbs>` `--template <variant>` `--dedupe-within <s>` `--allow-duplicate-name` `--skip-ready` `--agent <selector>` `--folder` `--json` |
41
+ | `create <title>` | Allocate a new task (race-safe WBS) | `--feature <id>` `--no-reopen` `--parent <wbs>` `--template <variant>` `--dedupe-within <s>` `--allow-duplicate-name` `--skip-ready` `--agent <selector>` `--folder` `--json` |
42
42
  | `show <wbs>` | Print one task's frontmatter + body | `--folder` `--json` |
43
- | `update <wbs> [status]` | Lifecycle transition, section replace, **or** frontmatter set | `--section <name> --from-file <path>` `--assignee <spec-id>` (exclusive with `--section`) `--feature <id>` `--priority <p>` `--ac-numbering task-local` `--ac-altitude <a>` `--estimate-hours <n>` `--no-lifecycle` `--force-done` `--reason <text>` `--provenance-bypass` `--verdict-dir <path>` `--folder` `--json` |
43
+ | `update <wbs> [status]` | Lifecycle transition, section replace, **or** frontmatter set | `--section <name> --from-file <path>` `--assignee <spec-id>` (exclusive with `--section`) `--feature <id>` `--no-reopen` `--priority <p>` `--ac-numbering task-local` `--ac-altitude <a>` `--estimate-hours <n>` `--no-lifecycle` `--force-done` `--reason <text>` `--provenance-bypass` `--verdict-dir <path>` `--folder` `--json` |
44
44
  | `deps <wbs> <op> [values...]` | Mutate `dependencies[]` frontmatter array (ops: `set`, `add`, `remove`, `clear`) | `--folder` `--json` |
45
45
  | `sections <wbs> <op> [name]` | Initialize, add, or list canonical task sections (ops: `init`, `add`, `list`) | `--folder` `--json` |
46
46
  | `list` | List tasks, filtered | `--status <s>` `--phase <p>` `--parent <wbs>` `--feature <id>` `--folder` `--json` |
47
47
  | `refresh` | Re-scan the corpus and report counts (**`kanban.md` retired** — web Task Kanban is SSOT) | `--folder` `--json` |
48
48
  | `migrate` | One-time A17 corpus normalization pass | `--dry-run` `--folder` `--json` |
49
- | `migrate-anchors` | Qualify in-repo evidence anchors to repo-relative paths (0583 R1–R3) | `--dry-run` `--json` |
49
+ | `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` |
50
50
  | `refresh-roster <wbs>` | Regenerate a parent task's sub-task roster block in `## Plan` | `--folder` `--json` |
51
51
  | `batch-create` | Create many tasks from a validated JSON array | `--file <path>` `--skip-ready` `--agent <selector>` `--folder` `--json` |
52
52
  | `record <wbs>` | Write `Testing` from a verify verdict (deterministic); bare-`## Review` fallback only; optional Solution + transition | `--verdict-file <path>` `--solution-from-diff` `--transition <status>` `--folder` `--json` |
@@ -67,8 +67,11 @@ tasks folder. **Exit codes:** `0` success, `1` error, `2` invalid usage.
67
67
  spur task create "Add email validation" --feature H2 --parent 0040
68
68
  ```
69
69
 
70
- - **`--feature <id>`** wires traceability: it derives the task's `Background` from the feature's
71
- `Goal` and records `feature_id` in frontmatter (L4 traceability reads this edge).
70
+ - **`--feature <id>`** wires traceability: it derives the task's `Background` from the feature's `Goal`
71
+ and records `feature_id` in frontmatter (L4 traceability reads this edge). The parent feature's
72
+ status is checked before any write: `done`/`cancelled` is rejected with the status plus up to three
73
+ `active` sibling ids, and `verifying` is reopened to `active` through the guarded feature transition
74
+ (`featureReopened` in `--json`); `--no-reopen` suppresses only that reopen.
72
75
  - **`--parent <wbs>`** groups the new task under a parent WBS for sub-task decomposition.
73
76
  - **`--template <variant>`** selects the section-matrix variant that shapes the new file's sections:
74
77
  `standard·feature-impl·issue·review·meta·brainstorm`. The default is **`feature-impl` when
@@ -273,7 +276,7 @@ corpus, or with a WBS for one task:
273
276
 
274
277
  ```bash
275
278
  spur task check --json # whole corpus
276
- spur task check 0040 --json # one task
279
+ spur task check 0040 --json # one task; output is an array — read .[0].pass
277
280
  spur task check --strict --json # elevate ALL warnings to failures
278
281
  spur task check 0040 --as done # evaluate as the done row (lifecycle target, F92 R2)
279
282
  spur task check 0040 --strict-core # compatibility alias; not the done gate (use --as done)
@@ -134,6 +134,13 @@ runner (see [validation-and-extension.md](validation-and-extension.md)).
134
134
  | Guard | `always` | Unconditional pass — the default edge condition / fallback transition |
135
135
  | Guard | `action-ok` | Pass iff the prior action on this state/node succeeded — useful for a single hard shell check |
136
136
 
137
+ Spur's host additionally registers (`registerSpurBuiltins`, `packages/app/src/workflow/builtins.ts`):
138
+
139
+ | Kind | Capability |
140
+ | ---- | ---------- |
141
+ | Action | `agent.run` (model call via `spur agent run`; `executor: 'fleet'` dispatches into the agent fleet), `decide` (inline `id`/`method`/`question`/`choices`/`default`/`evidence` → outcome written to `resultFile`; catalog-id references are pending task 1094 — use `spur decision run` for catalog decisions), `command.gate`, `rule.check`, `doctor.probe`, `response.validate`, `proof.fingerprint`, `run.artifact`, `file.exists`, `file.read`, `file.read.into-var`, `http.request`, `hitl.confirm`, `hitl.select`, `hitl.input`, `shell` (streaming) |
142
+ | Guard | `shell` (env-aware), `contract-violation` |
143
+
137
144
  Order matters for both guards and conditions: **the first that passes wins.** Put the discriminating
138
145
  guard before the unconditional fallback (`always` / no-guard edge). For multi-condition gates (doctor
139
146
  + task check, quality gate + attempt cap), prefer a **soft probe** shell that writes PASS|FAIL and
@@ -112,7 +112,7 @@ The skill's logic divides by **whether the LLM adds value**:
112
112
  | `run` | `spur workflow run` (CLI) | `<file> [--run-id <id>] [--vars <json>] [--dry-run] [--async] [--no-plan] [--quiet/--silent/--verbose] [--detail <level>] [--trace-file] [--no-log] [--steer]` | Terminal state reached (sync) or run started (async); trace readable |
113
113
  | `continue` | `spur workflow continue` (CLI) | `[run-id] [--yes] [--answer <yes\|no\|cancel>] [--answer-text <text>] [--async] [--no-log]` | Resume a paused or interrupted run (omit id -> most recent resumable); `--answer` injects a confirm/select gate answer and `--answer-text` answers an input gate with free text (H1 R27), both before guard re-evaluation; one of them is required headless (0901 R3) and each is validated against the pending gate kind; `--async` detaches the resume (0901 R4) |
114
114
  | `cancel` | `spur workflow cancel` (CLI) | `<run-id>` | Single non-terminal run marked failed (SIGTERM async worker when live) |
115
- | `clean` | `spur workflow clean` (CLI) | `[--older-than <min>] [--force] [--logs] [--dry-run]` | Bulk-finalize stale `running`/`pending` runs as failed **and** reclaim retained run logs older than `workflow.logRetentionDays` (30d default) |
115
+ | `clean` | `spur workflow clean` (CLI) | `[--older-than <min>] [--force] [--logs] [--dry-run]` | Bulk-finalize stale `running`/`pending` runs as failed **and** reclaim retained run logs older than `workflows.logRetentionDays` (30d default) |
116
116
  | `list` | `spur workflow list` (CLI) | — | Available workflow **YAML definition files** (not run records) |
117
117
  | `trace` | `spur workflow trace` (CLI) | `[run-id] [--workflow <n>] [--status <s>] [--since <iso>] [--last <n>] [--follow] [--poll <ms>] [--output] [--timeout <ms>]` | Run history list or per-run timeline |
118
118
  | `progress` | `spur workflow progress` (CLI) | `<run-id>` | The `projectWorkflowProgress` projection for that run — current state, per-action attempts, candidate next transitions, diagnostics. Read-only; the verb renders, `packages/app` derives. Unknown run id exits 1 with `Run <id> not found.` |
@@ -273,6 +273,11 @@ spur workflow progress <run-id> [--json]
273
273
  `spur workflow show <file>` renders the declared graph as Mermaid. `--format todo` instead emits a
274
274
  declared-step checklist; `--json` serializes the selected projection. This verb intentionally does
275
275
  not advertise `--json-envelope` because its JSON projection is a kept-raw document surface.
276
+ Task 1104: for annotated definitions the todo `--json` payload also carries `plan` — the two-layer
277
+ A-Z/1-9 phased plan derived from each state's `display` (`phase`/`phaseTitle`/`title`/`show`);
278
+ `null` when no state declares `display`. `workflow validate` enforces the phase table on annotated
279
+ definitions (every non-terminal state phased, terminals bare, ≤25 phases, ≤9 states per phase,
280
+ consistent `phaseTitle`).
276
281
 
277
282
  | Flag (on `run`) | Effect |
278
283
  | --------------- | ------ |
@@ -361,7 +366,7 @@ redirecting `agent.run` stages (ADR-047).
361
366
  - **Stale-run finalization** (existing): bulk-finalizes orphaned `running`/`pending` runs as `failed`.
362
367
  `--older-than <minutes>` (default 30) and `--force` (all non-terminal regardless of age) apply here only.
363
368
  - **Run-log reclamation** (0429): removes expired `.log` files from `.spur/memory/runs/`
364
- and legacy `.spur/run/`, using `workflow.logRetentionDays` (default 30 days). Non-terminal
369
+ and legacy `.spur/run/`, using `workflows.logRetentionDays` (default 30 days). Non-terminal
365
370
  runs, including paused/interrupted runs, are protected; ownership lookup failures preserve logs.
366
371
  The two-file record (`.md` + `.state.json`) and partial handoffs are retained.
367
372
  - **Checkpoint reclamation**: removes expired terminal checkpoints only when confinement,
@@ -49,7 +49,7 @@ its own output and never runs a recurring loop — evaluation is the doctor's jo
49
49
  | feature | Apply accepted rows through `spur feature update --section --from-file`; keep acceptance criteria in Gherkin | [../spur-cli/references/features.md](../spur-cli/references/features.md) |
50
50
  | rule | The trace-driven tuning loop (§ Rule tuning loop) | [../spur-cli/references/rules.md](../spur-cli/references/rules.md) · [fine-tuning](../spur-cli/references/rules/fine-tuning.md) |
51
51
  | workflow | Catalog selection, the composition ladder, and the ADR-115 budgets (§ below) | [../spur-cli/references/workflows.md](../spur-cli/references/workflows.md) · [operations](../spur-cli/references/workflows/operations.md) |
52
- | agent spec | Read through `spur agent list --specs`; specs are materialized from the fleet declaration at serve start | [../spur-cli/references/agent.md](../spur-cli/references/agent.md) |
52
+ | agent spec | Read through `spur agent list --specs`; fleet member specs are derived in memory from `agent.fleet` (never written to `.spur/agents/`) | [../spur-cli/references/agent.md](../spur-cli/references/agent.md) |
53
53
  | board module | Declare under `bootstrap.modules`, gated by the serve preflight (§ Board module composition) | [../spur-cli/references/serve.md](../spur-cli/references/serve.md) |
54
54
 
55
55
  Do not drive the planning→execution lifecycle from here — that is `sp:spur-dev`.