@gobing-ai/spur 0.4.8 → 0.4.10

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 (211) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/pipeline-budgets.json +2 -2
  3. package/config/rules/README.md +1 -1
  4. package/config/rules/boundary/config-loading-ownership.yaml +1 -0
  5. package/config/rules/boundary/env-var-hygiene.yaml +0 -1
  6. package/config/rules/boundary/sp-plugin-standalone.yaml +1 -1
  7. package/config/rules/boundary/sp-script-placement.yaml +3 -3
  8. package/config/rules/docs/sourced-api-claims.yaml +29 -64
  9. package/config/rules/strict/runtime-boundaries.yaml +40 -1
  10. package/config/rules/structure/protected-files.yaml +1 -1
  11. package/config/rules/surface/check-cli-surface.yaml +33 -0
  12. package/config/rules/typescript/no-debugger.yaml +3 -0
  13. package/config/workflow-candidates.json +2 -2
  14. package/config/workflows/feature-verification.yaml +6 -19
  15. package/config/workflows/history-anatomy.yaml +14 -28
  16. package/config/workflows/idea-pipeline.yaml +6 -19
  17. package/config/workflows/pr-review.yaml +9 -16
  18. package/config/workflows/task-pipeline.yaml +18 -25
  19. package/config/workflows/wrapup-pipeline.yaml +21 -63
  20. package/package.json +3 -3
  21. package/plugins/sp/README.md +70 -37
  22. package/plugins/sp/agents/expert-spur.md +0 -1
  23. package/plugins/sp/agents/super-planner.md +5 -5
  24. package/plugins/sp/agents/super-reviewer.md +2 -2
  25. package/plugins/sp/commands/dev-changelog.md +1 -1
  26. package/plugins/sp/commands/dev-daily.md +1 -1
  27. package/plugins/sp/commands/dev-pr-review.md +1 -1
  28. package/plugins/sp/commands/dev-review-session.md +1 -1
  29. package/plugins/sp/commands/dev-runall.md +4 -4
  30. package/plugins/sp/commands/dev-verify.md +4 -6
  31. package/plugins/sp/commands/dev-verifyall.md +4 -5
  32. package/plugins/sp/hooks/hooks.json +11 -1
  33. package/plugins/sp/lib/context-post-tool.ts +1 -1
  34. package/plugins/sp/lib/context-session-start.ts +1 -1
  35. package/plugins/sp/lib/context-session-stop.ts +1 -1
  36. package/plugins/sp/lib/destructive-policy.ts +65 -1
  37. package/plugins/sp/plugin.json +2 -5
  38. package/plugins/sp/{hooks → scripts/hooks}/agent-lifecycle.ts +1 -1
  39. package/plugins/sp/scripts/hooks/careful-guard.ts +94 -0
  40. package/plugins/sp/{hooks → scripts/hooks}/context-post-tool.ts +2 -2
  41. package/plugins/sp/{hooks → scripts/hooks}/context-session-start.ts +1 -1
  42. package/plugins/sp/{hooks → scripts/hooks}/context-session-stop.ts +1 -1
  43. package/plugins/sp/{hooks → scripts/hooks}/fleet-guest-stop.ts +6 -4
  44. package/plugins/sp/{hooks → scripts/hooks}/task-write-guard.ts +38 -21
  45. package/plugins/sp/skills/brainstorm/SKILL.md +12 -11
  46. package/plugins/sp/skills/brainstorm/agents/openai.yaml +1 -1
  47. package/plugins/sp/skills/brainstorm/examples/ideation-example.md +0 -4
  48. package/plugins/sp/skills/brainstorm/metadata.openclaw +1 -1
  49. package/plugins/sp/skills/brainstorm/references/workflows.md +4 -14
  50. package/plugins/sp/skills/code-implementation/SKILL.md +1 -1
  51. package/plugins/sp/skills/code-verification/SKILL.md +8 -8
  52. package/plugins/sp/skills/code-verification/references/secu-review.md +4 -4
  53. package/plugins/sp/skills/code-verification/references/verdict-schema.md +9 -1
  54. package/plugins/sp/skills/daily-summary/SKILL.md +4 -5
  55. package/plugins/sp/skills/dogfood-testing/SKILL.md +9 -9
  56. package/plugins/sp/skills/dogfood-testing/references/report-template.md +1 -1
  57. package/plugins/sp/skills/history-anatomy/references/modes.md +2 -2
  58. package/plugins/sp/skills/history-anatomy/references/operations.md +3 -4
  59. package/plugins/sp/skills/history-anatomy/references/report-contract.md +2 -3
  60. package/plugins/sp/skills/issue-finding/SKILL.md +1 -1
  61. package/plugins/sp/skills/next-router/references/routing-table.md +1 -1
  62. package/plugins/sp/skills/parallel-execution/SKILL.md +2 -2
  63. package/plugins/sp/skills/parallel-execution/references/result-synthesis.md +9 -10
  64. package/plugins/sp/skills/pr-reviewing/SKILL.md +14 -15
  65. package/plugins/sp/skills/reverse-engineering/SKILL.md +4 -6
  66. package/plugins/sp/skills/session-review/SKILL.md +13 -29
  67. package/plugins/sp/skills/source-driven-development/SKILL.md +26 -27
  68. package/plugins/sp/skills/spur-check/SKILL.md +14 -13
  69. package/plugins/sp/skills/spur-cli/SKILL.md +1 -1
  70. package/plugins/sp/skills/spur-cli/references/agent.md +17 -2
  71. package/plugins/sp/skills/spur-cli/references/builder.md +27 -6
  72. package/plugins/sp/skills/spur-cli/references/features.md +6 -1
  73. package/plugins/sp/skills/spur-cli/references/history.md +3 -0
  74. package/plugins/sp/skills/spur-cli/references/self.md +5 -3
  75. package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +3 -0
  76. package/plugins/sp/skills/spur-cli/references/tasks.md +13 -3
  77. package/plugins/sp/skills/spur-cli/references/workflows/authoring-workflows.md +1 -1
  78. package/plugins/sp/skills/spur-cli/references/workflows.md +36 -1
  79. package/plugins/sp/skills/spur-dev/SKILL.md +1 -1
  80. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +1 -1
  81. package/plugins/sp/skills/spur-dev/references/dev-operations.md +12 -13
  82. package/plugins/sp/skills/spur-dev/references/execution-batch-report.md +10 -11
  83. package/plugins/sp/skills/spur-dev/references/execution-batch.md +16 -17
  84. package/plugins/sp/skills/spur-dev/references/execution-parallel-isolation.md +1 -1
  85. package/plugins/sp/skills/spur-dev/references/execution-worktree-landing.md +9 -12
  86. package/plugins/sp/skills/spur-dev/references/execution-worktree-setup.md +6 -8
  87. package/plugins/sp/skills/spur-dev/references/gate-checklists.md +1 -1
  88. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +33 -40
  89. package/plugins/sp/skills/spur-dev/references/structured-trace-emission.md +24 -24
  90. package/plugins/sp/skills/spur-doctor/SKILL.md +5 -4
  91. package/spur.js +12726 -1456
  92. package/web/_astro/{BoardApp.CaNvQBD_.js → BoardApp.B5rTVNd_.js} +1 -1
  93. package/web/_astro/{BoardApp.C5jnkkKP.js → BoardApp.BMprmPRc.js} +141 -141
  94. package/web/_astro/{TaskDetail.DGKndhI8.js → TaskDetail.Ddsur8qd.js} +1 -1
  95. package/web/_astro/{arc.DHrwdg3G.js → arc.DLqVVBxP.js} +1 -1
  96. package/web/_astro/{architectureDiagram-3BPJPVTR.pvKpK1s5.js → architectureDiagram-3BPJPVTR.C-Pk3uAi.js} +1 -1
  97. package/web/_astro/{blockDiagram-GPEHLZMM.BQmRcZsS.js → blockDiagram-GPEHLZMM.BRO1i_Nm.js} +1 -1
  98. package/web/_astro/{c4Diagram-AAUBKEIU.CCLjHeH1.js → c4Diagram-AAUBKEIU.BU_cWu6e.js} +1 -1
  99. package/web/_astro/channel.Bs3Illhy.js +1 -0
  100. package/web/_astro/{chunk-2J33WTMH.DL6Yuoma.js → chunk-2J33WTMH.D2VXiQ2t.js} +1 -1
  101. package/web/_astro/{chunk-4BX2VUAB.CzlyEI7l.js → chunk-4BX2VUAB.BcHT772J.js} +1 -1
  102. package/web/_astro/{chunk-55IACEB6.B60EWxp1.js → chunk-55IACEB6.DhDtICmo.js} +1 -1
  103. package/web/_astro/{chunk-727SXJPM.c7v_fRLo.js → chunk-727SXJPM.BoKHp7gV.js} +1 -1
  104. package/web/_astro/{chunk-AQP2D5EJ.8BxLWdDc.js → chunk-AQP2D5EJ.Chu4JRpE.js} +1 -1
  105. package/web/_astro/{chunk-FMBD7UC4.DmKuxGFT.js → chunk-FMBD7UC4.wHdwKPlq.js} +1 -1
  106. package/web/_astro/{chunk-ND2GUHAM.1Zwd4mqV.js → chunk-ND2GUHAM.ffN-M1JB.js} +1 -1
  107. package/web/_astro/{chunk-QZHKN3VN.BvYLu-A1.js → chunk-QZHKN3VN.FRubwg4S.js} +1 -1
  108. package/web/_astro/{classDiagram-4FO5ZUOK.CEqRt0WU.js → classDiagram-4FO5ZUOK.c22tQsc_.js} +1 -1
  109. package/web/_astro/{classDiagram-v2-Q7XG4LA2.CEqRt0WU.js → classDiagram-v2-Q7XG4LA2.c22tQsc_.js} +1 -1
  110. package/web/_astro/{cose-bilkent-S5V4N54A.C7JiUdj2.js → cose-bilkent-S5V4N54A.B9c6fiSj.js} +1 -1
  111. package/web/_astro/{cynefin-OW5HDTMX.B6mZ-1be.js → cynefin-OW5HDTMX.DrZsrUHl.js} +1 -1
  112. package/web/_astro/{dagre-BM42HDAG.BuryfDy6.js → dagre-BM42HDAG.DG1U4b3y.js} +1 -1
  113. package/web/_astro/{diagram-2AECGRRQ.dao39YQM.js → diagram-2AECGRRQ.CH15b-K3.js} +1 -1
  114. package/web/_astro/{diagram-5GNKFQAL.lnGZe4At.js → diagram-5GNKFQAL.BH1j7twR.js} +1 -1
  115. package/web/_astro/{diagram-KO2AKTUF.uWfhzEfT.js → diagram-KO2AKTUF.q2zCkbAj.js} +1 -1
  116. package/web/_astro/{diagram-LMA3HP47.ppq8-198.js → diagram-LMA3HP47.BLaaZnHV.js} +1 -1
  117. package/web/_astro/{diagram-OG6HWLK6.CKSCqDt5.js → diagram-OG6HWLK6.BcpRdQwI.js} +1 -1
  118. package/web/_astro/{erDiagram-TEJ5UH35.sFSf2yBN.js → erDiagram-TEJ5UH35.D7KBlqfM.js} +1 -1
  119. package/web/_astro/{flowDiagram-I6XJVG4X.BJQjKLbz.js → flowDiagram-I6XJVG4X.D_gmuRqg.js} +1 -1
  120. package/web/_astro/{ganttDiagram-6RSMTGT7.DAHKNj2N.js → ganttDiagram-6RSMTGT7.DzgWYniD.js} +1 -1
  121. package/web/_astro/{gitGraphDiagram-PVQCEYII.BlmzcW_O.js → gitGraphDiagram-PVQCEYII.576i3hm3.js} +1 -1
  122. package/web/_astro/index.DiC1a6lh.css +1 -0
  123. package/web/_astro/{infoDiagram-5YYISTIA.DGhjaqsi.js → infoDiagram-5YYISTIA.DMCclBiz.js} +1 -1
  124. package/web/_astro/{ishikawaDiagram-YF4QCWOH.gKIpgt6F.js → ishikawaDiagram-YF4QCWOH.9Kyca4SH.js} +1 -1
  125. package/web/_astro/{journeyDiagram-JHISSGLW.DG3tmP0R.js → journeyDiagram-JHISSGLW.chbdG-8q.js} +1 -1
  126. package/web/_astro/{kanban-definition-UN3LZRKU.CgHDSxkR.js → kanban-definition-UN3LZRKU.Bds54-e0.js} +1 -1
  127. package/web/_astro/{linear.BuGEpcuM.js → linear.D5ND9GN_.js} +1 -1
  128. package/web/_astro/{mermaid.core.DBVqkWBp.js → mermaid.core.D9N_PGbj.js} +4 -4
  129. package/web/_astro/{mindmap-definition-RKZ34NQL.D-kOcji9.js → mindmap-definition-RKZ34NQL.t0xop5vp.js} +1 -1
  130. package/web/_astro/{pieDiagram-4H26LBE5.BvGPwtZt.js → pieDiagram-4H26LBE5.DqgKh6hM.js} +1 -1
  131. package/web/_astro/{quadrantDiagram-W4KKPZXB.BKb_9FV6.js → quadrantDiagram-W4KKPZXB.DeuHVi2t.js} +1 -1
  132. package/web/_astro/{requirementDiagram-4Y6WPE33.Cx0fvD8v.js → requirementDiagram-4Y6WPE33.BdYFSG4W.js} +1 -1
  133. package/web/_astro/{sankeyDiagram-5OEKKPKP.fatULi0W.js → sankeyDiagram-5OEKKPKP.k1LPPETJ.js} +1 -1
  134. package/web/_astro/{sequenceDiagram-3UESZ5HK.ChHyKqco.js → sequenceDiagram-3UESZ5HK.DdyfpzoG.js} +1 -1
  135. package/web/_astro/{stateDiagram-AJRCARHV.BdUpKWyj.js → stateDiagram-AJRCARHV.DSEI8il0.js} +1 -1
  136. package/web/_astro/{stateDiagram-v2-BHNVJYJU.fmJxqIm5.js → stateDiagram-v2-BHNVJYJU.CoMnQRKo.js} +1 -1
  137. package/web/_astro/{timeline-definition-PNZ67QCA.BayDn5-V.js → timeline-definition-PNZ67QCA.DM1AHNm-.js} +1 -1
  138. package/web/_astro/{vennDiagram-CIIHVFJN.Bm2Aggwa.js → vennDiagram-CIIHVFJN.C-cJmVtl.js} +1 -1
  139. package/web/_astro/{wardleyDiagram-YWT4CUSO.DI75O-uG.js → wardleyDiagram-YWT4CUSO.D0xMzKPb.js} +1 -1
  140. package/web/_astro/{xychartDiagram-2RQKCTM6.DL90E7Q7.js → xychartDiagram-2RQKCTM6.BH5xJcEq.js} +1 -1
  141. package/web/index.html +2 -2
  142. package/config/plugin-scripts.json +0 -116
  143. package/config/script-placement-baseline.json +0 -33
  144. package/plugins/sp/hooks/careful-guard.ts +0 -74
  145. package/plugins/sp/hooks/pi/guard-extension.ts +0 -304
  146. package/plugins/sp/lib/dogfood-pipeline.ts +0 -265
  147. package/plugins/sp/lib/dogfood-report.ts +0 -278
  148. package/plugins/sp/lib/history-anatomy.generated.d.mts +0 -112
  149. package/plugins/sp/lib/history-anatomy.generated.mjs +0 -691
  150. package/plugins/sp/lib/idea-handoff.generated.d.mts +0 -17
  151. package/plugins/sp/lib/idea-handoff.generated.mjs +0 -1446
  152. package/plugins/sp/lib/inline-run-app.ts +0 -68
  153. package/plugins/sp/lib/inline-run.generated.d.mts +0 -37
  154. package/plugins/sp/lib/inline-run.generated.mjs +0 -3103
  155. package/plugins/sp/lib/plan-projection.generated.d.mts +0 -197
  156. package/plugins/sp/lib/plan-projection.generated.mjs +0 -982
  157. package/plugins/sp/lib/quality-gate.generated.d.mts +0 -139
  158. package/plugins/sp/lib/quality-gate.generated.mjs +0 -30510
  159. package/plugins/sp/lib/residual-scan.generated.d.mts +0 -93
  160. package/plugins/sp/lib/residual-scan.generated.mjs +0 -383
  161. package/plugins/sp/lib/run-summary-core.ts +0 -225
  162. package/plugins/sp/lib/spur-bin.ts +0 -36
  163. package/plugins/sp/lib/step-profile.generated.d.mts +0 -71
  164. package/plugins/sp/lib/step-profile.generated.mjs +0 -174
  165. package/plugins/sp/lib/transcript.ts +0 -112
  166. package/plugins/sp/scripts/batch-plan.mjs +0 -1096
  167. package/plugins/sp/scripts/batch-plan.ts +0 -145
  168. package/plugins/sp/scripts/batch-preflight.mjs +0 -423
  169. package/plugins/sp/scripts/batch-preflight.ts +0 -270
  170. package/plugins/sp/scripts/commit-guard.mjs +0 -226
  171. package/plugins/sp/scripts/commit-guard.ts +0 -248
  172. package/plugins/sp/scripts/daily-summary/daily-summary.mjs +0 -626
  173. package/plugins/sp/scripts/daily-summary/daily-summary.ts +0 -855
  174. package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.mjs +0 -211
  175. package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts +0 -110
  176. package/plugins/sp/scripts/dogfood-testing/validate-report.mjs +0 -282
  177. package/plugins/sp/scripts/dogfood-testing/validate-report.ts +0 -98
  178. package/plugins/sp/scripts/feature-verification-steps.mjs +0 -82
  179. package/plugins/sp/scripts/feature-verification-steps.ts +0 -164
  180. package/plugins/sp/scripts/history-anatomy-cache.mjs +0 -931
  181. package/plugins/sp/scripts/history-anatomy-cache.ts +0 -247
  182. package/plugins/sp/scripts/idea-handoff.mjs +0 -32
  183. package/plugins/sp/scripts/idea-handoff.ts +0 -47
  184. package/plugins/sp/scripts/inline-run-dispatch.mjs +0 -131
  185. package/plugins/sp/scripts/inline-run-dispatch.ts +0 -115
  186. package/plugins/sp/scripts/inline-run-setup.mjs +0 -746
  187. package/plugins/sp/scripts/inline-run-setup.ts +0 -198
  188. package/plugins/sp/scripts/persist-out-check.mjs +0 -217
  189. package/plugins/sp/scripts/persist-out-check.ts +0 -249
  190. package/plugins/sp/scripts/pr-reviewing.mjs +0 -712
  191. package/plugins/sp/scripts/pr-reviewing.ts +0 -952
  192. package/plugins/sp/scripts/quality-gate.mjs +0 -30491
  193. package/plugins/sp/scripts/quality-gate.ts +0 -80
  194. package/plugins/sp/scripts/residual-scan.mjs +0 -634
  195. package/plugins/sp/scripts/residual-scan.ts +0 -248
  196. package/plugins/sp/scripts/run-summary.mjs +0 -758
  197. package/plugins/sp/scripts/run-summary.ts +0 -107
  198. package/plugins/sp/scripts/script-root.mjs +0 -129
  199. package/plugins/sp/scripts/script-root.ts +0 -199
  200. package/plugins/sp/scripts/session-timeline.mjs +0 -359
  201. package/plugins/sp/scripts/session-timeline.ts +0 -190
  202. package/plugins/sp/scripts/task-diffstat.mjs +0 -181
  203. package/plugins/sp/scripts/task-diffstat.ts +0 -219
  204. package/plugins/sp/scripts/workflow-step-profile.mjs +0 -338
  205. package/plugins/sp/scripts/workflow-step-profile.ts +0 -165
  206. package/plugins/sp/scripts/wrapup-drift-probe.mjs +0 -190
  207. package/plugins/sp/scripts/wrapup-drift-probe.ts +0 -261
  208. package/plugins/sp/scripts/wrapup-steps.mjs +0 -627
  209. package/plugins/sp/scripts/wrapup-steps.ts +0 -891
  210. package/web/_astro/channel.C7wG9RxA.js +0 -1
  211. package/web/_astro/index.BCY1JJHd.css +0 -1
