@gobing-ai/spur 0.3.91 → 0.3.93

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 (148) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/pipeline-budgets.json +2 -9
  3. package/config/plugin-scripts.json +27 -1
  4. package/config/templates/AGENTS.md +4 -0
  5. package/config/templates/docs/02_ROADMAP.md +2 -0
  6. package/config/templates/docs/03_ARCHITECTURE.md +3 -1
  7. package/config/templates/docs/04_DESIGN.md +2 -0
  8. package/config/templates/docs/99_PROJECT_CONSTITUTION.md +10 -2
  9. package/config/workflow-candidates.json +72 -1
  10. package/config/workflows/feature-lifecycle.yaml +14 -5
  11. package/config/workflows/feature-verification.yaml +36 -27
  12. package/config/workflows/history-anatomy.yaml +16 -25
  13. package/config/workflows/idea-pipeline.yaml +76 -23
  14. package/config/workflows/pr-review.yaml +8 -0
  15. package/config/workflows/task-pipeline.yaml +362 -40
  16. package/config/workflows/wayfinder-resolution.yaml +5 -0
  17. package/config/workflows/wrapup-pipeline.yaml +102 -19
  18. package/package.json +9 -9
  19. package/plugins/sp/README.md +7 -2
  20. package/plugins/sp/agents/super-planner.md +14 -5
  21. package/plugins/sp/commands/dev-dogfood.md +4 -4
  22. package/plugins/sp/commands/dev-fixall.md +8 -5
  23. package/plugins/sp/commands/dev-run.md +8 -2
  24. package/plugins/sp/commands/dev-runall.md +14 -8
  25. package/plugins/sp/commands/dev-verify.md +9 -0
  26. package/plugins/sp/commands/dev-verifyall.md +5 -0
  27. package/plugins/sp/lib/idea-handoff.generated.mjs +306 -301
  28. package/plugins/sp/lib/inline-run.generated.d.mts +18 -0
  29. package/plugins/sp/lib/inline-run.generated.mjs +1468 -0
  30. package/plugins/sp/plugin.json +1 -1
  31. package/plugins/sp/references/environment-lens.md +1 -1
  32. package/plugins/sp/scripts/dogfood-testing/validate-report.mjs +136 -0
  33. package/plugins/sp/scripts/dogfood-testing/validate-report.ts +196 -2
  34. package/plugins/sp/scripts/feature-verification-steps.mjs +174 -0
  35. package/plugins/sp/scripts/feature-verification-steps.ts +275 -0
  36. package/plugins/sp/scripts/history-anatomy-cache.mjs +104 -4
  37. package/plugins/sp/scripts/history-anatomy-cache.ts +137 -13
  38. package/plugins/sp/scripts/inline-pipeline-parity-check.ts +2 -1
  39. package/plugins/sp/scripts/inline-run-setup.mjs +421 -0
  40. package/plugins/sp/scripts/inline-run-setup.ts +325 -78
  41. package/plugins/sp/scripts/quality-gate.mjs +248 -6
  42. package/plugins/sp/scripts/quality-gate.ts +410 -9
  43. package/plugins/sp/scripts/record-feature-sync.mjs +63 -0
  44. package/plugins/sp/scripts/record-feature-sync.ts +84 -0
  45. package/plugins/sp/scripts/residual-scan.mjs +484 -0
  46. package/plugins/sp/scripts/residual-scan.ts +640 -0
  47. package/plugins/sp/scripts/task-diffstat.mjs +156 -0
  48. package/plugins/sp/scripts/task-diffstat.ts +229 -0
  49. package/plugins/sp/scripts/task-evidence-precheck.ts +8 -3
  50. package/plugins/sp/scripts/task-size-precheck.ts +8 -3
  51. package/plugins/sp/scripts/wrapup-drift-probe.mjs +181 -0
  52. package/plugins/sp/scripts/wrapup-drift-probe.ts +258 -0
  53. package/plugins/sp/scripts/wrapup-steps.mjs +60 -1
  54. package/plugins/sp/scripts/wrapup-steps.ts +89 -4
  55. package/plugins/sp/skills/brainstorm/SKILL.md +2 -0
  56. package/plugins/sp/skills/brainstorm/references/workflows.md +17 -2
  57. package/plugins/sp/skills/branch-workflow/SKILL.md +1 -0
  58. package/plugins/sp/skills/branch-workflow/references/worktree-patterns.md +2 -0
  59. package/plugins/sp/skills/code-implementation/SKILL.md +17 -0
  60. package/plugins/sp/skills/code-verification/SKILL.md +21 -0
  61. package/plugins/sp/skills/code-verification/references/secu-review.md +3 -2
  62. package/plugins/sp/skills/code-verification/references/verdict-schema.md +1 -0
  63. package/plugins/sp/skills/dogfood-testing/SKILL.md +5 -3
  64. package/plugins/sp/skills/dogfood-testing/references/monitor-ledger.md +63 -26
  65. package/plugins/sp/skills/dogfood-testing/references/report-template.md +33 -10
  66. package/plugins/sp/skills/history-anatomy/references/modes.md +5 -3
  67. package/plugins/sp/skills/next-feature/references/ranking-rubric.md +1 -1
  68. package/plugins/sp/skills/next-router/references/routing-table.md +7 -0
  69. package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +1 -1
  70. package/plugins/sp/skills/session-review/SKILL.md +12 -2
  71. package/plugins/sp/skills/spur-check/SKILL.md +112 -0
  72. package/plugins/sp/skills/spur-cli/references/features.md +1 -1
  73. package/plugins/sp/skills/spur-cli/references/projects.md +3 -1
  74. package/plugins/sp/skills/spur-cli/references/workflows.md +39 -19
  75. package/plugins/sp/skills/spur-dev/SKILL.md +13 -5
  76. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +18 -3
  77. package/plugins/sp/skills/spur-dev/references/dev-operations.md +2 -2
  78. package/plugins/sp/skills/spur-dev/references/document-authoring.md +85 -0
  79. package/plugins/sp/skills/spur-dev/references/execution-batch.md +286 -58
  80. package/plugins/sp/skills/spur-dev/references/execution-workflow.md +1 -1
  81. package/plugins/sp/skills/spur-dev/references/flag-glossary.md +27 -4
  82. package/plugins/sp/skills/spur-dev/references/gate-checklists.md +3 -2
  83. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +61 -16
  84. package/plugins/sp/skills/spur-dev/references/planning-workflow.md +10 -5
  85. package/plugins/sp/skills/spur-dev/templates/design.md +31 -0
  86. package/plugins/sp/skills/spur-dev/templates/plan.md +32 -0
  87. package/plugins/sp/skills/spur-doctor/SKILL.md +60 -14
  88. package/schemas/state-machine-workflow.schema.json +4 -0
  89. package/spur.js +22501 -19644
  90. package/web/_astro/BoardApp.CerSBgis.js +192 -0
  91. package/web/_astro/BoardApp.eoTz0pZs.js +1 -0
  92. package/web/_astro/{TaskDetail.CXGltuT_.js → TaskDetail.DCqiC-OZ.js} +1 -1
  93. package/web/_astro/arc.CPwg6Rw0.js +1 -0
  94. package/web/_astro/{architectureDiagram-3BPJPVTR.DJ8DHkWE.js → architectureDiagram-3BPJPVTR.DM_vp_hO.js} +1 -1
  95. package/web/_astro/{blockDiagram-GPEHLZMM.D8DHK3Jl.js → blockDiagram-GPEHLZMM.DXVIiv0p.js} +1 -1
  96. package/web/_astro/{c4Diagram-AAUBKEIU.BugQbX9u.js → c4Diagram-AAUBKEIU.BbF_zCxW.js} +1 -1
  97. package/web/_astro/channel.MYZLKNwy.js +1 -0
  98. package/web/_astro/{chunk-2J33WTMH.Mv26KlVn.js → chunk-2J33WTMH.CAgQHpPC.js} +1 -1
  99. package/web/_astro/{chunk-4BX2VUAB.CD51JoT_.js → chunk-4BX2VUAB.BN-5tpw4.js} +1 -1
  100. package/web/_astro/{chunk-55IACEB6.D_PFaIEe.js → chunk-55IACEB6.CnPkEEr0.js} +1 -1
  101. package/web/_astro/{chunk-727SXJPM.DemMW1ao.js → chunk-727SXJPM.BQzQeMVm.js} +4 -4
  102. package/web/_astro/{chunk-AQP2D5EJ.Iu2V5-ex.js → chunk-AQP2D5EJ.B6xNyDnL.js} +1 -1
  103. package/web/_astro/{chunk-FMBD7UC4.MsNgSP-E.js → chunk-FMBD7UC4.C7f9Ih78.js} +1 -1
  104. package/web/_astro/{chunk-ND2GUHAM.DfbRaAlm.js → chunk-ND2GUHAM.CNV1dFXT.js} +1 -1
  105. package/web/_astro/{chunk-QZHKN3VN.BbJAQ4h-.js → chunk-QZHKN3VN.Cudn2TkJ.js} +1 -1
  106. package/web/_astro/{classDiagram-4FO5ZUOK.CPurtiC2.js → classDiagram-4FO5ZUOK.D1NwP50q.js} +1 -1
  107. package/web/_astro/{classDiagram-v2-Q7XG4LA2.CPurtiC2.js → classDiagram-v2-Q7XG4LA2.D1NwP50q.js} +1 -1
  108. package/web/_astro/{cose-bilkent-S5V4N54A.CKKdx1bM.js → cose-bilkent-S5V4N54A.B1wSL-Xb.js} +1 -1
  109. package/web/_astro/{cynefin-OW5HDTMX.CoKMTg-R.js → cynefin-OW5HDTMX.BmK52w8G.js} +1 -1
  110. package/web/_astro/{dagre-BM42HDAG.D4h4_k56.js → dagre-BM42HDAG.Bfy5CTDT.js} +2 -2
  111. package/web/_astro/diagram-2AECGRRQ.DhNnvUvX.js +43 -0
  112. package/web/_astro/diagram-5GNKFQAL.lTX5KwnS.js +10 -0
  113. package/web/_astro/{diagram-KO2AKTUF.BFoCkiCr.js → diagram-KO2AKTUF.CW_vMJ4z.js} +3 -3
  114. package/web/_astro/{diagram-LMA3HP47.exHn9OVx.js → diagram-LMA3HP47.B_8ZGF67.js} +1 -1
  115. package/web/_astro/{diagram-OG6HWLK6.CeqO34nN.js → diagram-OG6HWLK6.BppnHsdS.js} +1 -1
  116. package/web/_astro/{erDiagram-TEJ5UH35.D_v7HqxR.js → erDiagram-TEJ5UH35.BEuHXcjJ.js} +5 -5
  117. package/web/_astro/{flowDiagram-I6XJVG4X.EUmrpbwh.js → flowDiagram-I6XJVG4X.CH-UlnGr.js} +4 -4
  118. package/web/_astro/{ganttDiagram-6RSMTGT7.BOCF5lII.js → ganttDiagram-6RSMTGT7.BO81S85v.js} +1 -1
  119. package/web/_astro/{gitGraphDiagram-PVQCEYII.Di7otYZD.js → gitGraphDiagram-PVQCEYII.XnPxPPZN.js} +1 -1
  120. package/web/_astro/index.Hjbr15fG.css +1 -0
  121. package/web/_astro/{infoDiagram-5YYISTIA.TcBkCAJk.js → infoDiagram-5YYISTIA.JyjYRu_T.js} +1 -1
  122. package/web/_astro/{ishikawaDiagram-YF4QCWOH.D-2y4M0c.js → ishikawaDiagram-YF4QCWOH.BBRBF-Fo.js} +5 -5
  123. package/web/_astro/{journeyDiagram-JHISSGLW.DPbJI_n2.js → journeyDiagram-JHISSGLW.C_iymSyp.js} +1 -1
  124. package/web/_astro/{kanban-definition-UN3LZRKU.EFxhQ9Fj.js → kanban-definition-UN3LZRKU.DdfW-Oqt.js} +7 -7
  125. package/web/_astro/{linear.DSAsQLzs.js → linear.C2_IkbZT.js} +1 -1
  126. package/web/_astro/mermaid.core.GAOYeSR0.js +303 -0
  127. package/web/_astro/{mindmap-definition-RKZ34NQL.CJY1N_7V.js → mindmap-definition-RKZ34NQL.DAZIxQSK.js} +2 -2
  128. package/web/_astro/{pieDiagram-4H26LBE5.567ZNoL2.js → pieDiagram-4H26LBE5.CN8sIhKM.js} +3 -3
  129. package/web/_astro/{quadrantDiagram-W4KKPZXB.mqfz9-MY.js → quadrantDiagram-W4KKPZXB.3dGcX5GP.js} +1 -1
  130. package/web/_astro/{requirementDiagram-4Y6WPE33.Bv1Gv9In.js → requirementDiagram-4Y6WPE33.BV2y4dd6.js} +3 -3
  131. package/web/_astro/{sankeyDiagram-5OEKKPKP.B6Gs4X4r.js → sankeyDiagram-5OEKKPKP.Cqo15Tvo.js} +4 -4
  132. package/web/_astro/{sequenceDiagram-3UESZ5HK.BhYj4v-m.js → sequenceDiagram-3UESZ5HK.CROCPMJB.js} +1 -1
  133. package/web/_astro/{stateDiagram-AJRCARHV.BPbBnkpw.js → stateDiagram-AJRCARHV.RfXZrkFE.js} +1 -1
  134. package/web/_astro/{stateDiagram-v2-BHNVJYJU.C4squMNK.js → stateDiagram-v2-BHNVJYJU.CPXmbBs9.js} +1 -1
  135. package/web/_astro/{timeline-definition-PNZ67QCA.C_SwIHgl.js → timeline-definition-PNZ67QCA.DdgKTiO8.js} +3 -3
  136. package/web/_astro/{vennDiagram-CIIHVFJN.Bz4NZGpQ.js → vennDiagram-CIIHVFJN.CPNVSHF1.js} +5 -5
  137. package/web/_astro/{wardleyDiagram-YWT4CUSO.CozMVZ3i.js → wardleyDiagram-YWT4CUSO.CQhA0Jyr.js} +3 -3
  138. package/web/_astro/{xychartDiagram-2RQKCTM6.BwMGBwjB.js → xychartDiagram-2RQKCTM6.n61BWyy4.js} +1 -1
  139. package/web/index.html +2 -2
  140. package/config/workflows/decision-routing-example.yaml +0 -134
  141. package/web/_astro/BoardApp.BEDWpzsr.js +0 -188
  142. package/web/_astro/BoardApp.DQG2xfEz.js +0 -1
  143. package/web/_astro/arc.C0rrflm_.js +0 -1
  144. package/web/_astro/channel.SRrg1P-w.js +0 -1
  145. package/web/_astro/diagram-2AECGRRQ.DJ0h9zgw.js +0 -43
  146. package/web/_astro/diagram-5GNKFQAL.DvPk1jYd.js +0 -10
  147. package/web/_astro/index.Bx6GY4RH.css +0 -1
  148. package/web/_astro/mermaid.core.kAZjgJHG.js +0 -301
