@gobing-ai/spur 0.4.21 → 0.4.23

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 (85) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/pipeline-budgets.json +1 -1
  3. package/config/rules/boundary/config-loading-ownership.yaml +1 -1
  4. package/config/rules/strict/runtime-boundaries.yaml +3 -3
  5. package/config/rules/surface/check-cli-surface.yaml +1 -1
  6. package/config/workflow-candidates.json +1 -1
  7. package/config/workflows/history-anatomy.yaml +11 -11
  8. package/package.json +11 -11
  9. package/plugins/sp/commands/dev-runall.md +1 -1
  10. package/plugins/sp/plugin.json +1 -1
  11. package/plugins/sp/skills/conflict-finding/SKILL.md +2 -0
  12. package/plugins/sp/skills/dogfood-testing/SKILL.md +7 -7
  13. package/plugins/sp/skills/dogfood-testing/references/report-template.md +1 -1
  14. package/plugins/sp/skills/history-anatomy/references/modes.md +1 -1
  15. package/plugins/sp/skills/issue-finding/SKILL.md +2 -0
  16. package/plugins/sp/skills/reverse-engineering/SKILL.md +2 -0
  17. package/plugins/sp/skills/spur-cli/references/agent.md +6 -5
  18. package/plugins/sp/skills/spur-cli/references/builder.md +1 -8
  19. package/plugins/sp/skills/spur-cli/references/history.md +8 -1
  20. package/plugins/sp/skills/spur-cli/references/self.md +37 -2
  21. package/plugins/sp/skills/spur-cli/references/tasks.md +2 -1
  22. package/plugins/sp/skills/spur-cli/references/workflows.md +6 -2
  23. package/plugins/sp/skills/spur-dev/references/execution-batch-report.md +3 -3
  24. package/plugins/sp/skills/spur-dev/references/execution-batch.md +3 -3
  25. package/plugins/sp/skills/spur-dev/references/execution-worktree-landing.md +2 -2
  26. package/plugins/sp/skills/spur-dev/references/execution-worktree-setup.md +4 -4
  27. package/plugins/sp/skills/wayfinder/SKILL.md +2 -0
  28. package/spur.js +33626 -21793
  29. package/web/_astro/{BoardApp.DFBNysRC.js → BoardApp.CNBpKuB6.js} +167 -169
  30. package/web/_astro/{BoardApp.DspUVt5b.js → BoardApp.DVWLxHcV.js} +1 -1
  31. package/web/_astro/{TaskDetail.DEzLL6Fe.js → TaskDetail.BY6jO_3P.js} +1 -1
  32. package/web/_astro/arc.CLFbvaU4.js +1 -0
  33. package/web/_astro/{architectureDiagram-3BPJPVTR.D2Zyc6nm.js → architectureDiagram-3BPJPVTR.YYrMKtrm.js} +1 -1
  34. package/web/_astro/{blockDiagram-GPEHLZMM.BnA_rJl6.js → blockDiagram-GPEHLZMM.D-Xzu32A.js} +1 -1
  35. package/web/_astro/{c4Diagram-AAUBKEIU.DVUo9pxo.js → c4Diagram-AAUBKEIU.Cv7EV8QD.js} +1 -1
  36. package/web/_astro/channel.DzHZuqj0.js +1 -0
  37. package/web/_astro/{chunk-2J33WTMH.BJ-VkV91.js → chunk-2J33WTMH.CkAKN-fF.js} +1 -1
  38. package/web/_astro/{chunk-4BX2VUAB.xpN1rBQK.js → chunk-4BX2VUAB.D-xu2Tgi.js} +1 -1
  39. package/web/_astro/{chunk-55IACEB6.Dtu4VTmK.js → chunk-55IACEB6.yNQibVGY.js} +1 -1
  40. package/web/_astro/{chunk-727SXJPM.CjXhM1c1.js → chunk-727SXJPM.DlVIFHHZ.js} +4 -4
  41. package/web/_astro/{chunk-AQP2D5EJ.DSCad_Gd.js → chunk-AQP2D5EJ.C-LGFaeS.js} +1 -1
  42. package/web/_astro/{chunk-FMBD7UC4.DxwDIiuY.js → chunk-FMBD7UC4.Df2n26zT.js} +1 -1
  43. package/web/_astro/{chunk-ND2GUHAM.D5LgSWYE.js → chunk-ND2GUHAM.CV_k83Gj.js} +1 -1
  44. package/web/_astro/{chunk-QZHKN3VN.CwXZoKZI.js → chunk-QZHKN3VN.BQQDO3h3.js} +1 -1
  45. package/web/_astro/{classDiagram-4FO5ZUOK.DZ-I2QOo.js → classDiagram-4FO5ZUOK.DkSMdA84.js} +1 -1
  46. package/web/_astro/{classDiagram-v2-Q7XG4LA2.DZ-I2QOo.js → classDiagram-v2-Q7XG4LA2.DkSMdA84.js} +1 -1
  47. package/web/_astro/{cose-bilkent-S5V4N54A.DszE5dpz.js → cose-bilkent-S5V4N54A.CCN7GwAZ.js} +1 -1
  48. package/web/_astro/{cynefin-OW5HDTMX.c-ctyPLt.js → cynefin-OW5HDTMX.CqQCttkM.js} +1 -1
  49. package/web/_astro/{dagre-BM42HDAG.Boq07Shn.js → dagre-BM42HDAG.CCn6iftc.js} +2 -2
  50. package/web/_astro/diagram-2AECGRRQ.DImUVZK-.js +43 -0
  51. package/web/_astro/diagram-5GNKFQAL.BYNywZwV.js +10 -0
  52. package/web/_astro/{diagram-KO2AKTUF.BXEZQbTM.js → diagram-KO2AKTUF.LJZ9DjsJ.js} +3 -3
  53. package/web/_astro/{diagram-LMA3HP47.CFcDobF6.js → diagram-LMA3HP47.CJ3YpVED.js} +1 -1
  54. package/web/_astro/{diagram-OG6HWLK6.CJ8Q1cQd.js → diagram-OG6HWLK6.CnVtq5_j.js} +1 -1
  55. package/web/_astro/{erDiagram-TEJ5UH35.B409nFLg.js → erDiagram-TEJ5UH35.SdmuzZwT.js} +5 -5
  56. package/web/_astro/{flowDiagram-I6XJVG4X.BtF5dGDY.js → flowDiagram-I6XJVG4X.C9V-B-nO.js} +5 -5
  57. package/web/_astro/{ganttDiagram-6RSMTGT7.BbflTg4R.js → ganttDiagram-6RSMTGT7.DT5v7SL5.js} +1 -1
  58. package/web/_astro/{gitGraphDiagram-PVQCEYII.BLPcOhGS.js → gitGraphDiagram-PVQCEYII.B3qURYBL.js} +1 -1
  59. package/web/_astro/index.C8LjH5ri.css +1 -0
  60. package/web/_astro/{infoDiagram-5YYISTIA.DsaY8QU3.js → infoDiagram-5YYISTIA.CHO0xT8l.js} +1 -1
  61. package/web/_astro/{ishikawaDiagram-YF4QCWOH.D9PaTLtO.js → ishikawaDiagram-YF4QCWOH.buALAOGh.js} +5 -5
  62. package/web/_astro/{journeyDiagram-JHISSGLW.4_zPJ9m2.js → journeyDiagram-JHISSGLW.DvKuIdbX.js} +1 -1
  63. package/web/_astro/{kanban-definition-UN3LZRKU.IqD1vq7W.js → kanban-definition-UN3LZRKU.Dvoi9jdN.js} +7 -7
  64. package/web/_astro/{linear.JJiEkviR.js → linear.EsEfz8Ex.js} +1 -1
  65. package/web/_astro/mermaid.core.Vk3ryVC7.js +303 -0
  66. package/web/_astro/{mindmap-definition-RKZ34NQL.B6pZnBGO.js → mindmap-definition-RKZ34NQL.DG1pkymq.js} +2 -2
  67. package/web/_astro/{pieDiagram-4H26LBE5.MM6Of7YP.js → pieDiagram-4H26LBE5.DAUmIdd6.js} +3 -3
  68. package/web/_astro/{quadrantDiagram-W4KKPZXB.7eWQnH9R.js → quadrantDiagram-W4KKPZXB.Du3QUozl.js} +1 -1
  69. package/web/_astro/{requirementDiagram-4Y6WPE33.C3T9mbHc.js → requirementDiagram-4Y6WPE33.neRi5GrQ.js} +3 -3
  70. package/web/_astro/{sankeyDiagram-5OEKKPKP.CqlwDe_m.js → sankeyDiagram-5OEKKPKP.CMUtxA70.js} +4 -4
  71. package/web/_astro/{sequenceDiagram-3UESZ5HK.BNVlPChR.js → sequenceDiagram-3UESZ5HK.CfYFLmYH.js} +1 -1
  72. package/web/_astro/{stateDiagram-AJRCARHV.DSExW-ER.js → stateDiagram-AJRCARHV.Bn4dmAad.js} +1 -1
  73. package/web/_astro/{stateDiagram-v2-BHNVJYJU.CxE4k_fB.js → stateDiagram-v2-BHNVJYJU.BMNezvp-.js} +1 -1
  74. package/web/_astro/{timeline-definition-PNZ67QCA.uFqjG7Z5.js → timeline-definition-PNZ67QCA.ByaDwsBX.js} +3 -3
  75. package/web/_astro/{vennDiagram-CIIHVFJN.DpTrAXYs.js → vennDiagram-CIIHVFJN.CUYU1Mc9.js} +5 -5
  76. package/web/_astro/{wardleyDiagram-YWT4CUSO.Dl0KBFZe.js → wardleyDiagram-YWT4CUSO.DpZZeJr2.js} +3 -3
  77. package/web/_astro/{xychartDiagram-2RQKCTM6.CE0syl0o.js → xychartDiagram-2RQKCTM6.CWwI33U0.js} +1 -1
  78. package/web/board-runtime.json +4 -0
  79. package/web/index.html +2 -2
  80. package/web/_astro/arc.TAQDSOGC.js +0 -1
  81. package/web/_astro/channel.DpBpvy1k.js +0 -1
  82. package/web/_astro/diagram-2AECGRRQ.Csap4wVu.js +0 -43
  83. package/web/_astro/diagram-5GNKFQAL.Cy4jXe_F.js +0 -10
  84. package/web/_astro/index.DVDW9-eD.css +0 -1
  85. package/web/_astro/mermaid.core.Brxzivhz.js +0 -301