@@ -7,7 +7,7 @@
7
7
  "plugins": [
8
8
  {
9
9
  "name": "sp",
10
- "version": "0.4.8",
10
+ "version": "0.4.10",
11
11
  "source": "./plugins/sp"
12
12
  }
13
13
  ]
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "generatedAt": "2026-08-20T00:00:00.000Z",
4
- "note": "Per-pipeline model-query + wall-clock cost budgets (task 0607 R3). modelQueries anchors the live workflow definitions' query lists — the SSOT, extracted by extractResolvedWorkflowFacts and guarded by composition-baseline.test.ts (0775 retired the snapshot this file previously anchored to). wallClockMs is a gross-regression ceiling anchored to measured real-run data (R5): the gate compares the median-of-sane terminal-run wall-clock against it. A null budget is unenforced until measured — never treated as 0. Raising a numeric budget requires a fresh recorded decision in the same commit (config/pipeline-budgets.json vs git HEAD); the check-pipeline-budgets gate fails a silent raise by name.",
4
+ "note": "Per-pipeline model-query + wall-clock cost budgets (task 0607 R3). modelQueries anchors the live workflow definitions' query lists — the SSOT, extracted by extractResolvedWorkflowFacts and guarded by composition-baseline.test.ts (0775 retired the snapshot this file previously anchored to). wallClockMs is a gross-regression ceiling anchored to measured real-run data (R5): the gate compares the median-of-sane terminal-run wall-clock against it. A null budget is unenforced until measured — never treated as 0. Raising a numeric budget requires a fresh recorded decision in the same commit (config/pipeline-budgets.json vs git HEAD); the `spur workflow cost --budget` gate fails a silent raise by name.",
5
5
  "budgets": {
6
6
  "task-pipeline": {
7
7
  "modelQueries": 4,
@@ -39,7 +39,7 @@
39
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. 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.",
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 `spur history anatomy paths` op (history-anatomy-cache before script-absorption PR-6).",
43
43
  "decision": null
44
44
  },
45
45
  "wayfinder-resolution": {
@@ -17,7 +17,7 @@ install or to ts-libs.
17
17
  | `surface` | `surface/` | CLI surface consistency (registerXxxCommand wiring, --json serialization) |
18
18
  | `migration` | `migration/` | Transitional helpers for the regex → `rg` evaluator move (`rg-dialect`) |
19
19
  | `ui` | `ui/` | Web UI seam boundaries (import seam, daisyUI class leak) |
20
- | `docs` | `docs/` | Sourced API/library claims in markdown — citation anchor + HIGH/MEDIUM/LOW level. Advisory (`info`), and deliberately **not** in a preset: see the file header for its calibration audit and the one-line promotion step. |
20
+ | `docs` | `docs/` | Sourced API/library claims in markdown — same-line citation anchor (no confidence level, ADR-138). Advisory (`info`), and deliberately **not** in a preset: see the file header for its calibration audit. |
21
21
 
22
22
  ## Presets
23
23
 
@@ -67,6 +67,7 @@ rules:
67
67
  exclude:
68
68
  - "packages/config/src/**"
69
69
  - "apps/cli/src/index.ts"
70
+ - "apps/cli/src/workflow-transport.ts" # boot-free composition root of `spur workflow inline|commit-guard` (PR-4)
70
71
  - "apps/server/src/serve.ts"
71
72
  - "apps/server/src/context.ts"
72
73
  - "**/tests/**"
@@ -13,7 +13,6 @@ $schema: "@gobing-ai/spur/schemas/rule-file.schema.json"
13
13
  # gateway — because `superskill install` bundles them on targets with no
14
14
  # node_modules, where any `@gobing-ai/*` import fails ("Bundle failed", task
15
15
  # 0669). It mirrors the upstream semantics and is the one exempt file.
16
- # The `superskill script convert` `.mjs` twins remain self-contained by inlining.
17
16
  # - `apps/web` uses `import.meta.env` (Vite browser plane) — not process env, never matches.
18
17
  # - Which variables exist and who consumes them is documented in `.env.example`.
19
18
  # (The former per-var lease table moved there; the rule now enforces the funnel,
@@ -12,7 +12,7 @@ $schema: "@gobing-ai/spur/schemas/rule-file.schema.json"
12
12
  # - plugins/sp/hooks/**, plugins/sp/scripts/**, plugins/sp/lib/** may value-import
13
13
  # only `node:*` builtins and relative paths (vendored helpers live in plugins/sp/lib/).
14
14
  # - `import type` / `export type` from any package is fine — erased before bundling
15
- # (e.g. inline-run-setup.ts's type-only import from @gobing-ai/app).
15
+ # (a type-only import from @gobing-ai/app is safe).
16
16
  # - This rule is the author-time tripwire over DIRECT imports; the transitive closure
17
17
  # and the real `superskill install` path are checked by `bun run plugin-smoke`, and
18
18
  # script-contract-check Rule 5 (manifest-aware) fails the spur-check gate.
@@ -2,11 +2,11 @@ $schema: "@gobing-ai/spur/schemas/rule-file.schema.json"
2
2
  # [boundary] ADR-130 script placement contract (task 1000). Runs the fast
3
3
  # --placement-only mode of the relocated script-contract-check on every
4
4
  # recommended-pre-check; SKIPs outside the Spur source repo (same pattern as
5
- # strict/rule-files-structural.yaml SKIP on missing yq). The full twin check
6
- # stays in spur-check-feature.
5
+ # strict/rule-files-structural.yaml SKIP on missing yq). The full hook-only
6
+ # layout check (`bun run script-contract-check`) stays in spur-check-feature.
7
7
  rules:
8
8
  - id: sp-script-placement
9
- description: "Plugins/sp scripts must honor the ADR-130 placement contract (glue budget, no db imports, no corpus parsing, no noun clash); baseline config/script-placement-baseline.json can only shrink."
9
+ description: "plugins/sp and scripts/commands must honor the ADR-130 placement contract (hook entry budget, no DB driver or corpus parsing in plugin scripts/hooks/lib, no raw DB driver in scripts/commands, no noun clash, ADR-129 hook layout); any finding fails, no baseline."
10
10
  severity: error
11
11
  evaluator:
12
12
  type: exit-code
@@ -1,40 +1,18 @@
1
1
  $schema: "@gobing-ai/spur/schemas/rule-file.schema.json"
2
- # Sourced-claims rules (docs corpus) — API/library claims in markdown must be
3
- # verifiable. A bare version string or a time-anchored API claim ("deprecated
4
- # since", "added in 0.5.x") on a line with no citation anchor (http(s) URL or a
5
- # repo path:line reference) is an unverifyable claim: readers cannot tell
6
- # measured fact from model memory. The deterministic scan is line-level and
7
- # heuristic — code fences and command examples can legitimately carry bare
8
- # versions, so severity is info (advisory visibility; the recommended-pre-check
9
- # gate runs --fail-on warning, so this rule surfaces findings for review without
10
- # reddening gates — changed-file enforcement happens in SECUA review).
2
+ # Sourced-claims rules (docs corpus) — an external API/library claim in markdown
3
+ # (a bare x.y.z version, or "deprecated since / added in / removed in <v>") must carry
4
+ # a same-line citation anchor: an http(s) URL or a repo path:line. Contract owned by
5
+ # sp-source-driven-development; changed-file enforcement is SECUA review.
11
6
  #
12
- # Calibration audit (2026-10-12, `spur rule run --file … --json`, unsuppressed):
13
- # the category was pulled from `recommended-pre-check` on 2026-10-08 for "finding
14
- # noise" — 593 findings. The audit split them 580 `cited-version-strings` /
15
- # 13 `cited-api-claims`, and 579 of the 580 were false positives on two shapes
16
- # that are not external claims at all: a document's own version
17
- # (`docs/00_ADR.md:5` → `version: 1.69.0`), a section number in a heading
18
- # (`docs/04_DESIGN.md:116` → `### 1.0.1 Shared option registry`) and a
19
- # `§`-numbered cross-reference (`docs/00_ADR.md:1118` → `§1.2.1`). All three are
20
- # excluded by the pattern below — the first two on the line's shape, the third on
21
- # the token itself. The remaining source was a stale exclude list that stopped at
22
- # `docs/tasks4/` while the active corpus folder is `docs/tasks5/`, which alone
23
- # produced 226 findings; it is now one `docs/tasks*/**` glob. 593 → 330 after those
24
- # two fixes, then 277 once the `§` shape was excluded too — the residual are
25
- # version-pinned package claims that genuinely lack a same-line anchor, and they
26
- # stay visible rather than suppressed.
7
+ # Severity is info and the category is deliberately NOT in any preset: the scan is
8
+ # line-level, fires inside code fences, and its residual is a review surface, not a
9
+ # gate (2026-10-12 audit: 593 → 277 findings after the shape/`§`/excludes fixes; the
10
+ # 2026-10-16 widening admitted only verbs whose shape vouches for a version).
11
+ # Re-measure with `spur rule run --file … --json` before widening the vocabulary.
27
12
  #
28
- # The semantic contract — every external API/library claim carries a source
29
- # citation (URL or path:line) AND a confidence level (HIGH/MEDIUM/LOW) — is
30
- # owned by the sp-source-driven-development skill and verified in SECUA review
31
- # (code-verification secu-review checklist). These rules are its deterministic
32
- # backstop: the two `cited-*` rules cover the citation half, and
33
- # `cited-api-claims-confidence` covers the level half. All are severity `info`,
34
- # and the category is deliberately NOT in `recommended-pre-check` — it surfaces
35
- # findings for review without reddening gates. The 2026-10-12 audit below settled
36
- # the promotion question: the residual findings stay a review-surface concern
37
- # (SECUA checklist), not a gate one — do not add `- docs` to that preset.
13
+ # Citation only — no HIGH/MEDIUM/LOW level rule (ADR-138, task 1221): a model can
14
+ # write HIGH as easily as a claim, so the level verified nothing. The anchor is the
15
+ # evidence; do not reintroduce a level half.
38
16
  include:
39
17
  - "docs/**/*.md"
40
18
  - "plugins/sp/skills/**/references/**/*.md"
@@ -47,6 +25,11 @@ exclude:
47
25
  # fallback strips the `*` down to `docs/tasks/` — which is why that form
48
26
  # silently excluded nothing (measured 2026-10-12).
49
27
  - "docs/tasks*/**"
28
+ # Dated working records — see the "Historical-record excludes" note above.
29
+ - "docs/report*/**"
30
+ - "docs/dogfood/**"
31
+ - "docs/plans/**"
32
+ - "docs/analysis/**"
50
33
  - "drizzle/**"
51
34
  - "**/node_modules/**"
52
35
  rules:
@@ -55,8 +38,8 @@ rules:
55
38
  A markdown line asserting a version string (x.y.z) without a citation
56
39
  anchor on the same line — http(s) URL or repo path reference like
57
40
  packages/app/src/foo.ts:123 — is unverifyable. Add the anchor, or drop
58
- the version if it is not load-bearing. Confidence level (HIGH/MEDIUM/LOW)
59
- is part of the claim contract; see sp-source-driven-development.
41
+ the version if it is not load-bearing; contract in
42
+ sp-source-driven-development.
60
43
  severity: info
61
44
  evaluator:
62
45
  type: regex
@@ -66,40 +49,22 @@ rules:
66
49
  # contains a semver-ish token. Lookarounds exclude IPs (127.0.0.1),
67
50
  # longer dotted numerics, a heading's section number (`### 1.0.1 Title`),
68
51
  # a document-version metadata line (`version: 1.69.0`) and a `§`-numbered
69
- # section reference (`§7.3.1`) — none of which is an external claim;
70
- # fenced-code lines are out of regex reach — that residual noise is why
71
- # this is info, not warning. The `§` guard sits on the token itself, not on
72
- # the line, so a line carrying both a section reference and a real version
73
- # still fires on the version.
52
+ # section reference (`§7.3.1`) — none of which is an external claim.
53
+ # Fenced code and command examples can legitimately carry bare versions and
54
+ # are NOT skipped by the evaluator (measured 2026-10-16) — that residual
55
+ # noise, with the above, is why this is info, not warning. The `§` guard sits
56
+ # on the token itself, not on the line, so a line carrying both a section
57
+ # reference and a real version still fires on the version.
74
58
  pattern: "^(?!.*(?:https?://|(?:[\\w.-]+/)+[\\w.-]+:\\d+))(?!\\s*#{1,6}\\s+\\d+\\.\\d+\\.\\d+)(?!\\s*[\\w-]+:\\s*\\d+\\.\\d+\\.\\d+\\s*$).*(?<![\\d.§])\\d+\\.\\d+\\.\\d+(?!\\.\\d)"
75
59
  - id: cited-api-claims
76
60
  description: >
77
61
  A markdown line making a time- or version-anchored external API claim
78
- ("deprecated since 1.2", "introduced in v3", "available since 0.9") must
79
- carry a citation anchor on the same line — URL or repo path:line. Add the
80
- source (URL or path:line) and the confidence level (HIGH/MEDIUM/LOW);
81
- contract in sp-source-driven-development.
62
+ ("deprecated since 1.2", "introduced in v3", "removed in 0.9") must carry
63
+ a citation anchor on the same line — URL or repo path:line; contract in
64
+ sp-source-driven-development.
82
65
  severity: info
83
66
  evaluator:
84
67
  type: regex
85
68
  config:
86
69
  mode: forbid
87
- pattern: "^(?!.*(?:https?://|(?:[\\w.-]+/)+[\\w.-]+:\\d+)).*\\b(?:deprecated (?:since|in|as of)|introduced in|added in|available since|stable since)\\b"
88
- - id: cited-api-claims-confidence
89
- description: >
90
- A markdown line making a time- or version-anchored external API claim
91
- ("deprecated since 1.2", "introduced in v3", "available since 0.9") must
92
- also state its confidence level — HIGH, MEDIUM or LOW — so a reader can
93
- tell a checked fact from model memory; contract in
94
- sp-source-driven-development. Pairs with `cited-api-claims`, which covers
95
- the citation half: a line missing both halves reports once per rule,
96
- deliberately, because each missing half is its own defect.
97
- severity: info
98
- evaluator:
99
- type: regex
100
- config:
101
- mode: forbid
102
- # Fires on a claim line carrying no uppercase level token. The verbs match
103
- # `cited-api-claims` exactly, so the two rules never disagree about which
104
- # lines are claims.
105
- pattern: "^(?!.*\\b(?:HIGH|MEDIUM|LOW)\\b).*\\b(?:deprecated (?:since|in|as of)|introduced in|added in|available since|stable since)\\b"
70
+ pattern: "^(?!.*(?:https?://|(?:[\\w.-]+/)+[\\w.-]+:\\d+)).*\\b(?:deprecated (?:since|in|as of)|introduced in|added in|available since|stable since|removed (?:in|since) [vV]?\\d|(?:since|as of) (?:[vV]\\d+\\.\\d+(?:\\.\\d+)?|\\d+\\.\\d+\\.\\d+))\\b"
@@ -37,6 +37,13 @@ rules:
37
37
  - "apps/desktop/src/server-process.ts"
38
38
 
39
39
  # Low-level system primitives:
40
+ # `spur builder pr` spine (script-absorption PR-7, moved from plugins/sp/scripts/pr-reviewing.ts):
41
+ # every git/gh call goes through ONE synchronous, test-injectable CommandRunner seam
42
+ # (`setCommandRunner`); the spine is synchronous end to end (wait polls with a sync sleep).
43
+ # The ts-runtime sync executors cannot stand in: NodeSyncProcessExecutor maps a spawn
44
+ # failure (gh/git missing) to a bare exit 1 and drops the reason the spine reports, and
45
+ # both strip the final newline. Output bytes are pinned by the PR-7 golden.
46
+ - "packages/app/src/services/pr-review/index.ts"
40
47
  - "packages/app/src/services/quality-gate.ts" # gate runs `sh -c` with stdout+stderr merged onto ONE fd; ProcessExecutor captures streams separately and cannot reproduce the stream-order contract (task 1006 R1; mirrors the history-anatomy bundling exemptions)
41
48
  # The feature-verification pass runs one long command with stdout+stderr merged onto the
42
49
  # run's single log fd and a 4 h ceiling (the frozen contract from task 0915: `safe argv
@@ -44,6 +51,13 @@ rules:
44
51
  # and exposes no timeout, so it cannot reproduce either half (task 1176 R2; same class as
45
52
  # the quality-gate exemption above).
46
53
  - "packages/app/src/workflow/feature-verification-run.ts"
54
+ # `spur task wrapup` steps (script-absorption PR-5, plan §3.4), pinned to the retired plugin
55
+ # scripts' golden output by apps/cli/tests/script-absorption-pr5-parity.test.ts. The feature gate
56
+ # (`sh -c`) and `task resolve` run with stdio/stderr INHERITED so their output streams into the
57
+ # workflow run log in order, and every step is synchronous; ProcessExecutor captures the streams
58
+ # separately and cannot inherit them (same class as the quality-gate exemption above).
59
+ - "packages/app/src/workflow/wrapup/steps.ts"
60
+ - "packages/app/src/workflow/wrapup/drift-probe.ts" # sync nested `spur task show` reads beside steps.ts (same exemption)
47
61
 
48
62
  - id: no-direct-fs-io
49
63
  description: "Prefer ts-runtime's FileSystem seam for fs IO."
@@ -66,6 +80,15 @@ rules:
66
80
 
67
81
  # Low-level system primitives (O_EXCL locks, FD byte-tailing, FS watcher, atomic registry, Vite glob fallback):
68
82
  - "packages/domain/src/planning/locks.ts" # POSIX atomic O_EXCL file locks
83
+ # Script-absorption PR-6: synchronous op modules whose file bytes are pinned by the
84
+ # PR-6 golden (apps/cli/tests/script-absorption-pr6). They keep the retired scripts'
85
+ # sync node:fs reads/writes (atomic publish rename, porcelain baselines, env/report
86
+ # writes, transcript and progress reads, the daily summary file + latest.json pointer);
87
+ # the async FileSystem seam would turn every op async and reorder their output.
88
+ - "packages/app/src/services/history-anatomy-cli.ts"
89
+ - "packages/app/src/services/session-timeline.ts"
90
+ - "packages/app/src/workflow/run-summary-cli.ts"
91
+ - "packages/app/src/services/daily-summary.ts"
69
92
  - "packages/domain/src/retention.ts" # recursive backup-dir reclamation + mtime stat (task 0622 R8); ts-runtime FileSystem seam has no recursive dir remove
70
93
  - "packages/app/src/services/token-ledger-service.ts" # FD byte-window log tailing
71
94
  - "packages/app/src/services/token-ledger-watcher.ts" # node:fs watch() live watcher
@@ -78,11 +101,27 @@ rules:
78
101
  - "packages/app/src/services/history-anatomy.ts" # deterministic history-anatomy cache core (task 1005 R2): fsync'd tmp+rename atomic publish, readdir digest scans and sync report reads must stay byte-stable; bundled standalone for the bare-node plugin twin (mirrors agent-usage-producer.ts / history-service.ts exemptions)
79
102
  - "packages/app/src/observability/workflow-run-log-sink.ts" # sync FD append for mid-run tail-able all-in-one run log (task 0426 / feature D2); append() is sync from the observability bus
80
103
  - "packages/app/src/observability/agent-run-log.ts" # same primitive as the sink above for the per-run agent stream (task 1076 R1, ADR-132); append() is sync from the agent service's own onOutput hook, and the byte cap needs the FD position it tracks
104
+ # Inline-driver transports (script-absorption PR-4, `spur workflow inline|commit-guard`): moved
105
+ # verbatim from the plugin scripts with their golden output pinned; synchronous probes and
106
+ # atomic tmp+rename snapshot writes inside one short-lived CLI process.
107
+ - "packages/app/src/workflow/commit-guard.ts" # .spur/run/<run>-tree-start.json atomic snapshot + target conflict-marker reads
108
+ - "packages/app/src/workflow/persist-check.ts" # recursive evidence-tree listing + byte comparison of both trees
109
+ - "packages/app/src/workflow/run-summary-render.ts" # close-step .spur/run/<run>-summary.{md,json} write (1146 R1)
110
+ - "packages/app/src/workflow/transcript.ts" # read-only host-transcript resolution (existsSync/readdirSync)
81
111
  # commands/workflow.ts was split per verb (commands/workflow/<verb>.ts); the FD tail lives in trace.ts.
82
112
  - "apps/cli/src/commands/workflow/trace.ts" # FD byte-window tail of the mid-run run log for `workflow trace --follow` streaming (task 0428 / feature D2); readSync at offset over the observability sink's FDs
83
113
  - "apps/web/src/modules/discover.ts" # Vite/Astro module scanner fallback under bun test
84
- - "packages/app/src/services/quality-gate.ts" # gate artifacts (log/findings/receipt) written directly; merged-fd gate log and fsync-free atomic writes must stay byte-stable; bundled standalone for the bare-node plugin twin (task 1006 R1; mirrors history-anatomy.ts)
114
+ - "packages/app/src/services/quality-gate.ts" # gate artifacts (log/findings/receipt) written directly; merged-fd gate log and fsync-free atomic writes must stay byte-stable (task 1006 R1; `spur task gate` since script-absorption PR-3; mirrors history-anatomy.ts)
115
+ - "packages/app/src/workflow/wrapup/steps.ts" # `spur task wrapup` steps (script-absorption PR-5): sync status/metrics appends and run-artifact writes byte-pinned to the retired plugin scripts' golden output (apps/cli/tests/script-absorption-pr5-parity.test.ts); the FileSystem seam is async and has no append
116
+ - "packages/app/src/workflow/wrapup/drift-probe.ts" # drift-probe step beside steps.ts (same exemption)
117
+ # Script-absorption PR-3: the residual sweep and triage diffstat glue moved here from the retired
118
+ # plugin scripts (`spur task residual` / `spur task diffstat`). Same class as quality-gate.ts:
119
+ # synchronous `wx`/tmp+rename artifact writes, mtime-ordered verdict copies, and an fstat(1)
120
+ # dev/ino identity check (1067 R3) that the async FileSystem seam cannot express.
121
+ - "packages/app/src/services/residual-scan-run.ts"
122
+ - "packages/app/src/workflow/task-diffstat.ts"
85
123
  - "packages/app/src/workflow/feature-verification-run.ts" # the pass opens the run's single merged log fd (`openSync(path,'a')`) and mkdirs the run dir beside the receipt writer, exactly as the plugin entry did before the move; the fd cannot be expressed through the FileSystem seam (task 1176 R2; same class as the quality-gate exemption above)
124
+ - "packages/app/src/services/pr-review/index.ts" # `spur builder pr` (PR-7): sync --status-file verdict writes and the AGENTS.md review-rules probe inside the synchronous spine (same exemption as its process seam above)
86
125
  - "packages/app/src/services/run-storage.ts" # durable-evidence migration core (task 1025 R4): atomic tmp+rename byte copies with digest reread and atomic manifest publish must stay byte-stable (mirrors agent-usage-producer.ts / project-registry.ts exemptions)
87
126
  - "packages/app/src/services/durable-plane-ignore.ts" # .git/info/exclude append moved verbatim out of run-storage.ts to break an import cycle (same exemption)
88
127
 
@@ -42,7 +42,7 @@ rules:
42
42
  - "apps/desktop/resources/"
43
43
  # `apps/cli/plugins/` is the same kind of gitignored build:bundle output — a staged
44
44
  # npm copy of `plugins/`, itself outside the include scope. Minified generated libs
45
- # there trip the api-key shape (0976: HEAD's inline-run.generated.mjs fires too).
45
+ # there tripped the api-key shape (0976; the generated libs were retired by script-absorption PR-6).
46
46
  - "apps/cli/plugins/"
47
47
 
48
48
  - id: no-unsafe-git-commands
@@ -28,6 +28,8 @@ rules:
28
28
  exclude:
29
29
  # Per-noun shared.ts holds helpers used by 2+ verbs; it registers nothing.
30
30
  - "apps/cli/src/commands/*/shared.ts"
31
+ # Byte-exact stdout/stderr writer for the absorbed pipeline steps (script-absorption PR-5); registers nothing.
32
+ - "apps/cli/src/commands/task/step-output.ts"
31
33
  evaluator:
32
34
  type: rg
33
35
  config:
@@ -51,6 +53,37 @@ rules:
51
53
  - "apps/cli/src/commands/agent/loop.ts"
52
54
  - "apps/cli/src/commands/agent/start.ts"
53
55
  - "apps/cli/src/commands/agent/stop.ts"
56
+ # Absorbed pipeline steps (script-absorption PR-5): the app operation renders the golden-pinned
57
+ # text/JSON (planning-preflight.ts JSON.stringify for `task preflight --json`, batch-plan.ts for
58
+ # `task batch-plan`); wrapup, feature verify/handoff declare no --json. step-output.ts writes bytes.
59
+ - "apps/cli/src/commands/task/batch-plan.ts"
60
+ - "apps/cli/src/commands/task/preflight.ts"
61
+ - "apps/cli/src/commands/task/step-output.ts"
62
+ - "apps/cli/src/commands/task/wrapup.ts"
63
+ - "apps/cli/src/commands/feature/handoff.ts"
64
+ - "apps/cli/src/commands/feature/verify.ts"
65
+ # commit-guard declares no --json: its {staged, foreign} / {foreign} lines are rendered by
66
+ # @gobing-ai/spur-app/commit-guard (byte-identical to the retired script, PR-4 golden).
67
+ - "apps/cli/src/commands/workflow/commit-guard.ts"
68
+ # Pipeline-internal task verbs (script-absorption PR-3) declare no --json: their contract is
69
+ # the .spur/run artifact they write (gate status/receipt, residuals.json, diffstat.json) and
70
+ # the exit code; the gate's own status line is serialized by the app service.
71
+ - "apps/cli/src/commands/task/gate.ts"
72
+ - "apps/cli/src/commands/task/residual.ts"
73
+ - "apps/cli/src/commands/task/diffstat.ts"
74
+ # Absorbed measurement/report verbs (script-absorption PR-6): the app module serializes the
75
+ # golden-pinned JSON (step-profile-cli for `workflow profile --json`, run-summary-cli for
76
+ # `workflow summary`, session-timeline for `history timeline`, history-anatomy-cli for the
77
+ # anatomy ops); `history summary` writes Markdown and declares no --json.
78
+ - "apps/cli/src/commands/workflow/profile.ts"
79
+ - "apps/cli/src/commands/workflow/summary.ts"
80
+ - "apps/cli/src/commands/history/anatomy.ts"
81
+ - "apps/cli/src/commands/history/timeline.ts"
82
+ - "apps/cli/src/commands/history/summary.ts"
83
+ # Absorbed dogfood / PR-review spines (script-absorption PR-7): --json is rendered by
84
+ # @gobing-ai/spur-app/dogfood and @gobing-ai/spur-app/pr-review (JSON.stringify), not the CLI envelope.
85
+ - "apps/cli/src/commands/agent/dogfood.ts"
86
+ - "apps/cli/src/commands/builder/pr.ts"
54
87
  evaluator:
55
88
  type: rg
56
89
  config:
@@ -14,6 +14,9 @@ include:
14
14
  - "scripts/**/*.ts"
15
15
  exclude:
16
16
  - "**/tests/**"
17
+ # The PR-review hygiene scanner matches the word in diff text (a /\bdebugger\b/ WARN pattern);
18
+ # it holds no statement. Biome noDebugger still guards the file (script-absorption PR-7).
19
+ - "packages/app/src/services/pr-review/index.ts"
17
20
  rules:
18
21
  - id: no-debugger-statement
19
22
  description: >
@@ -7,7 +7,7 @@
7
7
  "canonical": "task-pipeline",
8
8
  "deadline": "2026-11-24",
9
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).",
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 (`spur task diffstat`, formerly 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
11
  "measurement": {
12
12
  "workflow": "task-pipeline"
13
13
  },
@@ -39,7 +39,7 @@
39
39
  "canonical": "wrapup-pipeline",
40
40
  "deadline": "2026-11-24",
41
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).",
42
+ "rationale": "0944 (feature D64): a deterministic probe (`spur task wrapup drift-probe`, packages/app/src/workflow/wrapup/drift-probe.ts since script-absorption PR-5) 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, `spur history anatomy`, formerly 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
43
  "measurement": {
44
44
  "workflow": "wrapup-pipeline"
45
45
  },
@@ -21,8 +21,9 @@
21
21
  # shipped entry no longer provides, and the entry path. Reinstalling or upgrading the
22
22
  # plugin cannot supply a retired export — only the two remedies above can.
23
23
  #
24
- # Shape: verify -> done | failed. The onEnter step runs the standard script
25
- # `feature-verification-steps.ts` (no public CLI verb, D63 task 0915): it
24
+ # Shape: verify -> done | failed. The onEnter step runs `spur feature verify`
25
+ # (D63 task 0915; script-absorption PR-5 retired the feature-verification-steps
26
+ # plugin script): it
26
27
  # resolves this very definition for the verifier identity (name, source path,
27
28
  # layer, definition digest), records the RUNNING receipt (run-scoped +
28
29
  # feature-latest copies), registers the run-scoped receipt as a run artifact,
@@ -51,34 +52,20 @@ vars:
51
52
  featureId: "X"
52
53
  spurBin: "spur"
53
54
  verificationCmd: "bun run spur-check-feature"
54
- # Operator-declared confidence level; empty derives it from the pass (HIGH when the selected
55
- # definition's own command exited 0 with an unchanged proof-input digest, MEDIUM under a caller
56
- # `--cmd` override, LOW otherwise). The completion boundary refuses a PASS carrying no level or
57
- # LOW unless the receipt records the acknowledgement below.
58
- confidence: ""
59
- # Operator acknowledgement of a LOW level. It rides the receipt, so the transition reads it from
60
- # the evidence rather than from whatever flags a later command happens to pass.
61
- ackLowConfidence: "false"
62
55
  __runId: ""
63
56
 
64
57
  states:
65
58
  - id: verify
66
59
  description: >
67
- Run the repo-wide check set via the standard verification script, which
60
+ Run the repo-wide check set via `spur feature verify`, which
68
61
  records the bound evidence receipt (verifier identity, checked-input
69
62
  digest, run identity) and the coarse status file, always exit 0 so the
70
63
  transition guard routes missing/corrupt/FAIL to `failed`.
71
64
  onEnter:
72
- # 0960 R2: run-start script-resolution identity — record which tree this run
73
- # resolved (source-repo vs installed) before the verification step runs. Never aborts.
74
65
  - kind: shell
75
66
  options:
76
67
  command: >-
77
- S=plugins/sp/scripts/script-root.ts; [ -f config/plugin-scripts.json -a -f "$S" ] || S="$(superskill script path sp script-root.mjs 2>/dev/null)"; RUNNER=bun; case "$S" in *.mjs) RUNNER=node ;; esac; [ -f "$S" ] && "$RUNNER" "$S" --run-id "$__runId" --spur-bin "$spurBin" || echo "script-root failed closed — run 'superskill install sp --marketplace gobing-ai/spur'" >&2; exit 0
78
- - kind: shell
79
- options:
80
- command: >-
81
- mkdir -p .spur/run; eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/feature-verification-steps.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/feature-verification-steps.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)"; ACK=""; [ "$ackLowConfidence" = "true" ] && ACK="--ack-low-confidence"; [ -f "$S" ] && "$RUNNER" "$S" verify --feature-id "$featureId" --run-id "$__runId" --spur-bin "$spurBin" --confidence "$confidence" $ACK || printf 'FAIL feature-verification failed closed — script not found — run superskill install sp --marketplace gobing-ai/spur\n' > ".spur/run/$__runId-feature-verification.status"; exit 0
68
+ mkdir -p .spur/run; $spurBin feature verify "$featureId" --run-id "$__runId" --no-logo || printf 'FAIL feature-verification failed closed — spur feature verify exited nonzero\n' > ".spur/run/$__runId-feature-verification.status"; exit 0
82
69
 