@@ -7,7 +7,7 @@
7
7
  "plugins": [
8
8
  {
9
9
  "name": "sp",
10
- "version": "0.3.91",
10
+ "version": "0.3.93",
11
11
  "source": "./plugins/sp"
12
12
  }
13
13
  ]
@@ -36,10 +36,10 @@
36
36
  "decision": null
37
37
  },
38
38
  "history-anatomy": {
39
- "modelQueries": 4,
39
+ "modelQueries": 3,
40
40
  "wallClockMs": null,
41
41
  "tokenCostUsd": null,
42
- "source": "Coverage entry (0826 R2): the live definition's model-query count (extractResolvedWorkflowFacts, 2026-09-11). No real-run measurement yet: wall-clock and cost are unenforced until measured, never 0.",
42
+ "source": "Coverage entry (0826 R2): the live definition's model-query count (extractResolvedWorkflowFacts, 2026-09-11). No real-run measurement yet: wall-clock and cost are unenforced until measured, never 0. 0920 recount 2026-09-23: 4 -> 3 — the resolve-scope model hop was removed; scope/window validation is deterministic in the history-anatomy-cache paths command.",
43
43
  "decision": null
44
44
  },
45
45
  "wayfinder-resolution": {
@@ -48,13 +48,6 @@
48
48
  "tokenCostUsd": null,
49
49
  "source": "Coverage entry (0826 R2): the live definition's model-query count (extractResolvedWorkflowFacts, 2026-09-11). No real-run measurement yet: wall-clock and cost are unenforced until measured, never 0.",
50
50
  "decision": null
51
- },
52
- "decision-routing-example": {
53
- "modelQueries": 0,
54
- "wallClockMs": null,
55
- "tokenCostUsd": null,
56
- "source": "Coverage entry (0911): authoring example (config/workflows/decision-routing-example.yaml) enumerating `decision:` modes. Measured 0 model queries — the producer is a shell action, so the example runs with no provider (live count via loadQueryCounts, 2026-09-20). Not a pipeline humans run; wall-clock and cost unenforced, never 0.",
57
- "decision": null
58
51
  }