@@ -7,7 +7,7 @@
7
7
  "plugins": [
8
8
  {
9
9
  "name": "sp",
10
- "version": "0.4.21",
10
+ "version": "0.4.23",
11
11
  "source": "./plugins/sp"
12
12
  }
13
13
  ]
@@ -32,7 +32,7 @@
32
32
  "modelQueries": 3,
33
33
  "wallClockMs": null,
34
34
  "tokenCostUsd": null,
35
- "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).",
35
+ "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).",
36
36
  "decision": null
37
37
  }
38
38
  }
@@ -67,7 +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 commit-guard|persist-*` (PR-4)
70
+ - "apps/cli/src/workflow-transport.ts" # boot-free composition root of `spur workflow commit-guard-*|persist-*` (PR-4)
71
71
  - "apps/server/src/serve.ts"
72
72
  - "apps/server/src/context.ts"
73
73
  - "**/tests/**"
@@ -37,7 +37,7 @@ 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):
40
+ # `spur builder pr-*` spine (script-absorption PR-7, moved from plugins/sp/scripts/pr-reviewing.ts):
41
41
  # every git/gh call goes through ONE synchronous, test-injectable CommandRunner seam
42
42
  # (`setCommandRunner`); the spine is synchronous end to end (wait polls with a sync sleep).
43
43
  # The ts-runtime sync executors cannot stand in: NodeSyncProcessExecutor maps a spawn
@@ -101,7 +101,7 @@ rules:
101
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)
102
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
103
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
- # Workflow transports (script-absorption PR-4, `spur workflow commit-guard`): moved
104
+ # Workflow transports (script-absorption PR-4, `spur workflow commit-guard-*`): moved
105
105
  # verbatim from the plugin scripts; synchronous probes and
106
106
  # atomic tmp+rename snapshot writes inside one short-lived CLI process.
107
107
  - "packages/app/src/workflow/commit-guard.ts" # .spur/run/<run>-tree-start.json atomic snapshot + target conflict-marker reads
@@ -121,7 +121,7 @@ rules:
121
121
  - "packages/app/src/services/residual-scan-run.ts"
122
122
  - "packages/app/src/workflow/task-diffstat.ts"
123
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)
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)
125
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)
126
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)
127
127
 
@@ -62,7 +62,7 @@ rules:
62
62
  - "apps/cli/src/commands/task/wrapup.ts"
63
63
  - "apps/cli/src/commands/feature/handoff.ts"
64
64
  - "apps/cli/src/commands/feature/verify.ts"
65
- # commit-guard declares no --json: its {staged, foreign} / {foreign} lines are rendered by
65
+ # commit-guard-* declare no --json: its {staged, foreign} / {foreign} lines are rendered by
66
66
  # @gobing-ai/spur-app/commit-guard (byte-identical to the retired script, PR-4 golden).
67
67
  - "apps/cli/src/commands/workflow/commit-guard.ts"
68
68
  # WT-4 worktree-landing transports (D65 1242, flat since the inline group was deleted): they
@@ -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 (`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).",
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
  },