83
70
  - id: done
84
71
  description: Terminal — repo-wide checks passed and the receipt is bound.
@@ -89,7 +76,7 @@ states:
89
76
  transitions:
90
77
  - from: verify
91
78
  to: done
92
- description: Repo-wide checks passed — the script completed the receipt with PASS.
79
+ description: Repo-wide checks passed — `spur feature verify` completed the receipt with PASS.
93
80
  guard:
94
81
  kind: shell
95
82
  options:
@@ -4,7 +4,7 @@
4
4
  # Orchestration is configuration (ADR-022): a state machine over the existing dual-workflow
5
5
  # engine. The YAML owns ONLY the cache branch, deterministic stage ordering, executor dispatch,
6
6
  # bounded correction, and atomic publication sequencing. The deterministic cache/digest/
7
- # structure/publish work is 0659's dependency-free helper script; the judgment (mode validity,
7
+ # structure/publish work is `spur history anatomy <op>` (0659's helper, absorbed by script-absorption PR-6); the judgment (mode validity,
8
8
  # what counts as evidence, the report contract, enrich/validate rubrics) is 0658's skill. Per
9
9
  # ADR-069 R1, cache-decide / digest / structure-check / publish must NOT be inline shell — every
10
10
  # shell action here is glue length (a single helper invocation), because each of those programs