59
52
  }
60
53
  }
@@ -36,6 +36,11 @@
36
36
  "contract": "standard",
37
37
  "twin": "idea-handoff.mjs"
38
38
  },
39
+ {
40
+ "rel": "wrapup-drift-probe.ts",
41
+ "contract": "standard",
42
+ "twin": "wrapup-drift-probe.mjs"
43
+ },
39
44
  {
40
45
  "rel": "wrapup-steps.ts",
41
46
  "contract": "standard",
@@ -48,7 +53,13 @@
48
53
  },
49
54
  {
50
55
  "rel": "inline-run-setup.ts",
51
- "contract": "repo-only"
56
+ "contract": "standard",
57
+ "twin": "inline-run-setup.mjs"
58
+ },
59
+ {
60
+ "rel": "feature-verification-steps.ts",
61
+ "contract": "standard",
62
+ "twin": "feature-verification-steps.mjs"
52
63
  },
53
64
  {
54
65
  "rel": "idea-coverage-check.ts",
@@ -63,11 +74,21 @@
63
74
  "contract": "standard",
64
75
  "twin": "pr-reviewing.mjs"
65
76
  },
77
+ {
78
+ "rel": "record-feature-sync.ts",
79
+ "contract": "standard",
80
+ "twin": "record-feature-sync.mjs"
81
+ },
66
82
  {
67
83
  "rel": "quality-gate.ts",
68
84
  "contract": "standard",
69
85
  "twin": "quality-gate.mjs"
70
86
  },