@@ -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 `spur history anatomy <op>` (0659's helper, absorbed by script-absorption PR-6); 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
@@ -108,11 +108,11 @@ states:
108
108
  onEnter:
109
109
  - kind: shell
110
110
  options:
111
- # Path arithmetic lives in `spur history anatomy paths` (ADR-069 R1; script-absorption
111
+ # Path arithmetic lives in `spur history anatomy-paths` (ADR-069 R1; script-absorption
112
112
  # PR-6 — HA_HELPER is the running spur, HA_SKILL the resolved skill dir). Avoid
113
113
  # `${...}` here — that syntax collides with the engine's own template interpolation.
114
114
  command: >-
115
- $spurBin history anatomy paths --report-dir "$reportDir" --date "$date"
115
+ $spurBin history anatomy-paths --report-dir "$reportDir" --date "$date"
116
116
  --output "$output" --mode "$mode" --since "$since" --until "$until"
117
117
  --focus "$focus" --recompute "$recompute" --run-id "$__runId"
118
118
  --out .spur/run/$__runId-paths.txt
@@ -146,7 +146,7 @@ states:
146
146
  options:
147
147
  command: >-
148
148
  . .spur/run/$__runId-paths.txt;
149
- $spurBin history anatomy probe --artifact .spur/run/$__runId-history-anatomy-current.json
149
+ $spurBin history anatomy-probe --artifact .spur/run/$__runId-history-anatomy-current.json
150
150
  --baseline .spur/run/$__runId-history-anatomy-baseline.json --target "$HA_TARGET"
151
151
  --mode "$mode" --date "$HA_DATE" --recompute "$recompute" --executor "$agent"
152
152
  --skill-dir "$HA_SKILL" --contract "$HA_SKILL/references/report-contract.md"
@@ -187,7 +187,7 @@ states:
187
187
  - kind: shell
188
188
  options:
189
189
  command: >-
190
- $spurBin history anatomy 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
191
191
 
192
192
  - id: structure-gate
193
193
  description: >
@@ -198,7 +198,7 @@ states:
198
198
  - kind: shell
199
199
  options:
200
200
  command: >-
201
- $spurBin history anatomy check \
201
+ $spurBin history anatomy-check \
202
202
  .spur/run/$__runId-candidate.md > .spur/run/$__runId-structure-gate.txt 2>&1 || true
203
203
 
204
204
  - id: validate
@@ -264,7 +264,7 @@ states:
264
264
  - kind: shell
265
265
  options:
266
266
  command: >-
267
- $spurBin history anatomy 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
268
268
 
269
269
  - id: correct
270
270
  description: >
@@ -301,7 +301,7 @@ states:
301
301
  - kind: shell
302
302
  options:
303
303
  command: >-
304
- $spurBin history anatomy 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
305
305
 
306
306
  - id: refresh-provenance
307
307
  description: >
@@ -314,7 +314,7 @@ states:
314
314
  options:
315
315
  command: >-
316
316
  . .spur/run/$__runId-paths.txt;
317
- $spurBin history anatomy refresh --report "$HA_TARGET"
317
+ $spurBin history anatomy-refresh --report "$HA_TARGET"
318
318
  --out .spur/run/$__runId-publishable.md --disposition hit
319
319
 
320
320
  - id: stamp
@@ -328,7 +328,7 @@ states:
328
328
  options:
329
329
  command: >-
330
330
  . .spur/run/$__runId-paths.txt;
331
- $spurBin history anatomy stamp --candidate .spur/run/$__runId-candidate.md
331
+ $spurBin history anatomy-stamp --candidate .spur/run/$__runId-candidate.md
332
332
  --provenance .spur/run/$__runId-provenance.json
333
333
  --out .spur/run/$__runId-publishable.md
334
334
 
@@ -343,7 +343,7 @@ states:
343
343
  command: >-
344
344
  . .spur/run/$__runId-paths.txt;
345
345
  mkdir -p "$(dirname "$HA_TARGET")";
346
- $spurBin history anatomy publish .spur/run/$__runId-publishable.md "$HA_TARGET"
346
+ $spurBin history anatomy-publish .spur/run/$__runId-publishable.md "$HA_TARGET"
347
347
 
348
348
  - id: published
349
349
  description: Terminal — report published atomically after a passing validation.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobing-ai/spur",
3
- "version": "0.4.21",
3
+ "version": "0.4.23",
4
4
  "description": "Spur CLI — local-first harness for mainstream coding agents: constraint checking, workflow orchestration, agent health, and history analytics. Bun-native; exposes the `spur` command.",
5
5
  "keywords": [
6
6
  "spur",
@@ -57,19 +57,19 @@
57
57
  "prepublishOnly": "cd ../.. && bun run apps/cli/src/index.ts builder bump-ver --check spur --no-logo"
58
58
  },
59
59
  "devDependencies": {
60
- "@commander-js/extra-typings": "^14.0.0",
61
- "@gobing-ai/ts-db": "^0.7.1",
62
- "@gobing-ai/ts-ai-runner": "^0.7.1",
63
- "@gobing-ai/ts-dual-workflow-engine": "^0.7.1",
64
- "@gobing-ai/ts-infra": "^0.7.1",
65
- "@gobing-ai/ts-llm-jsonl-importer": "^0.7.1",
66
- "@gobing-ai/ts-rule-engine": "^0.7.1",
67
- "@gobing-ai/ts-runtime": "^0.7.1",
68
- "@gobing-ai/ts-utils": "^0.7.1",
60
+ "@commander-js/extra-typings": "14.0.0",
61
+ "@gobing-ai/ts-db": "0.7.1",
62
+ "@gobing-ai/ts-ai-runner": "0.7.1",
63
+ "@gobing-ai/ts-dual-workflow-engine": "0.7.1",
64
+ "@gobing-ai/ts-infra": "0.7.1",
65
+ "@gobing-ai/ts-llm-jsonl-importer": "0.7.1",
66
+ "@gobing-ai/ts-rule-engine": "0.7.1",
67
+ "@gobing-ai/ts-runtime": "0.7.1",
68
+ "@gobing-ai/ts-utils": "0.7.1",
69
69
  "@types/bun": "1.4.3",
70
70
  "@types/figlet": "^1.7.0",
71
71
  "@types/node-notifier": "8.0.5",
72
- "commander": "^14.0.3",
72
+ "commander": "14.0.3",
73
73
  "figlet": "^1.11.0",
74
74
  "zod": "4.4.3"
75
75
  },
@@ -102,7 +102,7 @@ full distinction.
102
102
  - **Bootstrap reads (1128):** before the first dispatch, read [SKILL.md § Bootstrap reads](../skills/spur-dev/SKILL.md#bootstrap-reads) and load only that mode's files — the section whose trigger has not fired is on demand.
103
103
  - **Publish the visible batch plan first (1105):** publish `A Prepare batch` (A1–A4) and `Z Batch
104
104
  report` before the first task, then one letter per task from `spur task batch-plan waves` after
105
- freeze/order and digit children from `spur task batch-plan task-children` at task start —
105
+ freeze/order and digit children from `spur task batch-plan-children` at task start —
106
106
  [execution-batch.md](../skills/spur-dev/references/execution-batch.md#27-visible-batch-plan-1105-r3)
107
107
  § 2.7 Visible batch plan.
108
108
  - Apply the [inline-default execution-surface contract](../skills/spur-dev/references/cross-cutting.md#inline-default-execution-surface). Interactive sequential omit/`inline` keeps the orchestrator in the host session through the engine loop (`spur workflow run --vars '{"executor":"host"}'` → work item → `spur workflow continue`); the resolved selector applies uniformly — eligible `agent.run` stages dispatch once to a native subagent with host fallback (0508). `--agent auto`, a name, or parallel mode retains the isolated per-task workflow boundary.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "sp",
3
- "version": "0.4.21",
3
+ "version": "0.4.23",
4
4
  "description": "Spur — a local-first harness engineering toolkit that wraps mainstream coding agents with constraint checking, workflow orchestration, and history analytics."
5
5
  }
@@ -234,6 +234,8 @@ findings, unresolved, coverage, cost, remediation, errors`.
234
234
  | `Bash` | `git`, `rg`, `spur task/feature ... --json`, `spur ... check`, `sp:doc-evolve` audit |
235
235
  | `Write` | Only for temp files / owner-routed repair payloads after confirmation (with `--resolve`) |
236
236
 
237
+ **Search routing** (hybrid search, ADR-147): concept, cross-file, or "how does X work" questions → semantic first — the zg MCP tool `zvec_grep_search` when the host exposes it, else `spur self search "<query>" --mode fuzzy --json`. Literal, symbol, regex, or exhaustive occurrence lists → `rg`. If zg is absent or the search response carries a `skipped` reason → fall back to `rg`.
238
+
237
239
  ## Platform Notes
238
240
 
239
241
  ### Claude Code
@@ -82,11 +82,11 @@ The command forwards these via `$ARGUMENTS`:
82
82
  > <!-- pipeline-tokens:end -->
83
83
  > matched as a **distinct hyphen-word**
84
84
  > (machine-checked by
85
- > `detectPipelineDriving` (`spur agent dogfood gate`);
85
+ > `detectPipelineDriving` (`spur agent dogfood-gate`);
86
86
  > see [§Pipeline-driving word-boundary contract](#pipeline-driving-word-boundary-contract))
87
87
  > → `⚠ pipeline-driving testee detected; pass --max-retry 0 (observe-only) or --max-retry N (fix mode, tree mutation acknowledged)`.
88
88
  > - **Mutating `--fix` modes** — `--fix all` / `--fix blockers-first`, boundary-guarded via
89
- > `hasMutatingFixMode` (`spur agent dogfood gate`) (never matches
89
+ > `hasMutatingFixMode` (`spur agent dogfood-gate`) (never matches
90
90
  > `--fix none` / `--focus all` / `--prefix all`). No pipeline token required: a verify/review leg
91
91
  > with `--fix all` mutates the tree on its own (0280 dogfood P2, task 0293). Honesty note:
92
92
  > `--max-retry 0` here bounds **the driver only** — the testee still mutates the tree — so the
@@ -100,7 +100,7 @@ The command forwards these via `$ARGUMENTS`:
100
100
  in-agent):
101
101
 
102
102
  ```bash
103
- spur agent dogfood gate \
103
+ spur agent dogfood-gate \
104
104
  --testee "<raw testee string>" \
105
105
  [--max-retry-present]
106
106
  ```
@@ -121,7 +121,7 @@ The command forwards these via `$ARGUMENTS`:
121
121
  re-run the gate with the derived step labels:
122
122
 
123
123
  ```bash
124
- spur agent dogfood gate \
124
+ spur agent dogfood-gate \
125
125
  --testee "<raw testee string>" \
126
126
  --max-retry-present \
127
127
  --steps "step1 label||step2 label||..."
@@ -232,7 +232,7 @@ contract violation**.
232
232
  **before** claiming `status: complete`:
233
233
 
234
234
  ```bash
235
- spur agent dogfood validate-report --file <report-path>
235
+ spur agent dogfood-validate-report --file <report-path>
236
236
  ```
237
237
 
238
238
  Exit **0** → proceed. Exit **2** → set `status: aborted`, list every error code under §5
@@ -338,7 +338,7 @@ Do **not** use this skill for:
338
338
  Pipeline-driving detection is **word-boundary**, not leading-space substring. The live gate is:
339
339
 
340
340
  ```bash
341
- spur agent dogfood gate --testee "<testee>" [--max-retry-present] [--steps "…"] [--json]
341
+ spur agent dogfood-gate --testee "<testee>" [--max-retry-present] [--steps "…"] [--json]
342
342
  ```
343
343
 
344
344
  | Token shape | Examples | Matches | Rejects |
@@ -349,7 +349,7 @@ spur agent dogfood gate --testee "<testee>" [--max-retry-present] [--steps "…"
349
349
  `-` is a **word character** for boundaries: a token must be a distinct hyphen-word. Contract tests:
350
350
  `packages/app/tests/services/dogfood/pipeline-detect.test.ts`. Helpers:
351
351
  `detectPipelineDriving`, `isImplementHeavyStep`, `detectImplementHeavy`, `evaluateDogfoodGate` in
352
- `spur agent dogfood gate` (absorbed into the CLI; was `plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts`).
352
+ `spur agent dogfood-gate` (absorbed into the CLI; was `plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts`).
353
353
 
354
354
  ## Mutating `--fix` mode contract
355
355
 
@@ -336,7 +336,7 @@ Before the skill may stop (success, partial, fail, observe-only end, or abort),
336
336
  and mirror the footer block at the **end of the report file**. A report whose body lacks the
337
337
  footer cannot set `status: complete`.
338
338
  8. **Self-validate (task 0278 R6):** run
339
- `spur agent dogfood validate-report --file <report-path>` before
339
+ `spur agent dogfood-validate-report --file <report-path>` before
340
340
  claiming `status: complete`. Exit 2 → `status: aborted` + list error codes under
341
341
  `#### Unresolved` (never force complete on a non-@1.2 shape).
342
342
  9. **Refusal rule (@1.2):** when any check above fails, set `status: aborted` and list every
@@ -2,7 +2,7 @@
2
2
 
3
3
  The skill resolves exactly two modes. Everything else fails loud. This matrix is the enforcement
4
4
  surface the workflow (0660) and the skill share; keep the vocabulary frozen. Execution note
5
- (0920): argument validation runs deterministically in `spur history anatomy paths`
5
+ (0920): argument validation runs deterministically in `spur history anatomy-paths`
6
6
  (formerly the `history-anatomy-cache` helper) (logic core: `packages/app/src/services/history-anatomy.ts`, task 1005) before the
7
7
  workflow starts; the model hop no longer performs it.
8
8
 
@@ -367,6 +367,8 @@ With `--create-task`, include `"task": { "wbs": "…", "file": "…", "status":
367
367
  | `Bash` | `spur history` + `spur task` CLI |
368
368
  | `Write` | Temp files for section bodies |
369
369
 
370
+ **Search routing** (hybrid search, ADR-147): concept, cross-file, or "how does X work" questions → semantic first — the zg MCP tool `zvec_grep_search` when the host exposes it, else `spur self search "<query>" --mode fuzzy --json`. Literal, symbol, regex, or exhaustive occurrence lists → `rg`. If zg is absent or the search response carries a `skipped` reason → fall back to `rg`.
371
+
370
372
  ## Platform Notes
371
373
 
372
374
  - **Claude Code** — invoke via `/sp:dev-find-issue …` or `Skill(skill="sp:issue-finding",
@@ -141,6 +141,8 @@ Execute phases in order. Stop at the phase boundary required by the selected mod
141
141
  3. Exclude or de-prioritize generated, vendored, build output, dependency cache, lockfile-only, binary-heavy, and snapshot-heavy paths unless they are directly relevant.
142
142
  4. For monorepos, identify packages/apps and either ask for scope or analyze each package at the requested depth if feasible.
143
143
 
144
+ **Search routing** (hybrid search, ADR-147): concept, cross-file, or "how does X work" questions → semantic first — the zg MCP tool `zvec_grep_search` when the host exposes it, else `spur self search "<query>" --mode fuzzy --json`. Literal, symbol, regex, or exhaustive occurrence lists → `rg`. If zg is absent or the search response carries a `skipped` reason → fall back to `rg`.
145
+
144
146
  ### Phase 3: Classify
145
147
 
146
148
  Classify the codebase as one or more archetypes:
@@ -30,7 +30,8 @@ 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
+ | `dogfood-gate` | `sp:dogfood-testing` gate: pipeline-driving refusal (exit 2) | `--testee` `--max-retry-present` `--steps` `--json` |
34
+ | `dogfood-validate-report` | `sp:dogfood-testing` report-contract validation (exit 2) | `--file` `--json` |
34
35
  | `usage` | Run-once provider usage capture (codexbar) → quota-owned availability refresh; scheduled externally | `--dry-run` `--source <name>` `--json` |
35
36
  | `start <spec-id>` | Start a supervised agent process (requires `spur self serve`) | `--server <url>` `--json` |
36
37
  | `stop <spec-id>` | Stop a supervised agent process (requires `spur self serve`) | `--server <url>` `--json` |
@@ -332,12 +333,12 @@ Posts to the supervisor API
332
333
  (`POST /api/agents/:id/stop`) and prints `stopped <id>`. Same server requirement and flags as
333
334
  `start`.
334
335
 
335
- ## `dogfood` - dogfood-testing gates
336
+ ## `dogfood-gate` / `dogfood-validate-report` - dogfood-testing gates
336
337
 
337
338
  ```bash
338
- spur agent dogfood gate --testee "/sp:dev-run 0123" --json # exit 2 = refuse (pipeline-driving, no --max-retry)
339
- spur agent dogfood gate --testee "…" --steps "plan||implement" # Phase 1 W8 re-check
340
- spur agent dogfood validate-report --file report.md --json # exit 2 = contract errors
339
+ spur agent dogfood-gate --testee "/sp:dev-run 0123" --json # exit 2 = refuse (pipeline-driving, no --max-retry)
340
+ spur agent dogfood-gate --testee "…" --steps "plan||implement" # Phase 1 W8 re-check
341
+ spur agent dogfood-validate-report --file report.md --json # exit 2 = contract errors
341
342
  ```
342
343
 
343
344
  Absorbed from `plugins/sp/scripts/dogfood-testing/` (script-absorption PR-7). `--json` here prints
@@ -20,8 +20,7 @@ This noun is **frozen at exactly eight verbs** (`bump-ver`, `drop-tags`, `publis
20
20
  script-absorption entries; `show-branches` and the four flat PR verbs `pr-status`, `pr-check`,
21
21
  `pr-open`, `pr-review` from the 2026-10-16 feature-L1 entries) by operator consent
22
22
  (`docs/design/harness-surface-governance.md` §3) — do not invent additional `builder` subcommands.
23
- The former `pr <op>` pass-through stays registered as a **hidden, deprecated alias** for one release
24
- (it prints one stderr deprecation line naming the replacement verb), so it is not listed here.
23
+ The former `pr <op>` pass-through was removed by task 1290 (two-level `spur <noun> <verb>` rule).
25
24
 
26
25
  ## Verb map
27
26
 
@@ -96,12 +95,6 @@ PR); `pr-check` → `{ ok, verdict, preflight, hygiene }`; `pr-open` → `{ ok,
96
95
  and returns `PENDING` when a marked request is still in flight; `--force` requests a fresh review
97
96
  of the current HEAD regardless. Never force-pushes.
98
97
 
99
- ```bash
100
- # deprecated alias, one release: maps the old op names to the verbs above
101
- spur builder pr preflight --json # -> spur builder pr-check
102
- spur builder pr status --json # -> spur builder pr-status
103
- ```
104
-
105
98
  ## `show-branches` - read-only branch topology report
106
99
 
107
100
  ```bash
@@ -23,7 +23,14 @@ 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`) |
26
+ | `anatomy-digest` | history-anatomy cache op `digest` behind the `history-anatomy` workflow | op argv (see `spur history anatomy-digest --help`) |
27
+ | `anatomy-check` | history-anatomy cache op `check` behind the `history-anatomy` workflow | op argv (see `spur history anatomy-check --help`) |
28
+ | `anatomy-paths` | history-anatomy cache op `paths` behind the `history-anatomy` workflow | op argv (see `spur history anatomy-paths --help`) |
29
+ | `anatomy-assert-clean` | history-anatomy cache op `assert-clean` behind the `history-anatomy` workflow | op argv (see `spur history anatomy-assert-clean --help`) |
30
+ | `anatomy-probe` | history-anatomy cache op `probe` behind the `history-anatomy` workflow | op argv (see `spur history anatomy-probe --help`) |
31
+ | `anatomy-stamp` | history-anatomy cache op `stamp` behind the `history-anatomy` workflow | op argv (see `spur history anatomy-stamp --help`) |
32
+ | `anatomy-refresh` | history-anatomy cache op `refresh` behind the `history-anatomy` workflow | op argv (see `spur history anatomy-refresh --help`) |
33
+ | `anatomy-publish` | history-anatomy cache op `publish` behind the `history-anatomy` workflow | op argv (see `spur history anatomy-publish --help`) |
27
34
  | `timeline` | Per-prompt work/wait time and tokens from the host transcript (JSON), for `sp:session-review` | `--transcript <path>` `--group <spec>` |
28
35
  | `summary` | Daily summary report for `sp:daily-summary` (tokens, git, history health, annotations) | `--date <d>` `--dry-run` `--output <path>` `--no-git` `--no-ccusage` |
29
36
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: spur-cli-self
3
- description: "spur-cli noun reference for `spur self`: self-management verbs — SDLC action runner (`exec`), scaffold (`init`), database maintenance (`maintain`), schema migrations (`migrate`), local web server (`serve`), and status overview (`status`). The five legacy verbs (`init`, `maintain`, `migrate`, `serve`, `status`) each mount the same command builder as their legacy top-level noun, which remains a hidden alias; `exec` has no top-level alias."
3
+ description: "spur-cli noun reference for `spur self`: self-management verbs — SDLC action runner (`exec`), scaffold (`init`), database maintenance (`maintain`), schema migrations (`migrate`), hybrid rg/zg search (`search`), local web server (`serve`), and status overview (`status`). The five legacy verbs (`init`, `maintain`, `migrate`, `serve`, `status`) each mount the same command builder as their legacy top-level noun, which remains a hidden alias; `exec` and `search` have no top-level alias."
4
4
  see_also:
5
5
  - spur-cli
6
6
  ---
@@ -14,7 +14,8 @@ Both paths share the same command builder: identical flags, output, and exit cod
14
14
  top-level forms are omitted from `spur --help`, leaving `self` as the visible surface.
15
15
 
16
16
  `exec` is the exception: it exists only as `spur self exec` — there is no `spur exec` top-level
17
- alias (`spur exec <action>` is an unknown command), so nothing depends on a legacy path.
17
+ alias (`spur exec <action>` is an unknown command), so nothing depends on a legacy path. `search`
18
+ is the second such verb: `spur self search` only.
18
19
 
19
20
  ## Verb map
20
21
 
@@ -24,6 +25,7 @@ alias (`spur exec <action>` is an unknown command), so nothing depends on a lega
24
25
  | `init` | Scaffold a new Spur project in the current directory | `--name <name>` `--force` `--minimal` `--adopt-global-config` `--json` |
25
26
  | `maintain` | Run database maintenance: PRAGMA optimize, WAL truncation, optional VACUUM | `--vacuum` `--json` |
26
27
  | `migrate` | Apply CLI-owned schema migrations (or `--check` the importer schema) | `--check` `--json` |
28
+ | `search` | Hybrid exact (`rg`) and semantic (`zg`) search over project docs and code | `--mode` `--scope` `--glob` `--limit` `--regex` `--status` `--json` |
27
29
  | `serve` | Start the Spur web server (local fallback) | `--port <n>` `--host <addr>` `--no-open` `--cwd <path>` `--json` |
28
30
  | `status [path]` | Show project and git status for a Spur project | `--json` |
29
31
 
@@ -63,6 +65,39 @@ first non-zero exit.
63
65
  `--json` without `--list` or `--dry-run` prints a final `{ action, steps: [{ name, exitCode, durationMs }], exitCode }`
64
66
  after the streaming output. Full surface: `docs/design/sdlc-actions.md` §3.3.
65
67
 
68
+ ## `self search` - hybrid exact and semantic search
69
+
70
+ ```bash
71
+ spur self search "how is a paused workflow resumed" # auto: exact + fuzzy where available
72
+ spur self search Bun.which --mode exact # ripgrep only
73
+ spur self search 'runCost' --mode fuzzy --limit 5 # zg semantic only
74
+ spur self search resum --mode exact --scope docs --glob '*.md'
75
+ spur self search --status # backend readiness, no query
76
+ spur self search Bun.which --mode exact --json # raw SearchResponse payload
77
+ ```
78
+
79
+ One verb over the hybrid search service (`docs/design/hybrid-search.md` §4, ADR-147). `--mode` is
80
+ `exact` | `fuzzy` | `auto` (default `auto`), `--scope` is `docs` | `code` | `all` (default `all`),
81
+ `--limit` is 1–100 (default 20), `--glob` adds a backend glob (repeatable; prefix `!` to negate),
82
+ and `--regex` switches the exact route from fixed string to pattern. `--status` prints the `rg`/`zg`
83
+ readiness payload and takes no query.
84
+
85
+ The groups are `exact` (ripgrep `--json` events) and `fuzzy` (zg `--hybrid`); a group is `null` when
86
+ that route did not run, and `skipped[]` names the degraded route with its reason
87
+ (`zg-not-installed`, `zg-index-missing`, `zg-timeout`, `zg-failed`, `zg-output-error`) plus an exact
88
+ hint string. Hints are printed, never executed — Spur installs and indexes nothing. Human output
89
+ prints `exact (n)` / `fuzzy (n)` headers with `path:start[-end] [matchedBy]` rows, the first three
90
+ snippet lines indented, then the skip lines; zero hits print `no matches`. `--json` emits the
91
+ `SearchResponse` verbatim (`--json-envelope` for the ADR-091 envelope).
92
+
93
+ | Exit | When |
94
+ | ---- | ---- |
95
+ | `0` | results, empty results, or a degraded fuzzy route |
96
+ | `1` | invalid request (empty query, bad mode/scope/limit), rg missing or rg failed |
97
+ | `2` | no query and no `--status` (usage) |
98
+
99
+ Raw zg/rg passthrough flags are deliberately absent: they would leak the adapter.
100
+
66
101
  ## `self init` - scaffold a Spur project
67
102
 
68
103
  ```bash
@@ -49,7 +49,8 @@ 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>` |
52
+ | `batch-plan <mode>` | Batch plan projection: `waves` / `order` (JSON on stdout; the batch driver's visible plan) | `--tasks <file>` `--concurrency <n>` |
53
+ | `batch-plan-children` | One task row's phase digits from the visible plan (JSON on stdout) | `--letter <A-Z>` `--plan <file>` |
53
54
  | `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
55
  | `wrapup <op>` | One deterministic `wrapup-pipeline` step (`resolve`, `route-reason`, `metrics`, `doc-sync-snapshot`, `doc-sync-scope`, `doc-supersession`, `drift-probe`) — workflow-internal | `--run-id <id>` `--tasks <json>` `--mode <m>` `--spur-bin <cmd>` |
55
56
  | `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` |
@@ -121,7 +121,9 @@ The skill's logic divides by **whether the LLM adds value**:
121
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
122
  | `persist-out` | `spur workflow persist-out` (CLI) | `--from <worktree> [--task-file <path>]…` | WT-4 landing: copy a worktree's run rows, two-file records and cited/owned evidence into the invoking tree before teardown; exit 1 fail closed (retain the worktree) |
123
123
  | `persist-check` | `spur workflow persist-check` (CLI) | `--from <worktree> [--task-file <path>]… [--run-id <id>]… [--root <tree>] [--success-json <path>]` | WT-4 pre-removal assertion that the worktree owns no unpersisted durable evidence; exit 0 ok / 1 blocked or divergent / 2 usage |
124
- | `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 |
124
+ | `commit-guard-start` | `spur workflow commit-guard-start` (CLI) | `--run <id>` | Fingerprint HEAD and the dirty working files into `.spur/run/<run>-tree-start.json` |
125
+ | `commit-guard-stage` | `spur workflow commit-guard-stage` (CLI) | `--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 |
126
+ | `commit-guard-check` | `spur workflow commit-guard-check` (CLI) | `--run <id> [--base <sha>]` | Report working-tree changes this run did not write; stage nothing. The nested `commit-guard <op>` spelling was removed (task 1290) |
125
127
  | `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) |
126
128
  | `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) |
127
129
 
@@ -277,7 +279,9 @@ spur workflow profile <workflow> [--last <n>] [--window <sec>] [--spur-bin <cmd
277
279
  spur workflow cost [--workflow <name>]... [--by-state] [--include-bookkeeping] [--since <YYYY-MM-DD>] [--budget <file>] [--measured-file <json>] [--json]
278
280
  spur workflow persist-out --from <worktree> [--task-file <path>]...
279
281
  spur workflow persist-check --from <worktree> [--task-file <path>]... [--run-id <id>]... [--root <tree>]
280
- spur workflow commit-guard <op> [options]
282
+ spur workflow commit-guard-start --run <id>
283
+ spur workflow commit-guard-stage --run <id> [--base <sha>] [-- <paths>...]
284
+ spur workflow commit-guard-check --run <id> [--base <sha>]
281
285
  ```
282
286
 
283
287
  ### `cost` — real-run measurements and budgets
@@ -185,11 +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
- `spur workflow 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
- 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> \
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> \
193
193
  || { echo "close-out halt: commit-guard refused a path (foreign, unmerged or conflict-marked); nothing committed" >&2; exit 1; }
194
194
  git commit -m "chore(wrap): <command> <selector> close-out writes"
195
195
  ```
@@ -311,7 +311,7 @@ per-task letter is ever hand-assigned.
311
311
  `spur workflow show task-pipeline.yaml --no-logo --format todo --json` payload:
312
312
 
313
313
  ```bash
314
- spur task batch-plan task-children --letter <task-letter> --plan <plan.json>
314
+ spur task batch-plan-children --letter <task-letter> --plan <plan.json>
315
315
  ```
316
316
 
317
317
  4. **When a task ends:** mark the task's letter (and its published digits) with the task's terminal
@@ -327,7 +327,7 @@ plan = resolve(--tasks) → freeze → order(deps) # may abort (cycle) or
327
327
  report = []
328
328
  publish visible plan §2.7: A/Z rows now; one letter per task after this freeze (task batch-plan waves)
329
329
  RUN_ID = WT-3 marker id under --worktree, else "batch-$(date -u +%Y%m%dT%H%M%SZ)" # fixed ONCE here; the close-out reuses it
330
- spur workflow commit-guard start --run "$RUN_ID" # 1129 R1: fingerprint before the first task writes; the close-out commit stages through it
330
+ spur workflow commit-guard-start --run "$RUN_ID" # 1129 R1: fingerprint before the first task writes; the close-out commit stages through it
331
331
  for wbs in plan: # default sequential mode
332
332
  if any dependency of wbs failed earlier in THIS batch:
333
333
  report += skipped(wbs, reason); continue # only relevant under --keep-going
@@ -338,7 +338,7 @@ for wbs in plan: # default sequential mode
338
338
  preflight = spur task preflight <wbs> # Step 2.6 — TABLE A STOP
339
339
  if preflight.action == skip:
340
340
  report += preflight-skip(wbs, preflight); continue
341
- visible plan (§2.7): letter in_progress + task-children digits at start; letter ← outcome at end
341
+ visible plan (§2.7): letter in_progress + batch-plan-children digits at start; letter ← outcome at end
342
342
  run: if interactive sequential omit/inline:
343
343
  spur workflow run task-pipeline.yaml --vars <vars with executor=host> --json
344
344
  perform the returned work item; spur workflow continue <run-id> --answer-text <receipt>
@@ -453,14 +453,14 @@ git checkout <base-ref> && git merge --no-ff -m "<prepared message>" <branch>
453
453
  # the batch's run id, the same one WT-3b's worktree fingerprint used — the two trees keep two
454
454
  # artifacts under the same id):
455
455
  # RUN_ID="<marker-id>" # the WT-3 marker's id
456
- # spur workflow commit-guard start --run "$RUN_ID"
456
+ # spur workflow commit-guard-start --run "$RUN_ID"
457
457
  # git checkout <base-ref> && git merge --no-commit <branch>
458
458
  # 2. resolve source conflicts by hand; generated files are then regenerated with the project's
459
459
  # generator, never hand-merged
460
460
  # (this repo: bun run --filter @gobing-ai/spur build:bundle)
461
461
  # 3. stage every resolved path and regenerated bundle through the guard — an unmerged or
462
462
  # unstaged path makes step 5 abort, and a conflict-marked path exits 3 (resolve, then retry):
463
- # spur workflow commit-guard stage --run "$RUN_ID" -- <resolved paths and regenerated bundles>
463
+ # spur workflow commit-guard-stage --run "$RUN_ID" -- <resolved paths and regenerated bundles>
464
464
  # Forbidden here as in every driver commit step: `git add -A` and `git add .`.
465
465
  # 4. run qualityGateCmd once, after ALL conflicts are resolved
466
466
  # 5. commit the merge with the prepared message file — CHECK THE PARENTS FIRST (step 5a)