@@ -100,16 +100,6 @@ states:
100
100
  # reclamation path (unlike the run-record pair and legacy `.log` files, which
101
101
  # `spur workflow clean --logs` owns). It is deliberately NOT a run record and is
102
102
  # exempt from the catalog record-name sweep (see run-record-catalog.test.ts).
103
-
104
-
105
- # 1007 R8: run-start script-resolution identity (same command as feature-verification
106
- # verify's first action), placed AFTER the id allocation above — the snippet reads
107
- # .spur/run/$__runId-script-root.json, so it needs the allocated id. Later
108
- # plugin-script actions resolve through it (1007 R4 snippet). Never aborts.
109
- - kind: shell
110
- options:
111
- command: >-
112
- S=plugins/sp/scripts/script-root.ts; [ -f config/plugin-scripts.json -a -f "$S" ] || S="$(superskill script path sp script-root.mjs 2>/dev/null)"; RUNNER=bun; case "$S" in *.mjs) RUNNER=node ;; esac; [ -f "$S" ] && "$RUNNER" "$S" --run-id "$__runId" --spur-bin "$spurBin" || echo "script-root failed closed — run 'superskill install sp --marketplace gobing-ai/spur'" >&2; exit 0
113
103
  - id: resolve-paths
114
104
  description: >