87
+ {
88
+ "rel": "residual-scan.ts",
89
+ "contract": "standard",
90
+ "twin": "residual-scan.mjs"
91
+ },
71
92
  {
72
93
  "rel": "script-contract-check.ts",
73
94
  "contract": "repo-only"
@@ -80,6 +101,11 @@
80
101
  "rel": "surface-drift-inventory.ts",
81
102
  "contract": "repo-only"
82
103
  },
104
+ {
105
+ "rel": "task-diffstat.ts",
106
+ "contract": "standard",
107
+ "twin": "task-diffstat.mjs"
108
+ },
83
109
  {
84
110
  "rel": "task-evidence-precheck.ts",
85
111
  "contract": "repo-only"
@@ -95,6 +95,10 @@ It owns document responsibilities and maintenance; `00` owns architectural choic
95
95
  `01` product scope, and root `DESIGN.md` UI/UX. Use **`sp:doc-evolve`** for drift,
96
96
  sync and contract checks. Follow host/operator precedence.
97
97
 
98
+ For new `docs/plans/` working records and `docs/design/` non-UI satellites, use the
99
+ `sp:spur-dev` plan/design templates and document-authoring reference. Preserve legacy files' history
100
+ and headings when revising them; `sp:spur-doctor` can propose safe upgrades.
101
+
98
102
  ### Doc map
99
103
 
100
104
  | File | Owns | Update when |
@@ -16,6 +16,8 @@ sync: [T5, T6]
16
16
 
17
17
  Phase goals, order, dependencies and exits only. Detailed feature state belongs in the
18
18
  feature tool's index; task progress belongs in task records (constitution §6.3).
19
+ Detailed proposals and investigations may live in dated `docs/plans/` working records;
20
+ link accepted phase changes here without copying the plan.
19
21
 
20
22
  ## Phase 0 — Foundation
21
23
 
@@ -31,4 +31,6 @@ _(Describe the primary data path: input → processing → output. Name the seam
31
31
  <!--
32
32
  Describes the CURRENT architecture only. Future/accepted designs go in sections explicitly
33
33
  titled "(accepted design — ADR-NNN; not yet built)". Keep command/schema detail in 04 satellites and task delivery receipts in task records.
34
- -->
34
+ Use the `sp:spur-dev` design template for a new non-UI satellite; link it instead of copying its
35
+ contract here.
36
+ -->
@@ -16,6 +16,8 @@ sync: [T3, T9]
16
16
 
17
17
  Non-UI contract index (constitution §6.5). Keep signatures, schemas, defaults, errors
18
18
  and boundary behavior in the owning `docs/design/<slug>.md` satellite.
19
+ Start a new satellite from the `sp:spur-dev` design template; distinguish proposed from current
20
+ behavior and preserve existing headings when revising one.
19
21
 
20
22
  ## UI/UX boundary & DESIGN.md
21
23
 
@@ -3,7 +3,7 @@ name: Project Constitution
3
3
  doc: 99_PROJECT_CONSTITUTION
4
4
  owns: PROCESS — how the key files are maintained
5
5
  authority: authoritative-on-process
6
- version: 1.7.0
6
+ version: 1.8.0
7
7
  created_at: {{init-date}}
8
8
  updated_at: {{init-date}}
9
9
  edit_rules: 99 §6.8
@@ -70,11 +70,15 @@ size, approval, task count, or completion alone does not qualify it for an ADR (
70
70
  ### 4.2 Working layers (outside the authority chain)
71
71
 
72
72
  - Dated `docs/plans/` and `docs/reports/` files hold proposals, investigations, audits and evidence.
73
- They record work; accepted conclusions take effect only in their proper owner.
73
+ They record work; accepted conclusions take effect only in their proper owner. New plan files use
74
+ ordinary Markdown with concise frontmatter and purpose, evidence, recommendation, and follow-up
75
+ as applicable; the `sp:spur-dev` plan template is a starting point, not a rigid schema.
74
76
  - Configured task folders hold requirements, implementation plans, results and verification,
75
77
  maintained through the task tool. Resolve their paths through that tool.
76
78
  - Existing project context or learning storage holds reusable lessons (§8).
77
79
  - `docs/design/` and `docs/features/` are governed detail layers (§4.5), not scratch storage.
80
+ New non-UI design satellites use the `sp:spur-dev` design template; revisions preserve existing
81
+ meaning and references.
78
82
 
79
83
  Preserve historical evidence and its dates. It may be linked for provenance, but current
80
84
  contracts must be understandable without treating an old plan or report as governing policy.
@@ -90,6 +94,8 @@ Use `authoritative` for `00`, `authoritative-on-scope` for `01`,
90
94
  `owns` must match §4.1 in meaning. Bump the minor version for substantive edits and refresh
91
95
  `updated_at` when content changes. Do not touch unrelated documents just to update a date.
92
96
  Keep one metadata block. Root entry/UI files may use their established native format.
97
+ Plans and design satellites use lighter frontmatter for identity, truthful status and dates;
98
+ legacy files without it remain valid and readable. Do not infer historical status from a template.
93
99
 
94
100
  ### 4.4 AGENTS.md synchronization
95
101
 
@@ -194,6 +200,8 @@ Keep the index short. Satellites own non-UI signatures, schemas, defaults, error
194
200
  and boundary behavior. Verify against registrations/contracts; prefer generated artifacts to
195
201
  manual copies. UI rules belong in root `DESIGN.md`; architectural rationale belongs in `00`/`03`.
196
202
  Separate proposed from current behavior. A completed task adds no delivery receipt here.
203
+ Use the design template to structure new satellites around boundaries, contracts, invariants and
204
+ compatibility. Preserve stable headings and historical claims when revising old ones.
197
205
 
198
206
  ### 6.6 `docs/05_FEATURES.md` + `docs/features/<feature-id>_<slug>.md`
199
207
 
@@ -1,7 +1,72 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "note": "Workflow graph-change promotion candidates (task 0873, feature D62; ADR-076 amendment). A candidate is shadow-run against recorded real-run inputs and is promoted into the canonical definition or deleted by its named deadline — never left as a standing parallel <name>2.yaml. `verdict` is null while pending and is filled by `bun scripts/spur-dev.ts promotion evaluate <id>`; `promotion check` (spur-check-feature) fails any candidate still present past its deadline, any unreferenced parallel definition in config/workflows/, and (0877 R8) any retired definition with real (non-dry) terminal runs lacking a recorded decision in `retirements[]`.",
4
- "candidates": [],
4
+ "candidates": [
5
+ {
6
+ "id": "task-pipeline-triage-lanes",
7
+ "canonical": "task-pipeline",
8
+ "deadline": "2026-11-24",
9
+ "createdAt": "2026-09-25",
10
+ "rationale": "0943 (feature D64): task-pipeline work routes by triage lane and failure class instead of static graphs. Between a green gate and the review/verify fork a deterministic `triage` state writes the diffstat (plugins/sp/scripts/task-diffstat.ts, numstat + untracked scan against the precheck-anchored run base), honors a caller-set mode verbatim (never overridden), pins the safety lane on sensitive paths (drizzle/, packages/config/, server auth basenames, *secret*, .github/, plugins/sp/hooks/, *.sql) or >400 changed lines with NO model call, otherwise consults `decide task-triage` (low → fast lane skips review; standard/high → review), and appends the route reason to .spur/memory/task-pipeline-routes.log (R5). On a red gate, `decide failure-class` routes retryable → test-recheck (attempt counted, qualityGateMaxFixAttempts still bounds), fix → test-fix, stop → failed(failed-check); missing/corrupt decision fails closed. Projected basis: the 0938 baseline (docs/reports/2026-09-workflow-cost-baseline.md) measured task-pipeline wall median 7983s over 1 real terminal run with agent.run median 0; the fast lane saves the review agent.run + wall on triage-low diffs, and retryable classification saves fixall hops (and their gate re-runs) on transient failures. Measurement gap honestly named: with workflow.decideDecisionMaker off (R4) triage degrades to standard lanes (diffstat-guard-sensitive/large still forced safety — pure shell, no model), so benefit only materializes with the flag on; per-lane route counts are observable post-merge in .spur/memory/task-pipeline-routes.log. Measured-benefit status: projected from 0938, NOT shadow-run-confirmed — plan step 5 (recorded-input shadow runs) is DEFERRED out of the 0943 session and tracked by this candidate's deadline; `promotion evaluate` runs post-merge. If it does not beat the baseline, it is reverted (ADR-076).",
11
+ "measurement": {
12
+ "workflow": "task-pipeline"
13
+ },
14
+ "delta": {
15
+ "agentRunCount": 0,
16
+ "baselineAgentRunCount": 0,
17
+ "note": "Structural graph agent.run count unchanged (no new model state); fast-lane runs save the existing review agent.run (1 fewer on triage-low diffs), retryable classification can save fixall fix hops. baselineAgentRunCount = 0938 task-pipeline agentRunCountMedian."
18
+ },
19
+ "verdict": null
20
+ },
21
+ {
22
+ "id": "check-dedup-task-pipeline",
23
+ "canonical": "task-pipeline",
24
+ "deadline": "2026-11-24",
25
+ "createdAt": "2026-09-25",
26
+ "rationale": "0940 (feature D64): the comprehensive check runs once at the quality boundary — no-progress rechecks skip the full gate to the probe path (check.skipped-no-progress) and review confirms the check receipt (check.reused) instead of re-running tests/lint. Projected basis: the 0938 baseline (docs/reports/2026-09-workflow-cost-baseline.md) measured task-pipeline wall median 7983s over 1 real terminal run with agent.run median 0; per-state rows cover only `record` (visits=0) — no test-recheck/review state-level wall deltas exist yet, so the benefit is projected as wall time (full-gate vs probe cost on no-progress loops, plus removed review-stage re-runs), not agent.run count. Measured-benefit status: projected from 0938, NOT shadow-run-confirmed; `promotion evaluate` runs post-merge against recorded runs. If it does not beat the baseline, it is reverted (ADR-076).",
27
+ "measurement": {
28
+ "workflow": "task-pipeline"
29
+ },
30
+ "delta": {
31
+ "agentRunCount": 0,
32
+ "baselineAgentRunCount": 0,
33
+ "note": "No agent.run delta by design: check dedup removes full-gate wall time on no-progress rechecks and model-stage re-runs, not model hops. baselineAgentRunCount = 0938 task-pipeline agentRunCountMedian."
34
+ },
35
+ "verdict": null
36
+ },
37
+ {
38
+ "id": "wrapup-drift-probe",
39
+ "canonical": "wrapup-pipeline",
40
+ "deadline": "2026-11-24",
41
+ "createdAt": "2026-09-25",
42
+ "rationale": "0944 (feature D64): a deterministic probe (plugins/sp/scripts/wrapup-drift-probe.ts) runs only when the caller leaves wrapup mode empty and projects mode=fast when no changed path matches a doc-owned surface (AGENTS.md doc map + docs/99_PROJECT_CONSTITUTION.md ownership table) and every task's Solution change map parsed — clean wraps then skip doc-sync via the existing fast edge (fast:drift-probe-clean), any doubt stays on the safety path. Projected basis: doc-sync costs exactly 1 agent.run per wrapup (wrapup-pipeline declares one model query; 0938 baseline docs/reports/2026-09-workflow-cost-baseline.json has 0 recorded wrapup runs — agentRunCountMedian null — so the 1 is structural, never a measured median). Measurement gap honestly named: skipping doc-sync also skips learnings capture (0607 R2 merge), so clean wraps lose per-task learnings rows; measured post-promotion by comparing .spur/memory/wrapup-routes.log fast:drift-probe-clean counts against captured <runId>-wrapup-learnings.md files. For 0946 (measurement-only confirmation): the 0938 snapshot carries per-state rows in states[] but history-anatomy has zero of them (0 recorded runs — only task-pipeline/record exists), and cache hit/miss disposition lives in the history-anatomy provenance stamp (0659/0660, history-anatomy-cache.ts), not in real-run-cost.ts; terminalReasonMix exists per workflow but history-anatomy's is empty. Measured-benefit status: projected from structure + 0938, NOT shadow-run-confirmed; `promotion evaluate` runs post-merge. If it does not beat the baseline, it is reverted (ADR-076).",
43
+ "measurement": {
44
+ "workflow": "wrapup-pipeline"
45
+ },
46
+ "delta": {
47
+ "agentRunCount": 0,
48
+ "baselineAgentRunCount": 1,
49
+ "note": "Clean wrap skips the single doc-sync agent.run (1 -> 0 for those wraps). baselineAgentRunCount = 1 structural doc-sync agent.run per wrapup run (wrapup-pipeline declares one model query — config/pipeline-budgets.json); the 0938 snapshot records 0 wrapup runs (agentRunCountMedian null), so no measured median exists yet."
50
+ },
51
+ "verdict": null
52
+ },
53
+ {
54
+ "id": "idea-pipeline-guard-legibility",
55
+ "canonical": "idea-pipeline",
56
+ "deadline": "2026-11-24",
57
+ "createdAt": "2026-09-25",
58
+ "rationale": "0945 (feature D64): the four idea-pipeline route guards (ac-generate/feature-check → system-design|decompose) read derived fact files (.spur/run/<runId>-idea-design-route.txt, <runId>-idea-ac-ready.status) written by one deterministic shell action at the end of both ac-generate and feature-check onEnter, instead of re-deriving design×needs_design and dual status reads inline — guards drop from 4-5 logical commands with (warn) markers to 3 predicates with no warn (ADR-115), and routing is proven identical by the executed truth-table test (idea-pipeline-routing.test.ts: the frozen pre-refactor guards are the oracle across profile × __hitlAnswer × design × needs_design × ac × coverage, 3456 cells, plus the guard-parity fixture refreshed per the 0874→0887 protocol). Projected basis: 0938 terminal-reason coverage for idea-pipeline is 100% classified for new runs (all nine failure-state edges declare terminalReason under 0937), so route outcomes stay measurable per terminalReason; this is projected from structure, NOT shadow-run-confirmed — promotion evaluate fills the verdict post-merge, and a losing candidate reverts (ADR-076).",
59
+ "measurement": {
60
+ "workflow": "idea-pipeline"
61
+ },
62
+ "verdict": null,
63
+ "delta": {
64
+ "agentRunCount": 6,
65
+ "baselineAgentRunCount": 6,
66
+ "note": "No agent.run delta by design: legibility derives the route facts in shell, model hops are unchanged (composition baseline modelQueries=6 in config/pipeline-budgets.json holds). baselineAgentRunCount = 0938 idea-pipeline agentRunCountMedian."
67
+ }
68
+ }
69
+ ],
5
70
  "retirements": [
6
71
  {
7
72
  "name": "planning-pipeline",
@@ -14,6 +79,12 @@
14
79
  "recordedBy": "ADR-076 (commit 017ac7a30)",
15
80
  "date": "2026-08-20",
16
81
  "rationale": "Standing parallel definition deleted with the D5-N fixture promotion bar; 5 real terminal runs retained in history."
82
+ },
83
+ {
84
+ "name": "decision-routing-example",
85
+ "recordedBy": "0946 (D64)",
86
+ "date": "2026-09-25",
87
+ "rationale": "Example-only authoring sample (0911 D7, retained-as-example 0921) retired per the mechanical catalogue rule (D64 design §10): zero real runs in the 0938 window (2026-06-01, run-record plane) and no live caller — only the plugin README catalogue row, a 0-query budget coverage entry and design/help doc mentions. YAML deleted; README row, budget entry and doc mentions removed; the decision-policy regression fixture moved to packages/app/tests/services/fixtures/decision-routing-example.yaml (workflow-service.test.ts decision-policy block). Its exit also dropped `hitl.select` from the live action union, so the inline-pipeline-parity-check DOCUMENTED set and driver mirror dropped it (parity contract). No run history deleted; 0 real terminal runs retained in history."
17
88
  }
18
89
  ]
19
90
  }
@@ -40,9 +40,17 @@ states:
40
40
  onEnter:
41
41
  # Caller wiring (task 0880, ADR-119): entering verification RUNS the
42
42
  # feature-scoped pass instead of only passively reading its status file.
43
+ # 0948 R1: pass BOTH vars the inner workflow needs. `--vars` was documented as
44
+ # replace-not-merge and a partial override silently blanked `spurBin`; the engine
45
+ # merges declared defaults today (0948 R2), but the caller stays explicit so the
46
+ # nested run is self-sufficient under either semantic.
43
47
  - kind: shell
44
48
  options:
45
- command: '$spurBin workflow run feature-verification.yaml --vars "{\"featureId\":\"$featureId\"}"'
49
+ # Pass featureId and spurBin together. A partial --vars map used to be
50
+ # applied as a replacement, so the inner run lost spurBin and loadModule
51
+ # fell into source mode (0948 R1). The nested JSON is shell-expanded:
52
+ # $spurBin inside the double quotes keeps a multi-word invocation intact.
53
+ command: '$spurBin workflow run feature-verification.yaml --vars "{\"featureId\":\"$featureId\",\"spurBin\":\"$spurBin\"}"'
46
54
  - id: blocked
47
55
  description: Impediment; work suspended.
48
56
  - id: done
@@ -68,13 +76,14 @@ transitions:
68
76
  - from: verifying
69
77
  to: done
70
78
  description: >
71
- Feature verified — complete. Requires the feature-scoped verification pass
72
- (ADR-119) to have recorded PASS, then strict check (AC validated,
73
- traceability clean).
79
+ Feature verified — complete. The strict check at the done boundary also
80
+ validates the bound verification receipt (D63 task 0915): current, PASS,
81
+ matching feature identity and verifier contract, digest-chained to the
82
+ checked inputs. Stale/missing/failed evidence denies the hop.
74
83
  guard:
75
84
  kind: shell
76
85
  options:
77
- command: 'test "$(cat .spur/run/$featureId-feature-verification.status 2>/dev/null)" = PASS && $spurBin feature check $featureId --strict --as done'
86
+ command: '$spurBin feature check $featureId --strict --as done'
78
87
 
79
88
  # Rework: verifying → active (mandatory History entry)
80
89
  - from: verifying
@@ -1,29 +1,34 @@
1
- # Feature-scoped verification pass (ADR-119, feature D62, task 0872).
1
+ # Feature-scoped verification pass (ADR-119, feature D62, task 0872; D63 task
2
+ # 0915 remediation folds the evidence contract into a workflow-owned script).
2
3
  #
3
4
  # Owns a lifecycle boundary no per-task graph owns: the repo-wide checks whose
4
- # invariant spans the repository rather than a single task's diff — corpus
5
- # consistency, contract baselines, dependency/schema drift, the frozen History
6
- # surface, and the repo-wide test set. They run once per feature, deliberately
7
- # the slow pass; `feature-lifecycle`'s verifying entry invokes this workflow (task
8
- # 0880 caller wiring), and its verifying→done guard refuses to complete the
9
- # feature until this pass records PASS (ADR-119 consequence: a feature is not
10
- # done until it passes).
5
+ # invariant spans the repository rather than a single task's diff. They run
6
+ # once per feature, deliberately the slow pass; `feature-lifecycle`'s verifying
7
+ # entry invokes this workflow (task 0880 caller wiring), and its verifying→done
8
+ # guard refuses to complete the feature until this pass records PASS (ADR-119
9
+ # consequence: a feature is not done until it passes).
11
10
  #
12
- # Run: spur workflow run feature-verification.yaml --vars '{"featureId":"D62"}'
11
+ # Run: spur workflow run feature-verification.yaml --vars '{"featureId":"D63"}'
13
12
  #
14
- # Shape: verify -> done | failed. The shell action writes the verdict to
15
- # `.spur/run/<featureId>-feature-verification.status` and always exits 0; the
16
- # transition guard reads the status so a missing, corrupt or FAIL verdict routes
17
- # to `failed` (fail-closed), never a silent PASS.
13
+ # Shape: verify -> done | failed. The onEnter step runs the standard script
14
+ # `feature-verification-steps.ts` (no public CLI verb, D63 task 0915): it
15
+ # resolves this very definition for the verifier identity (name, source path,
16
+ # layer, definition digest), records the RUNNING receipt (run-scoped +
17
+ # feature-latest copies), registers the run-scoped receipt as a run artifact,
18
+ # runs the configured verification command via the safe launch splitter, and
19
+ # completes the receipt PASS/FAIL with the after-pass proof-input digest. A
20
+ # changed tree during the pass records FAIL.
18
21
  #
19
22
  # Reliability (aligned with task-pipeline / ADR-043): no agent.run nodes; the
20
- # verification command is a trusted config var executed via `sh -c` (same
21
- # surface as task-pipeline's qualityGateCmd — never interpolate untrusted input).
23
+ # verification command comes from `vars.verificationCmd` below and is never
24
+ # interpolated through a shell. The always-exit-0 onEnter means missing,
25
+ # corrupt or FAIL evidence routes to `failed` via the guard (fail-closed),
26
+ # never a silent PASS; infrastructure errors exit nonzero and surface.
22
27
  "$schema": "@gobing-ai/spur/schemas/state-machine-workflow.schema.json"
23
28
  kind: state-machine
24
29
  name: feature-verification
25
30
  version: "1"
26
- description: "Feature-scoped verification pass (ADR-119): runs the repo-wide check set once per feature and records PASS/FAIL. Invoked by feature-lifecycle's verifying entry."
31
+ description: "Feature-scoped verification pass (ADR-119): runs the repo-wide check set once per feature and records a bound PASS/FAIL evidence receipt. Invoked by feature-lifecycle's verifying entry."
27
32
  iterationBound: 2
28
33
  initialState: verify
29
34
  terminalStates:
@@ -35,37 +40,41 @@ vars:
35
40
  featureId: "X"
36
41
  spurBin: "spur"
37
42
  verificationCmd: "bun run spur-check-feature"
43
+ __runId: ""
38
44
 
39
45
  states:
40
46
  - id: verify
41
47
  description: >
42
- Run the repo-wide check set, record the verdict, always exit 0.
48
+ Run the repo-wide check set via the standard verification script, which
49
+ records the bound evidence receipt (verifier identity, checked-input
50
+ digest, run identity) and the coarse status file, always exit 0 so the
51
+ transition guard routes missing/corrupt/FAIL to `failed`.
43
52
  onEnter:
44
53
  - kind: shell
45
54
  options:
46
55
  command: >-
47
- mkdir -p .spur/run;
48
- sh -c "$verificationCmd" > ".spur/run/$featureId-feature-verification.log" 2>&1
49
- && printf 'PASS\n' > ".spur/run/$featureId-feature-verification.status"
50
- || printf 'FAIL\n' > ".spur/run/$featureId-feature-verification.status";
51
- exit 0
56
+ bun plugins/sp/scripts/feature-verification-steps.ts verify
57
+ --feature-id "$featureId"
58
+ --run-id "$__runId"
59
+ --spur-bin "$spurBin"
52
60
 
53
61
  - id: done
54
- description: Terminal — repo-wide checks passed.
62
+ description: Terminal — repo-wide checks passed and the receipt is bound.
55
63
 
56
64
  - id: failed
57
- description: Terminal — repo-wide checks failed or the verdict is missing/corrupt.
65
+ description: Terminal — repo-wide checks failed or the evidence is missing/corrupt.
58
66
 
59
67
  transitions:
60
68
  - from: verify
61
69
  to: done
62
- description: Repo-wide checks passed — the feature-scoped verification pass records PASS.
70
+ description: Repo-wide checks passed — the script completed the receipt with PASS.
63
71
  guard:
64
72
  kind: shell
65
73
  options:
66
- command: 'test "$(cat .spur/run/$featureId-feature-verification.status 2>/dev/null)" = PASS'
74
+ command: 'test "$(cat .spur/run/$__runId-feature-verification.status 2>/dev/null)" = PASS'
67
75
  - from: verify
68
76
  to: failed
69
- description: Repo-wide checks failed (or the verdict is missing/corrupt) — stop at failed.
77
+ terminalReason: failed-check
78
+ description: Repo-wide checks failed (or the evidence is missing/corrupt) — stop at failed.
70
79
  guard:
71
80
  kind: always
@@ -11,7 +11,7 @@
11
11
  # would exceed the shell composition threshold and be flagged as an owned-capability candidate.
12
12
  #
13
13
  # Shape:
14
- # start -> resolve-scope -> resolve-paths -> analyze -> cache-probe
14
+ # start -> resolve-paths -> analyze -> cache-probe
15
15
  # (hit -> refresh-provenance -> publish -> published)
16
16
  # (miss -> render -> enrich -> structure-gate -> validate -> stamp -> publish)
17
17
  # (structure-gate FAIL -> correct (max 2 total) -> structure-gate; exhausted -> failed)
@@ -28,7 +28,7 @@
28
28
  #
29
29
  # Vars (all must be declared here — the vars: block is the only safe shape; `spur workflow
30
30
  # validate` and the skill-structure test enforce it):
31
- # mode — "daily" (default) | "ad-hoc" (validated in resolve-scope)
31
+ # mode — "daily" (default) | "ad-hoc" (validated deterministically by the helper `paths` command)
32
32
  # date — YYYY-MM-DD for --date (daily); empty for ad-hoc
33
33
  # since — inclusive ISO lower bound (ad-hoc; also normalizes daily via the DST-aware rule)
34
34
  # until — inclusive ISO upper bound (ad-hoc)
@@ -39,7 +39,7 @@
39
39
  # focus — ad-hoc focus string (required in ad-hoc mode, rejected in daily)
40
40
  # recompute — "true" forces the full analyze/render/enrich/validate path (cache disposition
41
41
  # forced-recompute)
42
- # output — explicit report output path; default run directory
42
+ # output — explicit report output path; default docs/report/<date>-history-anatomy.md
43
43
  # agent — executor for the agent.run stages (enrich/validate)
44
44
  # spurBin — PATH-independent spur invocation (overridden by CLI at run start)
45
45
  # __runId — run-scoped id for explicit artifact paths (allocated in start)
@@ -85,28 +85,22 @@ states:
85
85
  description: >
86
86
  Allocate the run-scoped id and root. Every analyze/render path in this workflow writes to
87
87
  an explicit unique path under this run id — no stage reads the mutable latest.json pointer.
88
+ The retained identity is `.spur/run/<runId>-history-anatomy-run.id` (0948 R8). The fixed
89
+ `history-anatomy-run.id` name is only a latest pointer and is overwritten by the next run.
88
90
  onEnter:
89
91
  - kind: shell
90
92
  options:
91
93
  command: >-
92
94
  mkdir -p .spur/run;
93
95
  if [ -z "$__runId" ]; then __runId=$(uuidgen | tr 'A-Z' 'a-z' | cut -c1-8); fi;
94
- echo "$__runId" > .spur/run/history-anatomy-run.id
96
+ echo "$__runId" > ".spur/run/$__runId-history-anatomy-run.id";
97
+ cp ".spur/run/$__runId-history-anatomy-run.id" .spur/run/history-anatomy-run.id
98
+ # 0948 R8 retention disposition: `history-anatomy-run.id` is a SINGLE fixed-name
99
+ # pointer that is overwritten every run — it does not accumulate, so it needs no
100
+ # reclamation path (unlike the run-record pair and legacy `.log` files, which
101
+ # `spur workflow clean --logs` owns). It is deliberately NOT a run record and is
102
+ # exempt from the catalog record-name sweep (see run-record-catalog.test.ts).
95
103
 
96
- - id: resolve-scope
97
- description: >
98
- Dispatch the skill's mode validation (0658 references/modes.md): daily is the default and
99
- rejects focus/since/until/output; ad-hoc requires a non-empty focus plus two ordered
100
- inclusive bounds and rejects --date/--recompute. Writes the normalized selector artifact.
101
- onEnter:
102
- - kind: agent.run
103
- options:
104
- agent: ${vars.agent}
105
- input: "Validate the mode arguments per sp:history-anatomy references/modes.md and write the normalized selector to .spur/run/${vars.__runId}-selector.json. mode=${vars.mode} date=${vars.date} since=${vars.since} until=${vars.until} focus=${vars.focus}. Reject conflicting arguments, naming the offending one; a rejection marks the run failed."
106
- # Declared Layer-1 role (0538 R2): mode validation is a reviewer-standard judgment.
107
- role: reviewer
108
- expectFile: .spur/run/${vars.__runId}-selector.json
109
- timeoutMs: ${vars.stepTimeoutMs}
110
104
 
111
105
  - id: resolve-paths
112
106
  description: >
@@ -122,6 +116,7 @@ states:
122
116
  h=$(superskill script path sp history-anatomy-cache.mjs);
123
117
  node "$h" paths --helper "$h" --report-dir "$reportDir" --date "$date"
124
118
  --output "$output" --mode "$mode" --since "$since" --until "$until"
119
+ --focus "$focus" --recompute "$recompute" --run-id "$__runId"
125
120
  --out .spur/run/$__runId-paths.txt
126
121
 
127
122
  - id: analyze
@@ -338,14 +333,8 @@ states:
338
333
 
339
334
  transitions:
340
335
  - from: start
341
- to: resolve-scope
342
- description: Scope resolved.
343
- guard:
344
- kind: always
345
-
346
- - from: resolve-scope
347
336
  to: resolve-paths
348
- description: Mode valid — resolve helper/skill/target paths once.
337
+ description: Mode/window grammar validated and paths resolved once (deterministic).
349
338
  guard:
350
339
  kind: always
351
340
 
@@ -402,6 +391,7 @@ transitions:
402
391
  command: 'grep -q "^PASS$" .spur/run/$__runId-structure-gate.txt 2>/dev/null'
403
392
  - from: structure-gate
404
393
  to: failed
394
+ terminalReason: retry-exhausted
405
395
  description: Structure gate FAIL with the correction cap exhausted — never publish a malformed candidate.
406
396
  guard:
407
397
  kind: shell
@@ -429,6 +419,7 @@ transitions:
429
419
  command: '! tail -n 1 .spur/run/$__runId-validation.txt 2>/dev/null | grep -qx "Verdict: PASS" && test "$(cat .spur/run/$__runId-correction-count 2>/dev/null || echo 0)" -lt 2'
430
420
  - from: validate
431
421
  to: failed
422
+ terminalReason: retry-exhausted
432
423
  description: Validation FAIL with the correction cap exhausted — terminate without publishing.
433
424
  guard:
434
425
  kind: always