@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
@@ -30,6 +30,7 @@ that before using `run` for fan-out dispatch.
30
30
  | `leave` | Leave the fleet: release the guest lease, retire the occupant, return claimed messages to `queued` | `[id]` `--session-id <sid>` `--json` |
31
31
  | `status` | Agent specs with live process status and member session (requires `spur self serve`) | `--server <url>` `--json` |
32
32
  | `doctor [agent]` | Check agent readiness | `--json` `--probe-health` `--force-refresh` |
33
+ | `dogfood <gate\|validate-report>` | `sp:dogfood-testing` gates: pipeline-driving refusal (exit 2) and report-contract validation (exit 2) | `--testee` `--max-retry-present` `--steps` `--file` `--json` |
33
34
  | `usage` | Run-once provider usage capture (codexbar) → quota-owned availability refresh; scheduled externally | `--dry-run` `--source <name>` `--json` |
34
35
  | `start <spec-id>` | Start a supervised agent process (requires `spur self serve`) | `--server <url>` `--json` |
35
36
  | `stop <spec-id>` | Stop a supervised agent process (requires `spur self serve`) | `--server <url>` `--json` |
@@ -321,6 +322,17 @@ Posts to the supervisor API
321
322
  (`POST /api/agents/:id/stop`) and prints `stopped <id>`. Same server requirement and flags as
322
323
  `start`.
323
324
 
325
+ ## `dogfood` - dogfood-testing gates
326
+
327
+ ```bash
328
+ spur agent dogfood gate --testee "/sp:dev-run 0123" --json # exit 2 = refuse (pipeline-driving, no --max-retry)
329
+ spur agent dogfood gate --testee "…" --steps "plan||implement" # Phase 1 W8 re-check
330
+ spur agent dogfood validate-report --file report.md --json # exit 2 = contract errors
331
+ ```
332
+
333
+ Absorbed from `plugins/sp/scripts/dogfood-testing/` (script-absorption PR-7). `--json` here prints
334
+ the raw result object (no envelope).
335
+
324
336
  ## `usage` - run-once provider usage capture (quota-owned availability refresh)
325
337
 
326
338
  ```bash
@@ -329,9 +341,12 @@ spur agent usage --dry-run # print would-be changes; write nothing
329
341
  spur agent usage --json
330
342
  ```
331
343
 
332
- Runs `codexbar usage --format json --provider all` once, writes the snapshot to
344
+ Runs `codexbar usage --format json` once — the operator-enabled provider set, deliberately not an
345
+ all-provider sweep (`--provider all` covers every provider configured in CodexBar, most of them
346
+ uncredentialed, and its wall time is the slowest of all of them) — writes the snapshot to
333
347
  `~/.config/spur/agent-usage.json` (`captured_at`, `source`, `providers[]`, `raw`), maps providers