115
105
  Resolve the helper, the skill/contract logic paths, and the publication target once, into a
@@ -118,11 +108,11 @@ states:
118
108
  onEnter:
119
109
  - kind: shell
120
110
  options:
121
- # Path arithmetic lives in the helper (ADR-069 R1); the shell only locates it. Avoid
111
+ # Path arithmetic lives in `spur history anatomy paths` (ADR-069 R1; script-absorption
112
+ # PR-6 — HA_HELPER is the running spur, HA_SKILL the resolved skill dir). Avoid
122
113
  # `${...}` here — that syntax collides with the engine's own template interpolation.
123
114
  command: >-
124
- eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/history-anatomy-cache.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/history-anatomy-cache.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)";
125
- "$RUNNER" "$S" paths --helper "$S" --report-dir "$reportDir" --date "$date"
115
+ $spurBin history anatomy paths --report-dir "$reportDir" --date "$date"
126
116
  --output "$output" --mode "$mode" --since "$since" --until "$until"
127
117
  --focus "$focus" --recompute "$recompute" --run-id "$__runId"
128
118
  --out .spur/run/$__runId-paths.txt
@@ -155,13 +145,12 @@ states:
155
145
  - kind: shell
156
146
  options:
157
147
  command: >-
158
- eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/history-anatomy-cache.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/history-anatomy-cache.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)";
159
148
  . .spur/run/$__runId-paths.txt;
160
- "$RUNNER" "$S" probe --artifact .spur/run/$__runId-history-anatomy-current.json
149
+ $spurBin history anatomy probe --artifact .spur/run/$__runId-history-anatomy-current.json
161
150
  --baseline .spur/run/$__runId-history-anatomy-baseline.json --target "$HA_TARGET"
162
151
  --mode "$mode" --date "$HA_DATE" --recompute "$recompute" --executor "$agent"
163
152
  --skill-dir "$HA_SKILL" --contract "$HA_SKILL/references/report-contract.md"
164
- --workflow "$workflowFile" --helper "$S" --contract-version "$contractVersion" --run-id "$__runId"
153
+ --workflow "$workflowFile" --helper "$HA_HELPER" --contract-version "$contractVersion" --run-id "$__runId"
165
154
  --out .spur/run/$__runId-provenance.json
166
155
  > .spur/run/$__runId-cache-disposition.txt
167
156
 
@@ -198,7 +187,7 @@ states:
198
187
  - kind: shell
199
188
  options:
200
189
  command: >-
201
- eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/history-anatomy-cache.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/history-anatomy-cache.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)"; "$RUNNER" "$S" assert-clean --baseline .spur/run/$__runId-baseline-enrich.txt --expect .spur/run/$__runId-candidate.md
190
+ $spurBin history anatomy assert-clean --baseline .spur/run/$__runId-baseline-enrich.txt --expect .spur/run/$__runId-candidate.md
202
191
 