334
- to executors via `agent.executors[].agent` (or the model's `<provider>/` prefix), and records
348
+ to executors via `agent.executors[].agent` (with the `antigravity-cli` → `antigravity` alias) or the
349
+ model's `<provider>/` prefix, and records
335
350
  `owner: quota` availability observations that the standard drain applies — the single availability
336
351
  write path. A provider is exhausted when any `primary|secondary|tertiary` window reports
337
352
  `usedPercent >= 100`; the window name and `resetsAt` go into the observation reason. Per-provider
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: spur-cli-builder
3
- description: "spur-cli noun reference: operate `spur builder` as the release plumbing surface - bump a workspace package (or the `workspace:`-pinned release set) with `bump-ver`, delete release tags with `drop-tags`, with commit + annotated tag + optional push. Promoted from spur-dev (task 0617, ADR-051); frozen at exactly these two verbs."
3
+ description: "spur-cli noun reference: operate `spur builder` as the release plumbing surface - bump a workspace package (or the `workspace:`-pinned release set) with `bump-ver`, delete release tags with `drop-tags`, with commit + annotated tag + optional push; publish a package to npm with `publish` (and guard version drift with `bump-ver --check`); run the `/sp:dev-pr-review` spine ops with `pr`. Promoted from spur-dev (task 0617, ADR-051); frozen at exactly these four verbs."
4
4
  see_also:
5
5
  - spur-cli
6
6
  ---
@@ -8,22 +8,24 @@ see_also:
8
8
  # spur builder - release plumbing
9
9
 
10
10
  `spur builder` is the CLI for **version bumps and release tags**. It wraps the internal
11
- `release-ops` implementation behind a public two-verb surface. The repo-local forwarder
11
+ `release-ops` implementation behind a public four-verb surface. The repo-local forwarder
12
12
  (`scripts/commands/release.ts`) and its `spur-dev` dispatcher cases were retired in task 1173; the
13
13
  root `bun run bump-ver` / `bun run drop-tags` names route to `spur builder` directly. Package ids are
14
14
  the unscoped short names (`@gobing-ai/spur` → `spur`); the released set and the aggregate tag are
15
15
  discovered from the repo's own workspace manifests, so the same code serves any git+semver
16
16
  monorepo.
17
17
 
18
- This noun is **frozen at exactly two verbs** by operator consent (`docs/design/harness-surface-governance.md`
18
+ This noun is **frozen at exactly four verbs** (`bump-ver`, `drop-tags`, plus `pr` and `publish` from the 2026-10-15 script-absorption entries) by operator consent (`docs/design/harness-surface-governance.md`
19
19
  §3) — do not invent additional `builder` subcommands.
20
20
 
21
21
  ## Verb map
22
22
 
23
23
  | Verb | Purpose | Key flags |
24
24
  | ---- | ------- | --------- |
25
- | `bump-ver [package-id] <version>` | Bump one package (manifest + in-source `binaryVersion` + consumer `workspace:` pins), commit, tag, optionally push | `--all` `--push` `--json` |
25
+ | `bump-ver [package-id] [version]` | Bump one package (manifest + in-source `binaryVersion` + consumer `workspace:` pins), commit, tag, optionally push; `--check [package-id]` only verifies marketplace/plugin versions (exit 1 on drift) | `--all` `--push` `--check` `--json` |
26
26
  | `drop-tags [package-id] <version>` | Delete a package's release tag (local only by default) | `--all` `--remote` `--json` |
27
+ | `publish <dir>` | CI npm publish: resolve `workspace:`/`catalog:` ranges, `build:bundle`, `npm publish --access public`, restore the manifest | `--otp` |
28
+ | `pr <op>` | PR-review spine ops for `/sp:dev-pr-review`: `preflight` `push` `ensure` `hygiene` `request` `wait` `collect` `status` | `--base` `--since` `--head` `--json` `--status-file` |
27
29
 
28
30
  A bare `bump-ver <version>` (single positional that parses as semver) or explicit `--all` bumps
29
31
  every package pinned via `workspace:` by another workspace package, then adds per-package trace
@@ -31,20 +33,39 @@ tags plus the aggregate `@<scope>/<root>-v<version>` publish tag. `drop-tags --a
31
33
  for deletion.
32
34
 
33
35
  **Exit codes:** `0` success, `1` error (invalid semver, unknown package id, dirty tree, detached
34
- HEAD, or an existing local/origin tag). **Errors abort before any write** — a re-run after fixing
35
- the cause is safe.
36
+ HEAD, or an existing local/origin tag). Release preflight errors abort before mutation. `publish` temporarily rewrites dependency
37
+ ranges for packaging and restores the original manifest in `finally`, including build/publish
38
+ failures; npm publication itself is an external side effect.
36
39
 
37
40
  ## `bump-ver` - bump and tag a release
38
41
 
39
42
  ```bash
43
+ spur builder bump-ver --check # aggregate marketplace/plugin version drift, read-only
44
+ spur builder bump-ver --check spur # named package drift, read-only
40
45
  spur builder bump-ver spur 0.1.4 # one package: manifest, pins, commit, tag @gobing-ai/spur-v0.1.4
41
46
  spur builder bump-ver --all 0.1.4 # every workspace:-pinned package + aggregate tag
42
47
  spur builder bump-ver --all 0.1.4 --push # also push branch + tags to origin
43
48
  ```
44
49
 
50
+ `--check` accepts only an optional package id; it rejects a version argument and `--all`/`--push`.
51
+ Normal bump mode requires a version. `publish <dir> [--otp <code>]` builds and publishes the
52
+ package using native argv, then restores the original manifest on success or failure.
53
+
45
54
  ## `drop-tags` - delete release tags
46
55
 
47
56
  ```bash
48
57
  spur builder drop-tags spur 0.1.4 # delete the local tag @gobing-ai/spur-v0.1.4
49
58
  spur builder drop-tags --all 0.1.4 --remote # delete per-package + aggregate tags, locally and on origin
50
59
  ```
60
+
61
+ ## `pr` - PR-review spine ops
62
+
63
+ ```bash
64
+ spur builder pr preflight --json # repo/gh checks
65
+ spur builder pr ensure --base main --json # reuse or create the branch PR
66
+ spur builder pr wait --since "$t" --head "$sha" --json # exit 3 = still pending
67
+ spur builder pr status --json # read-only composite status
68
+ ```
69
+
70
+ Absorbed from `plugins/sp/scripts/pr-reviewing.ts` (script-absorption PR-7); driven by
71
+ the `pr-review` workflow. Exit codes: `0` ok, `1` usage, `2` hard failure, `3` wait timeout.
@@ -30,6 +30,8 @@ what* or *how to write a scenario*, this skill.
30
30
  | `refresh` | Rebuild INDEX + each feature `## Tasks` table from task edges (**docs only**; no status change) | `--feature <id>` `--all` `--folder` `--json` |
31
31
  | `check [id]` | Validate one feature / the tree; the 4-layer gate; `--fix` repairs structural findings in place | `--strict` `--fix` `--as <status>` `--folder` `--json` |
32
32
  | `sync [id]` | Align feature **lifecycle status** with linked task states (real transitions + guards) | `--all` `--dry-run` `--force` `--folder` `--json` |
33
+ | `verify [id]` | The `feature-verification` pass: run the check set once and record the bound PASS/FAIL receipt — workflow-internal (`feature-lifecycle` runs it) | `--run-id <id>` `--cmd <command>` |
34
+ | `handoff [id]` | The `idea-pipeline` finalization: task ordering, roster refresh, handoff report — workflow-internal | `--run-id <id>` `--spur-bin <cmd>` |
33
35
 
34
36
  **`refresh` vs `sync` (do not conflate):**
35
37
 
@@ -40,7 +42,10 @@ what* or *how to write a scenario*, this skill.
40
42
 
41
43
  `refresh` never runs lifecycle gates. `sync` never rewrites the Tasks table — run both when you need both.
42
44
 
43
- All verbs accept `--json` and `--folder <path>`.
45
+ Corpus verbs advertise `--json` and `--folder <path>` in the table. The workflow-internal
46
+ `verify` and `handoff` verbs accept neither: they write run artifacts and diagnostic stdout.
47
+ `verify` exits 0 after a completed PASS or FAIL; inspect its bound receipt/status file.
48
+ An execution/usage failure exits nonzero.
44
49
 
45
50
  ## Hierarchical IDs (DD-14)
46
51
 
@@ -23,6 +23,9 @@ live in `packages/app/src/services/history-service.ts` (`FanOutResult`, `DailyRe
23
23
  | `report [path]` | Purely render an existing artifact; default to `latest.json` | `--mode <name>` `--task <wbs>` `--top <n>` `--json` |
24
24
  | `daily` | Run import-all → analyze → artifact → 90-day report pruning once | `--since <iso>` `--until <iso>` `--root <path>` `--source-timeout <ms>` `--mode <name>` `--json` |
25
25
  | `reset` | Destructively wipe every `history_*` table for a clean re-import; refuses without `--yes` | `--yes` `--json` |
26
+ | `anatomy <op>` | history-anatomy cache ops behind the `history-anatomy` workflow (`digest`, `check`, `paths`, `assert-clean`, `probe`, `stamp`, `refresh`, `publish`) | op argv (see `spur history anatomy --help`) |
27
+ | `timeline` | Per-prompt work/wait time and tokens from the host transcript (JSON), for `sp:session-review` | `--transcript <path>` `--group <spec>` |
28
+ | `summary` | Daily summary report for `sp:daily-summary` (tokens, git, history health, annotations) | `--date <d>` `--dry-run` `--output <path>` `--no-git` `--no-ccusage` |
26
29
 
27
30
  Every JSON-capable verb also advertises `--json-envelope`; use the facade's machine-output contract.
28
31
 
@@ -19,7 +19,7 @@ top-level forms are omitted from `spur --help`, leaving `self` as the visible su
19
19
  | ---- | ------- | --------- |
20
20
  | `init` | Scaffold a new Spur project in the current directory | `--name <name>` `--force` `--minimal` `--adopt-global-config` `--json` |
21
21
  | `maintain` | Run database maintenance: PRAGMA optimize, WAL truncation, optional VACUUM | `--vacuum` `--json` |
22
- | `migrate` | Apply CLI-owned schema migrations | `--json` |
22
+ | `migrate` | Apply CLI-owned schema migrations (or `--check` the importer schema) | `--check` `--json` |
23
23
  | `serve` | Start the Spur web server (local fallback) | `--port <n>` `--host <addr>` `--no-open` `--cwd <path>` `--json` |
24
24
  | `status [path]` | Show project and git status for a Spur project | `--json` |
25
25
 
@@ -63,10 +63,12 @@ Executes SQLite database maintenance operations on `.spur/spur.db`:
63
63
  ```bash
64
64
  spur self migrate # apply pending migrations
65
65
  spur self migrate --json # machine-readable { ok, applied }
66
+ spur self migrate --check # read-only importer-schema drift report (exit 1 on drift)
66
67
  ```
67
68
 
68
- Temporary helper: applies CLI-owned schema migrations and reports `{ ok, applied }`. Only flag is
69
- `--json`.
69
+ Temporary helper: applies CLI-owned schema migrations and reports `{ ok, applied }`. Flags are
70
+ `--json` and `--check`; with `--check` the command only reports importer schema drift, leaves an
71
+ absent database absent, and never repairs.
70
72
 
71
73
  ## `self serve` - start the local web server
72
74
 
@@ -465,6 +465,9 @@ spur task resolve <file-path> [--strict] [--folder] [--json]
465
465
  spur task path <wbs> [--folder] [--json]
466
466
  spur task run-link <wbs> [--source <src>] [--run-id <id>] [--json]
467
467
  spur task scaffold-tests <wbs> [--file <path>] [--folder] [--json]
468
+ spur task gate <wbs> <run|recheck|light|deferred|status> [--cmd <c>] [--probe-cmd <c>] [--proof-digest <d>] [--run-id <id>]
469
+ spur task residual <wbs> <scan|review-gate|fold|settle|report> [--root <dir>] [--tmp-dir <dir>] [--folder]
470
+ spur task diffstat <wbs>
468
471
  ```
469
472
 
470
473
  **No `delete` verb — and that is the surface's shape, not an oversight.** The corpus is
@@ -49,6 +49,9 @@ re-reading or re-tokenizing the task.
49
49
  | `migrate-anchors` | Qualify in-repo evidence anchors to repo-relative paths (0583 R1–R3); `--wbs` scopes to one task file (1109 R1); retargets scratch `done_reason` verdict pointers (1140) | `--wbs` `--dry-run` `--json` |
50
50
  | `refresh-roster <wbs>` | Regenerate a parent task's sub-task roster block in `## Plan` | `--folder` `--json` |
51
51
  | `batch-create` | Create many tasks from a validated JSON array | `--file <path>` `--skip-ready` `--agent <selector>` `--folder` `--json` |
52
+ | `batch-plan <mode>` | Batch plan projection: `waves` / `order` / `task-children` (JSON on stdout; the batch driver's visible plan) | `--tasks <file>` `--concurrency <n>` `--letter <A-Z>` `--plan <file>` |
53
+ | `preflight [wbs]` | Read-only batch admission: TABLE A STOP check, quick readiness (`--operation`), one-shot recovery hop; status/deps read from the corpus unless given | `--status <s>` `--deps <list>` `--dep-status <map>` `--operation <op>` `--filtered-count <n>` `--required-sections <list>` `--present-sections <list>` `--force` `--recovery` `--classify-feature <json>` `--folder` `--json` |
54
+ | `wrapup <op>` | One deterministic `wrapup-pipeline` step (`resolve`, `route-reason`, `metrics`, `feature-transition`, `doc-sync-snapshot`, `doc-sync-scope`, `doc-supersession`, `drift-probe`) — workflow-internal | `--run-id <id>` `--tasks <json>` `--mode <m>` `--feature <id>` `--feature-gate-cmd <cmd>` `--spur-bin <cmd>` |
52
55
  | `record <wbs>` | Write `Testing` from a verify verdict (deterministic); bare-`## Review` fallback only; optional Solution + transition | `--verdict-file <path>` `--solution-from-diff` `--transition <status>` `--folder` `--json` |
53
56
  | `verdict <wbs>` | Derive PASS/PARTIAL/FAIL/UNKNOWN from verify answer text → verdict JSON; see [answer-file shape](tasks/verbs.md#answer-file-shape-what---from-answer-parses) | `--from-answer <path>` `--folder` `--json` |
54
57
  | `check [wbs]` | Four-layer validation; `--fix` repairs structure; `--corpus` is the explicit unsuppressed audit; `--precheck` adds the pipeline precheck gate (size + evidence channel, WBS required) | `--strict` `--as <status>` `--strict-core` `--precheck` `--fix` `--folder` `--corpus` `--since <ref>` `--json` |
@@ -57,9 +60,16 @@ re-reading or re-tokenizing the task.
57
60
  | `run-link <wbs>` | Record pipeline run provenance link for task | `--source <src>` `--run-id <id>` `--json` |
58
61
  | `verifyall-aggregate` | Aggregate per-task verify outcomes into a batch verdict (NOT-STARTED excluded) | `--from-file <path>` `--json` |
59
62
  | `scaffold-tests <wbs>` | Generate BDD test stubs from task Acceptance Criteria | `--file <path>` `--folder` `--json` |
60
-
61
- All verbs accept `--json` for machine consumption and `--folder <path>` to target a non-default
62
- tasks folder. **Exit codes:** `0` success, `1` error, `2` invalid usage.
63
+ | `gate <wbs> <mode>` | Task-pipeline quality gate (`run`, `recheck`, `light`, `deferred`, `status`); mode-specific exits and fingerprint-bound receipts (see `sp:spur-check`) | `--cmd <c>` `--probe-cmd <c>` `--proof-digest <d>` `--run-id <id>` |
64
+ | `residual <wbs> <step>` | F96 residual sweep step (`scan`, `review-gate`, `fold`, `settle`, `report`) | `--root <dir>` `--tmp-dir <dir>` `--folder` |
65
+ | `diffstat <wbs>` | Write the triage diffstat artifact against the run base (fails safe to `sensitive: true`) | — |
66
+
67
+ Use only the flags listed for the selected verb. `batch-plan` emits JSON without `--json`;
68
+ `wrapup`, `gate`, `residual` and `diffstat` use their operation-specific stdout/artifact contracts.
69
+ `run-link`, `verifyall-aggregate` and `migrate-anchors` accept `--json` but no `--folder`;
70
+ `residual` accepts `--folder` but no `--json`. Do not append shared flags to every command.
71
+ General exit codes are `0` success, `1` error, `2` invalid usage; consult the operation contract
72
+ for soft gate modes and specialized refusal codes.
63
73
 
64
74
  ## Creating tasks
65
75
 
@@ -138,7 +138,7 @@ Spur's host additionally registers (`registerSpurBuiltins`, `packages/app/src/wo
138
138
 
139
139
  | Kind | Capability |
140
140
  | ---- | ---------- |
141
- | Action | `agent.run` (model call via `spur agent run`; `executor: 'fleet'` dispatches into the agent fleet), `decide` (inline `id`/`method`/`question`/`choices`/`default`/`evidence` → outcome written to `resultFile`; catalog-id references are pending task 1094 — use `spur decision run` for catalog decisions), `command.gate`, `rule.check`, `doctor.probe`, `response.validate`, `proof.fingerprint`, `run.artifact`, `file.exists`, `file.read`, `file.read.into-var`, `http.request`, `hitl.confirm`, `hitl.select`, `hitl.input`, `shell` (streaming) |
141
+ | Action | `agent.run` (model call via `spur agent run`; `executor: 'fleet'` dispatches into the agent fleet), `decide` (inline `id`/`method`/`question`/`choices`/`default`/`evidence` → outcome written to `resultFile`; catalog-id references are pending task 1094 — use `spur decision run` for catalog decisions), `command.gate`, `rule.check`, `doctor.probe`, `proof.fingerprint`, `run.artifact`, `file.exists`, `file.read`, `file.read.into-var`, `http.request`, `hitl.confirm`, `hitl.select`, `hitl.input`, `shell` (streaming) |
142
142
  | Guard | `shell` (env-aware), `contract-violation` |
143
143
 
144
144
  Order matters for both guards and conditions: **the first that passes wins.** Put the discriminating
@@ -97,7 +97,7 @@ Use this skill to:
97
97
 
98
98
  The skill's logic divides by **whether the LLM adds value**:
99
99
 
100
- - **Direct CLI** (`validate`, `run`, `list`, `trace`, `progress`, `continue`, `cancel`, `clean`) — deterministic,
100
+ - **Direct CLI** (`validate`, `run`, `list`, `trace`, `progress`, `summary`, `profile`, `cost`, `continue`, `cancel`, `clean`) — deterministic,
101
101
  single-verb commands. Run them straight. A slash-command wrapper would only forward flags and add
102
102
  drift; **there is no command for these — use the CLI**. The skill still drives them in natural
103
103
  language (interpreting a failed validate, reading a run trace).
@@ -116,6 +116,11 @@ The skill's logic divides by **whether the LLM adds value**:
116
116
  | `list` | `spur workflow list` (CLI) | — | Available workflow **YAML definition files** (not run records) |
117
117
  | `trace` | `spur workflow trace` (CLI) | `[run-id] [--workflow <n>] [--status <s>] [--since <iso>] [--last <n>] [--follow] [--poll <ms>] [--output] [--timeout <ms>]` | Run history list or per-run timeline |
118
118
  | `progress` | `spur workflow progress` (CLI) | `<run-id>` | The `projectWorkflowProgress` projection for that run — current state, per-action attempts, candidate next transitions, diagnostics. Read-only; the verb renders, `packages/app` derives. Unknown run id exits 1 with `Run <id> not found.` |
119
+ | `summary` | `spur workflow summary` (CLI) | `--progress <[label=]file>`… \| `--rollup <[label=]file>`… `[--transcript] [--since] [--markdown]` | Measured execution summary (per-stage time, wait, tool calls, tokens, actor split) or the batch roll-up `/sp:dev-runall` prints. `n/a` exit 0 without a transcript; exit 2 on usage or unreadable input |
120
+ | `profile` | `spur workflow profile` (CLI) | `<workflow> [--last n] [--window sec] [--spur-bin cmd] [--json]` | Read-only per-node step profile from `spur workflow trace` with the ADR-115 cache-window flags, for `sp:spur-doctor`. Exit 1 when a trace read fails |
121
+ | `cost` | `spur workflow cost` (CLI) | `[--workflow <name>]… [--by-state] [--include-bookkeeping] [--since <date>] [--budget <file>] [--measured-file <json>] [--json]` | Real terminal non-dry run measurements, or a budget result; unknown measurements stay null. Budget failures exit 1 |
122
+ | `inline` | `spur workflow inline <op>` (CLI) | `begin`, `fingerprint`, `node-enter`, `action`, `actions`, `close`, `decide`, `persist-out`, `persist-check`, `attribution`, `dispatch-failure` | The host-inline driver's run lifecycle transport ([inline-pipeline-driver.md](../../spur-dev/references/inline-pipeline-driver.md)); exit 0 ok / 1 fail closed / 2 usage |
123
+ | `commit-guard` | `spur workflow commit-guard <op>` (CLI) | `start\|stage\|check --run <id> [--base <sha>] [-- <paths…>]` | Stages only paths this run wrote; exit 2 when a listed path is refused, 3 on unmerged/conflict-marked targets |
119
124
  | `add` | agent procedure | `"<nl-description>" [--kind <state-machine\|transition-flow>] [--file <path>]` | **Mode chosen (confirmed)** → first reconciled against existing workflows (extend an existing flow rather than duplicate) → YAML authored in real schema shape → **validated AND dry-run** (reaches the expected terminal state) → [add](workflows/operations.md#add) |
120
125
  | `refine` | agent procedure | `<workflow-file> [--intent "<goal>"] [--dry-run]` | Smallest change meeting the intent, re-validated and re-dry-run; `--dry-run` emits a diff only → [refine](workflows/operations.md#refine) |
121
126
 
@@ -266,8 +271,38 @@ spur workflow clean [--older-than <minutes>] [--force] [--logs] [--dry-run] [
266
271
  spur workflow list [--json]
267
272
  spur workflow trace [run-id] [--workflow <name>] [--status <s>] [--since <iso>] [--last <n>] [--follow] [--poll <ms>] [--output] [--timeout <ms>] [--json]
268
273
  spur workflow progress <run-id> [--json]
274
+ spur workflow summary (--progress <[label=]file>... | --rollup <[label=]file>...) [--transcript <path>] [--since <iso>] [--markdown]
275
+ spur workflow profile <workflow> [--last <n>] [--window <sec>] [--spur-bin <cmd>] [--json]
276
+ spur workflow cost [--workflow <name>]... [--by-state] [--include-bookkeeping] [--since <YYYY-MM-DD>] [--budget <file>] [--measured-file <json>] [--json]
277
+ spur workflow inline <op> [options]
278
+ spur workflow commit-guard <op> [options]
269
279
  ```
270
280
 
281
+ ### `cost` — real-run measurements and budgets
282
+
283
+ `spur workflow cost` reads `.spur/spur.db`; its default cohort is the project definitions in
284
+ `.spur/workflows/`, excluding bookkeeping. Use repeatable `--workflow <name>` filters to select
285
+ workflows explicitly; bookkeeping names still require `--include-bookkeeping`. Report mode
286
+ considers terminal, non-dry runs; `--since YYYY-MM-DD` filters
287
+ creation time in UTC. Missing measurements remain unknown (`null`), never fabricated zeros.
288
+
289
+ `--json` emits the stable workflow/state report; `--by-state` selects human state rows when JSON
290
+ is not requested. `--budget <file>` instead emits the budget result (including `ok`, errors and
291
+ exitCode with `--json`) and exits 1 for over-budget, missing-budget or silent-raise failures.
292
+ `--measured-file <json>` is valid only with `--budget`. Budget mode uses its own cohort inputs;
293
+ report-only `--since`, `--by-state` and `--include-bookkeeping` do not change the budget pass.
294
+ Repository promotion policy keeps its selected-run domain query; aggregate cost JSON does not
295
+ replace that distribution.
296
+
297
+ ### CLI launch strings
298
+
299
+ Workflow `spurBin` defaults to the current absolute CLI invocation: a compiled executable, or
300
+ `<runtime> <entry-module>` for source/JavaScript installs. Shell actions expand this multi-part
301
+ string as `$spurBin`, not `"$spurBin"`; quoting the whole value makes it one executable name.
302
+ The current string transport requires launch paths without spaces. Native `splitLaunchCommand`
303
+ consumers also reject shell metacharacters and shell-quoted command strings; shell expansion itself
304
+ does not validate those strings. Native callers with explicit launch argv preserve argument boundaries.
305
+
271
306
  ### `show` - project a definition
272
307
 
273
308
  `spur workflow show <file>` renders the declared graph as Mermaid. `--format todo` instead emits a
@@ -66,7 +66,7 @@ lifecycle, the gates, and the section-write contract (`cross-cutting.md`).
66
66
  ```
67
67
  vague description
68
68
  → intake (clarify scope, constraints — prompt work)
69
- → spur feature create … ; AC authored/generated (spur agent run, bdd templates)
69
+ → spur feature create … ; AC authored/generated (host-inline competency, BDD templates)
70
70
  → GATE: spur feature check (BDD validator; loop until clean)
71
71
  → decomposition (prompt work) → task-batch JSON
72
72
  → GATE: task-batch.schema.json + spur task batch-create (atomic: all-or-nothing)
@@ -258,7 +258,7 @@ procedure and do not fabricate a workflow YAML.
258
258
  inventory with `columnLabel` labels; the skill-only refine/verify batches keep the bootstrap rows
259
259
  below.
260
260
  2. **Quick deterministic readiness (R2) — plan row A1, before isolation.** Evaluate `quickReadiness`
261
- (`plugins/sp/scripts/batch-preflight.ts`) with the operation, status, filtered-set size, and the
261
+ (`spur task preflight <wbs> --operation <op>`) with the operation, status, filtered-set size, and the
262
262
  selected matrix required/present sections + content-policy findings. This is an admission decision
263
263
  (runnable / needs-refinement / blocked / skipped / invalid), never an implementation certificate.
264
264
  3. **Isolation (R3) — plan row A2, only when `--worktree` is valid.** After quick readiness and the
@@ -60,7 +60,7 @@ each would be scope creep for one-liner procedures.
60
60
  > See `plugins/sp/skills/next-router/references/routing-table.md` for the routing SSOT.
61
61
  >
62
62
  > **Batch consumer (task 0279):** `sp:super-planner` / `/sp:dev-runall` **consumes** TABLE A STOP rows
63
- > for preflight + one-shot recovery (`plugins/sp/scripts/batch-preflight.ts`) but keeps
63
+ > for preflight + one-shot recovery (`spur task preflight`) but keeps
64
64
  > `task-pipeline.yaml` as the happy path. Do **not** deep-merge batch orchestration into a loop of
65
65
  > `/sp:dev-next`. Single-task "what's next?" stays `/sp:dev-next`; multi-task execution stays
66
66
  > `/sp:dev-runall` → super-planner.
@@ -139,7 +139,7 @@ must not be changed without updating the backing skill.
139
139
  - **Inputs:** `<wbs>` (required). Verify executes inline (in-session) by default. `--agent <inline|auto|name>` selector accepted (see [SSOT](cross-cutting.md#inline-default-execution-surface)). `--fix`, `--focus`, `--bdd`, `--auto`, `--force` modulate the verify pass. `--next` (terminal chain link): on the **post-`--fix`** PASS verdict, transition `testing → done` through the FSM (target-aware `--as done` guard honored). On PARTIAL/FAIL or guard failure, stop as review-pending. **`--skip-shippable`** (alias `--skip-shipable`): disable the shippable gate that otherwise runs under `--fix all` when the task has a `feature_id`.
140
140
  - **Backing:** `sp:code-verification` skill, `verify` mode.
141
141
  - **Behavior:** Status guard → change-scope detection → requirements traceability → SECUA review → verdict aggregation → findings write-back → verdict-artifact emission → optional `--fix` pass → **shippable readiness** (when active). The per-task verdict gates the pipeline's `done` transition. With `--next`: the (post-`--fix`) PASS verdict → transition to `done` (FSM guard honored); PARTIAL/FAIL → stop and surface verdict. Shippable FAIL does not rewrite the task verdict line but must be printed; feature is not “ready.”
142
- - **Shippable readiness (default on with `--fix all`):** After the task verdict, if `--fix all` and the task has `feature_id` and not `--skip-shippable`, run `spur feature check <id> --json` + linked-task completeness. Emit `Shippable: PASS|FAIL|N/A`. FAIL when feature AC scenarios are orphaned/unverified or any linked task is not `done`/`cancelled`. SSOT procedure: `sp:code-verification` Step 13.
142
+ - **Shippable readiness (default on with `--fix all`):** After the task verdict, if `--fix all` and the task has `feature_id` and not `--skip-shippable`, run `spur feature check <id> --as done --strict --json` + linked-task completeness. Failed/missing completion receipts or required dogfood evidence also block shipping. Emit `Shippable: PASS|FAIL|N/A`. FAIL when feature AC scenarios are orphaned/unverified or any linked task is not `done`/`cancelled`. SSOT procedure: `sp:code-verification` Step 13.
143
143
  - **Delegation:** `Skill(skill="sp:code-verification", args="verify $ARGUMENTS")`
144
144
 
145
145
  ### 3a. verifyall
@@ -165,16 +165,16 @@ must not be changed without updating the backing skill.
165
165
 
166
166
  #### Execution summary
167
167
 
168
- Produced by the run's own close (1146 R1), not by a trailing step: `inline-run-setup --close` writes
168
+ Produced by the run's own close (1146 R1), not by a trailing step: `spur workflow inline close` writes
169
169
  `.spur/run/<runId>-summary.md` + `.json` and reports `summaryFile` in its stdout JSON. The driver's only
170
170
  job is to print that file's contents under an `### Execution summary` heading, and to pass `--no-summary`
171
- through to `--close`. `--no-summary` is a `--close` flag: anywhere else it is a usage error.
171
+ through to `inline close`. `--no-summary` is an `inline close` flag: anywhere else it is a usage error.
172
172
 
173
173
  `/sp:dev-runall` shows one summary per run — each produced by that run's own close, so each window is its own
174
174
  `runs.started_at` → close time and no block reuses a batch-wide window — plus one batch roll-up:
175
175
 
176
176
  ```
177
- node "$(superskill script path sp run-summary.mjs)" --rollup <runId>-summary.json --rollup <runId2>-summary.json
177
+ spur workflow summary --rollup <runId>-summary.json --rollup <runId2>-summary.json
178
178
  ```
179
179
 
180
180
  which renders one row per run (that run's own Total) and a bold total of the sums; when run windows overlap it
@@ -193,7 +193,7 @@ check receipt (`receipt.runId === runId`), otherwise `n/a (<reason>)`. Any value
193
193
 
194
194
  - **Purpose:** Refine a task's requirements via structured Q&A — clarify scope, elicit missing details, tighten acceptance criteria before execution. Optional **implement-ready** depth freezes Design/Requirements/Plan so another agent can implement without inventing design, and is also the path for **evaluating and correcting an existing task** — a review-triage filing, a stale backlog capture, or any task whose claims and proposed fixes may no longer hold.
195
195
  - **Inputs:** `<wbs>` (required). `--focus <mode>` narrows the gap analysis (values below). `--description <text>` injects operator framing into the Q&A/synthesis. `--depth <standard|ready>` (default **`standard`**) sets the depth bar — see [flag-glossary.md](flag-glossary.md#flag-depth). Execution defaults to inline (in-session); `--agent <inline|auto|name>` selector accepted (see [SSOT](cross-cutting.md#inline-default-execution-surface)). `--auto` skips interactive Q&A (synthesis only) and propagates down the `--next` chain. `--next`: advance to the next step — transition `backlog → todo` through the FSM **idempotently** (only when `status == backlog`; a task already at `todo` or past it skips the transition and chains anyway — `status >= todo` ⇒ already advanced) and invoke `/sp:dev-run <wbs> --mode implement --auto --next`. On a guard/refine failure, stop as review-pending.
196
- - **Status scope:** refine targets `backlog`/`todo` tasks (the same rule `batch-preflight` applies to refineall). A task at `wip` or later has an implementation built on its current spec. Refine it only on an explicit operator request, never under `--auto` alone, and never move its status backwards.
196
+ - **Status scope:** refine targets `backlog`/`todo` tasks (the same rule `spur task preflight` applies to refineall). A task at `wip` or later has an implementation built on its current spec. Refine it only on an explicit operator request, never under `--auto` alone, and never move its status backwards.
197
197
  - **`--focus` values** (hint bundles for the gap analysis/Q&A; default `all`):
198
198
 
199
199
  | Value | Domain hints | When |
@@ -481,7 +481,7 @@ gate commands, pending questions and approval requirements.>
481
481
  ### 13. runall
482
482
 
483
483
  - **Purpose:** Run a batch of tasks through their pipelines in dependency-correct order — resolve a set, topo-sort, run each via `task-pipeline.yaml`, inspect verdicts, apply the failure policy, emit a batch report.
484
- - **Inputs:** `--tasks <selector>` (required — explicit WBS list, status pseudo-list, `feature:<id>`, or `ready`). `--mode <sequential|parallel>` (default `sequential`; `parallel` fans out a proven-independent subset per `execution-batch.md` § Parallel Execution). `--keep-going` skips a failed task's in-batch dependents and continues independents (default halts on first failure). `--auto` sets `profile=auto` on each per-task run (skips the HITL approve gate). `--feature <id>` is sugar for `--tasks feature:<id>`; when the effective selector is feature-derived, the batch runs `spur feature check <id> --fix --json` then `spur feature check <id> --strict --json` **once** before task resolution — a non-zero strict check aborts with verdict `aborted`, zero attempted tasks, and the structured findings (task 0510 R2); scoped: `L4.scenario-unverified` and `L4.verifying-incomplete-tasks` (expected pre-run states of a not-yet-run or reopened feature) are reported verbatim but do not abort — the non-aborting set is `NON_ABORTING_PREFLIGHT_CODES` in `plugins/sp/scripts/batch-preflight.ts` and `--fix` repairs are listed under `autoRepairs` — any other strict error aborts. Explicit WBS/status/`ready` selectors add no feature check. The orchestrator loop itself continues in this session; interactive sequential omit/`inline` uses the host driver — host-controlled with eligible `agent.run` stages dispatching once to a native subagent and host fallback (task 0508) — while `--agent auto`/a name, parallel mode, and headless invocation keep the isolated per-task workflow subprocess boundary. `--agent <inline|auto|name>` pins the executor for the per-task stages (see [SSOT](cross-cutting.md#inline-default-execution-surface)); the value crosses into per-task `vars.agent`, not the orchestrator. `--json` emits the report as JSON. `--wrap` triggers `wrapup-pipeline.yaml` **once for the batch** over the `done` subset only (execution-batch.md Step 6: `vars.feature` only when every frozen task is `done`/`cancelled`; empty done subset skips with a reason), `--next` chains each task to terminal status then runs the same batch-once wrap, `--continue` resumes from checkpoint. `--no-summary` skips the [execution summary](#execution-summary) printed after the batch report (one row per attempted run).
484
+ - **Inputs:** `--tasks <selector>` (required — explicit WBS list, status pseudo-list, `feature:<id>`, or `ready`). `--mode <sequential|parallel>` (default `sequential`; `parallel` fans out a proven-independent subset per `execution-batch.md` § Parallel Execution). `--keep-going` skips a failed task's in-batch dependents and continues independents (default halts on first failure). `--auto` sets `profile=auto` on each per-task run (skips the HITL approve gate). `--feature <id>` is sugar for `--tasks feature:<id>`; when the effective selector is feature-derived, the batch runs `spur feature check <id> --fix --json` then `spur feature check <id> --strict --json` **once** before task resolution — a non-zero strict check aborts with verdict `aborted`, zero attempted tasks, and the structured findings (task 0510 R2); scoped: `L4.scenario-unverified` and `L4.verifying-incomplete-tasks` (expected pre-run states of a not-yet-run or reopened feature) are reported verbatim but do not abort — the non-aborting set is `NON_ABORTING_PREFLIGHT_CODES` behind `spur task preflight --classify-feature` and `--fix` repairs are listed under `autoRepairs` — any other strict error aborts. Explicit WBS/status/`ready` selectors add no feature check. The orchestrator loop itself continues in this session; interactive sequential omit/`inline` uses the host driver — host-controlled with eligible `agent.run` stages dispatching once to a native subagent and host fallback (task 0508) — while `--agent auto`/a name, parallel mode, and headless invocation keep the isolated per-task workflow subprocess boundary. `--agent <inline|auto|name>` pins the executor for the per-task stages (see [SSOT](cross-cutting.md#inline-default-execution-surface)); the value crosses into per-task `vars.agent`, not the orchestrator. `--json` emits the report as JSON. `--wrap` triggers `wrapup-pipeline.yaml` **once for the batch** over the `done` subset only (execution-batch.md Step 6: `vars.feature` only when every frozen task is `done`/`cancelled`; empty done subset skips with a reason), `--next` chains each task to terminal status then runs the same batch-once wrap, `--continue` resumes from checkpoint. `--no-summary` skips the [execution summary](#execution-summary) printed after the batch report (one row per attempted run).
485
485
  - **Three orthogonal axes (do not confuse):** `--keep-going` = batch failure policy (halt vs skip dependents); `--continue` = resume from checkpoint against the batch's original frozen identity (execution-batch.md § Batch continuation, task 0919); `--next` = per-task lifecycle chaining (advance status on a verdict — `dev-verify`/`dev-verifyall` only). `routing-table.md` offers `--continue` and `--next` as competing options for the same situation only when the batch was interrupted mid-run; otherwise they address different problems.
486
486
  - **Backing:** `sp:spur-dev` skill, `runall` operation → delegates the driver loop to the **`sp:super-planner`** agent (the batch orchestrator).
487
487
  - **Behavior:** The orchestrator reads [execution-batch.md](execution-batch.md) and drives: resolve selector → freeze set → topo-sort by `dependencies[]` (Kahn, WBS-ascending tie-break; cycle aborts) → resolve out-of-set deps by status (done → allow, else → block subtree) → run each task via `spur workflow run task-pipeline.yaml --async` + `spur workflow trace` polling → inspect terminal state + `.spur/run/<wbs>-verdict.json` → stop-the-batch default or `--keep-going` subtree skip → emit batch report. Per-task pipeline is invoked **verbatim** — no new FSM, no step edits. `--auto`/`--agent` are the only flags that cross the orchestrator→pipeline boundary (both into per-task `--vars`).
@@ -590,12 +590,11 @@ host instructions does not add one. An opt-in gate is explicit: `gitmsg --check
590
590
  - `keepachangelog` (default): `## [<version>] - <date>` header, then category headings per the keepachangelog convention — `### Added` / `### Fixed` / `### Changed` / `### Removed` / `### Other` — mapped from conventional-commit types.
591
591
  - `simple`: flat bulleted list grouped by type heading (`### feat`, `### fix`, …).
592
592
  6. Emit: with `<file>`, insert the section into that file above its newest `## [` release heading (or after its title when none exists) and touch nothing else in the file; without `<file>`, print it to stdout.
593
- 7. **Verify claims before emitting:** scan the generated bullets for API/library claims — bullets asserting what code, APIs, libraries, dependencies, or versions do (skip merge/bookkeeping bullets that assert no such fact). Verify each affected bullet, then append an HTML comment line directly under it: `<!-- src: <citation> · <HIGH|MEDIUM|LOW> -->`.
594
- - Internal claims (what a commit or the code does): confirm against the commit diff (`git show --stat <hash>`, reading hunks when the summary asserts behavior) or the artifact's presence in the tree; cite `path[:line]` — bare path for whole-file claims, `path:line` for a specific behavior or symbol.
595
- - External claims (framework/library/version behavior): confirm against official docs for the installed version; cite the URL. Unverifiable → LOW plus the reason in one clause.
596
- - Confidence: HIGH = the diff/artifact confirms the summary as written; MEDIUM = the evidence is real but narrower than the summary; LOW = cannot be confirmed from available sources.
597
- 8. Self-check before emitting: every short hash in `<since>..<until>` appears exactly once, and every verified bullet carries exactly one `<!-- src: … -->` comment whose level is `HIGH`, `MEDIUM`, or `LOW` — no off-rubric levels, no unannotated claim bullets. Fix any miss, duplicate, or bad level; do not report a verdict.
598
- 9. Reply in at most three lines: the range, bullet counts per category plus verified-claim counts (`x HIGH / y MEDIUM / z LOW`), and the output target.
593
+ 7. **Verify claims before emitting — one required check on every claim bullet.** Classify first: an *API/library claim* is a bullet asserting what code, an API, a library, a dependency or a version does — skip merge/bookkeeping bullets that assert no such fact (a status move, a filing, a doc relocation). Then run the check and append one HTML comment line directly under the bullet carrying its anchor: `<!-- src: <citation> -->`. No confidence level is recorded (ADR-138): the anchor is the evidence.
594
+ - **Source citation — the anchor.** Internal claims (what a commit or the code does): confirm against the commit diff (`git show --stat <hash>`, reading hunks when the summary asserts behavior) or the artifact's presence in the tree; cite `path[:line]` — bare path for whole-file claims, `path:line` for a specific behavior or symbol. External claims (framework/library/version behavior): confirm against official docs for the installed version; cite the URL. An anchor you cannot produce fails the check — reword the bullet or drop the claim; a citation is not a citation until it names something a reader can open.
595
+ - **Defect precision decides what must be fixed.** The check is precise once a bullet is classified as a claim: an annotation missing its anchor is unambiguously wrong and blocks emitting. A summary broader than its evidence is reworded to what the anchor shows. Which bullets *are* claims is the heuristic half — resolve it by this step's rule, and for a genuinely borderline bullet say so in the bullet's body rather than annotating or skipping it silently.
596
+ 8. Self-check before emitting: every short hash in `<since>..<until>` appears exactly once, and every claim bullet carries exactly one `<!-- src: … -->` comment holding exactly one anchor — no unannotated claim bullets, no duplicate annotations. Fix any miss or duplicate; do not report a verdict.
597
+ 9. Reply in at most three lines: the range, bullet counts per category plus the verified-claim count, and the output target.
599
598
  - **Invariants:** Bullets are derived from `git log` only; the claim-verification pass (step 7) adds evidence from commit diffs, the working tree, and official docs. No quality gates — no `bun run gate`/lint/typecheck/test/`spur-check`/rule runs, and no edits beyond the one inserted section (its verification comments included). The file is left uncommitted.
600
599
 
601
600
  ### 9. gitmsg
@@ -85,14 +85,14 @@ batch can never destroy its own evidence. Reuse mode retains its operator-owned
85
85
  persists the Step 5 report under the invoking tree; the reused tree's `.spur/run/` remains the live
86
86
  copy while that tree lives on. The per-run provenance — the worktree DB's run/action rows and the
87
87
  `.spur/memory/runs/<runId>.md` + `.state.json` records — is persisted mechanically by WT-4a's
88
- `inline-run-setup.ts --persist-out --from <worktree> [--task-file <merged-task>]...` call,
88
+ `spur workflow inline persist-out --from <worktree> [--task-file <merged-task>]...` call,
89
89
  not by hand.
90
90
 
91
91
  **Stage records are worktree-local too (0948 R9, E7 Finding 5; persisted by 0975 R1).** Each task's
92
92
  own per-stage run record (`.spur/memory/runs/<runId>.md` + `.state.json`) and the worktree DB's run rows are
93
93
  written inside the worktree and **are removed with it** in create mode — the E7 batch lost exactly
94
94
  this evidence. Copying them out is no longer a manual audit-time duty: WT-4a (create-mode block
95
- below) runs `inline-run-setup.ts --persist-out --from "$WT_PATH"` **before** WT-4b holder cleanup,
95
+ below) runs `spur workflow inline persist-out --from "$WT_PATH"` **before** WT-4b holder cleanup,
96
96
  which copies the run/action/phase/transition/workflow-state rows and both record files into the
97
97
  invoking tree.
98
98
 
@@ -106,7 +106,7 @@ obligation; neither do root-qualified paths (`knowledge-kit/.spur/run/…`, `/ab
106
106
  which cite another project's evidence — cite foreign run artifacts that way, never bare. A citation missing in BOTH trees, a divergent cited file (never overwritten — reconcile
107
107
  by hand), an unreadable task file, or more than 64 distinct cited files fails the pass → WT-5.
108
108
 
109
- **Durable planes ride it too (E71).** Persist-out copies canonical task verdicts, feature run/latest receipts, nested run artifacts and owned sessions before teardown. Artifact and task-run-link rows are exported with run rows, and stored path references are redirected to the invoking tree. Conflicting or unreadable **owned** retained evidence refuses teardown. A divergent copy of evidence a forwarded task does **not** own (its WBS is not a forwarded task's and its receipt `runId` is not a worktree run row) is `foreign-divergent` (1139 R5): it is skipped, reported as `evidenceSkipped[{name, reason:'foreign-divergent', newer:'invoking'|'worktree'}]`, and the invoking-tree copy is never overwritten — another task's newer verdict can no longer block this batch's teardown. A divergent **owned** file still fails with `durable evidence conflicts`. `persist-out-check` accepts the same foreign-divergent set from the success JSON and does not recompute it.
109
+ **Durable planes ride it too (E71).** Persist-out copies canonical task verdicts, feature run/latest receipts, nested run artifacts and owned sessions before teardown. Artifact and task-run-link rows are exported with run rows, and stored path references are redirected to the invoking tree. Conflicting or unreadable **owned** retained evidence refuses teardown. A divergent copy of evidence a forwarded task does **not** own (its WBS is not a forwarded task's and its receipt `runId` is not a worktree run row) is `foreign-divergent` (1139 R5): it is skipped, reported as `evidenceSkipped[{name, reason:'foreign-divergent', newer:'invoking'|'worktree'}]`, and the invoking-tree copy is never overwritten — another task's newer verdict can no longer block this batch's teardown. A divergent **owned** file still fails with `durable evidence conflicts`. `spur workflow inline persist-check` accepts the same foreign-divergent set from the success JSON and does not recompute it.
110
110
 
111
111
  **Owned evidence rides it too (1012).** With at least one `--task-file`, persist-out also treats as
112
112
  copy obligations the worktree's `.spur/run/` direct children named `<wbs>-…` (the WBS is each
@@ -124,7 +124,7 @@ pass before the invoking tree is written → WT-5. Without `--task-file` nothing
124
124
  The shapes are pinned (task 0975 R1; `record-missing`, citation behavior per 0984; `evidenceSkipped` per 1139 R5): idempotent on re-persist;
125
125
  success exits 0 printing
126
126
  `{"ok":true,"persisted":<n>,"skipped":[{"id":<run-id>,"reason":"id-exists"|"external-key-conflict"|"record-conflict:<file>"|"record-missing:<file>"|"cited-directory:<name>"|"cited-symlink:<name>"|"cited-non-file:<name>"}],"evidenceSkipped":[{"name":<file>,"reason":"foreign-divergent","newer":"invoking"|"worktree"}]}`
127
- (`evidenceSkipped` is omitted when empty; the same object is written to `<invoking-tree>/.spur/run/persist-out.json` for `persist-out-check` to read)
127
+ (`evidenceSkipped` is omitted when empty; the same object is written to `<invoking-tree>/.spur/run/persist-out.json` for `spur workflow inline persist-check` to read)
128
128
  — an `external-key-conflict` skip leaves the target run unchanged **and fails the pass (1049)**: the delegate exits 1 printing `{"ok":false,"error":…}` naming the skipped source run ids, because that (workflow, external key) identity already belongs to a different receiving run — the batch was not persisted, so reconcile the source worktree by hand (it stays the provenance owner of record) before any teardown: auditable reconciliation names the original archived DB snapshot and the skipped source run identities, verifies the archive by file hash and by merged-commit ancestry of the source branch, and treats any residual deletion as explicit operator-authorized cleanup under the strict canonical evidence rules above. Task 1149 R1 grades a terminal duplicate lifecycle row (`task-lifecycle`/`feature-lifecycle`) as `external-key-conflict-bookkeeping` (non-fatal), so guarded transitions driven inside the worktree do not block teardown; the receiving lifecycle row is reconciled automatically during persist-out. An `id-exists` replay repairs missing owned artifacts and task links without duplicating them. A
129
129
  `record-conflict:<file>` never overwrites a divergent invoking-tree record and causes the delegate to exit 1, retaining the worktree. Before reconciling one by hand, check **what** the invoking record is: when the run closed `done` inside a linked worktree the owning tree holds that run's **WT-0 landing obligation** (`landing: required branch=… path=… base=…`, see [execution-worktree-landing.md § WT-0](execution-worktree-landing.md#wt-0--markerless-worktree-runs)) — a 3-line record that is *not* a stub of the worktree's stage narrative, so copying the worktree record over it destroys the very obligation a later merge must rewrite. The reconciliation is therefore: discharge the obligation in place (`landing: merged <sha>` or `landing: retained`), and preserve the worktree narrative beside it (e.g. `<runId>.worktree-provenance.md`) rather than in place of it. A
130
130
  `record-missing:<file>` skip is a known `task-lifecycle`/`feature-lifecycle` row with no record file
@@ -140,7 +140,7 @@ invoking tree shows the merged run `done` with its per-action rows.
140
140
  the batch roll-up built from the per-run files:
141
141
 
142
142
  ```bash
143
- node "$(superskill script path sp run-summary.mjs)" --rollup <runId>-summary.json --rollup <runId2>-summary.json
143
+ spur workflow summary --rollup <runId>-summary.json --rollup <runId2>-summary.json
144
144
  ```
145
145
 
146
146
  One row per run carrying that run's own Total, a bold total of the sums, and — when run windows overlap —
@@ -155,7 +155,7 @@ The wrap receives only what it would accept:
155
155
 
156
156
  1. `vars.tasks` = the JSON-encoded array of batch WBS whose terminal status is `done`. A task that
157
157
  is `failed`/`blocked`/`skipped`/`not-attempted`/`recheck`/`not-admitted` is **excluded** —
158
- `wrapup task-resolve` refuses non-done members (wrapup-steps.ts task-resolve), so the driver
158
+ `wrapup task-resolve` refuses non-done members (`spur task wrapup resolve`), so the driver
159
159
  simply stops handing the wrap tasks it would refuse.
160
160
  2. `vars.feature` = the batch feature **only when every task in the frozen batch is `done` or
161
161
  `cancelled`**. Otherwise omit it and print `feature lifecycle not advanced: <n> task(s)
@@ -173,7 +173,7 @@ an empty string disables the check while still recording PASS. A FAIL routes the
173
173
  with already-written learnings/docs preserved — fix the flagged working-diff violation and re-run
174
174
  the wrap.
175
175
 
176
- Filtering lives here, in the batch driver — no change to wrapup-pipeline.yaml or wrapup-steps.ts;
176
+ Filtering lives here, in the batch driver — no change to wrapup-pipeline.yaml or `spur task wrapup`;
177
177
  the wrap's refusal of non-done tasks remains the hard invariant.
178
178
 
179
179
  **Close-out commit (1129 R2/R5).** In sequential mode the wrap's writes (learnings, metrics,
@@ -185,12 +185,11 @@ batch tip — the step that makes the close-out the report's own contradiction).
185
185
  is never a point on the base ref.
186
186
  Stage them through the guard — never a free-form `git add` — so a concurrent writer's file cannot
187
187
  ride into the close-out commit (incident `36f274590`). `$RUN_ID` is the id Step 3 fixed before
188
- `commit-guard start` (execution-batch.md § Step 3); an unset id makes the guard exit 1 — fail closed:
188
+ `spur workflow commit-guard start` (execution-batch.md § Step 3); an unset id makes the guard exit 1 — fail closed:
189
189
 
190
190
  ```bash
191
- GUARD=plugins/sp/scripts/commit-guard.ts; [ -f config/plugin-scripts.json -a -f "$GUARD" ] || GUARD="$(superskill script path sp commit-guard.mjs 2>/dev/null)"
192
- bun "$GUARD" check --run "$RUN_ID" # 1129 R3: a non-empty foreign list goes in the batch report
193
- bun "$GUARD" stage --run "$RUN_ID" -- <files the wrap wrote> \
191
+ spur workflow commit-guard check --run "$RUN_ID" # 1129 R3: a non-empty foreign list goes in the batch report
192
+ spur workflow commit-guard stage --run "$RUN_ID" -- <files the wrap wrote> \
194
193
  || { echo "close-out halt: commit-guard refused a path (foreign, unmerged or conflict-marked); nothing committed" >&2; exit 1; }
195
194
  git commit -m "chore(wrap): <command> <selector> close-out writes"
196
195
  ```