203
192
  - id: structure-gate
204
193
  description: >
@@ -209,7 +198,7 @@ states:
209
198
  - kind: shell
210
199
  options:
211
200
  command: >-
212
- eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/history-anatomy-cache.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/history-anatomy-cache.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)"; "$RUNNER" "$S" check \
201
+ $spurBin history anatomy check \
213
202
  .spur/run/$__runId-candidate.md > .spur/run/$__runId-structure-gate.txt 2>&1 || true
214
203
 
215
204
  - id: validate
@@ -267,7 +256,7 @@ states:
267
256
  command: >-
268
257
  f=.spur/run/$__runId-validation.txt;
269
258
  if [ -f "$f" ] && [ "$(grep -cx 'Verdict: FAIL' "$f")" = 0 ] && ! tail -n 1 "$f" | grep -qx 'Verdict: PASS'; then
270
- d=$("$spurBin" decision run anatomy-validation-verdict --evidence "$f" --json || true);
259
+ d=$($spurBin decision run anatomy-validation-verdict --evidence "$f" --json || true);
271
260
  v=$(printf '%s' "$d" | jq -r 'if (.source // .data.source) == "model" and (.value // .data.value) == "PASS" then "PASS" else "FAIL" end' 2>/dev/null);
272
261
  [ "$v" = "PASS" ] || v="FAIL";
273
262
  printf 'Verdict: %s\n' "$v" >> "$f";
@@ -275,7 +264,7 @@ states:
275
264
  - kind: shell
276
265
  options:
277
266
  command: >-
278
- eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/history-anatomy-cache.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/history-anatomy-cache.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)"; "$RUNNER" "$S" assert-clean --baseline .spur/run/$__runId-baseline-validate.txt --expect .spur/run/$__runId-validation.txt
267
+ $spurBin history anatomy assert-clean --baseline .spur/run/$__runId-baseline-validate.txt --expect .spur/run/$__runId-validation.txt
279
268
 
280
269
  - id: correct
281
270
  description: >
@@ -312,7 +301,7 @@ states:
312
301
  - kind: shell
313
302
  options:
314
303
  command: >-
315
- eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/history-anatomy-cache.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/history-anatomy-cache.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)"; "$RUNNER" "$S" assert-clean --baseline .spur/run/$__runId-baseline-correct.txt --expect .spur/run/$__runId-candidate.md
304
+ $spurBin history anatomy assert-clean --baseline .spur/run/$__runId-baseline-correct.txt --expect .spur/run/$__runId-candidate.md
316
305
 
317
306
  - id: refresh-provenance
318
307
  description: >
@@ -324,9 +313,8 @@ states:
324
313
  - kind: shell
325
314
  options:
326
315
  command: >-
327
- eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/history-anatomy-cache.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/history-anatomy-cache.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)";
328
316
  . .spur/run/$__runId-paths.txt;
329
- "$RUNNER" "$S" refresh --report "$HA_TARGET"
317
+ $spurBin history anatomy refresh --report "$HA_TARGET"
330
318
  --out .spur/run/$__runId-publishable.md --disposition hit
331
319
 
332
320
  - id: stamp
@@ -339,9 +327,8 @@ states:
339
327
  - kind: shell
340
328
  options:
341
329
  command: >-
342
- eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/history-anatomy-cache.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/history-anatomy-cache.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)";
343
330
  . .spur/run/$__runId-paths.txt;
344
- "$RUNNER" "$S" stamp --candidate .spur/run/$__runId-candidate.md
331
+ $spurBin history anatomy stamp --candidate .spur/run/$__runId-candidate.md
345
332
  --provenance .spur/run/$__runId-provenance.json
346
333
  --out .spur/run/$__runId-publishable.md
347
334
 
@@ -354,10 +341,9 @@ states:
354
341
  - kind: shell
355
342
  options:
356
343
  command: >-
357
- eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/history-anatomy-cache.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/history-anatomy-cache.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)";
358
344
  . .spur/run/$__runId-paths.txt;
359
345
  mkdir -p "$(dirname "$HA_TARGET")";
360
- "$RUNNER" "$S" publish .spur/run/$__runId-publishable.md "$HA_TARGET"
346
+ $spurBin history anatomy publish .spur/run/$__runId-publishable.md "$HA_TARGET"
361
347
 
362
348
  - id: published
363
349
  description: Terminal — report published atomically after a passing validation.