@gobing-ai/spur 0.3.47 → 0.3.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/config.example.yaml +94 -15
  3. package/config/transition-shims.json +33 -0
  4. package/config/workflows/basic.yaml +2 -0
  5. package/config/workflows/docs-pipeline.yaml +2 -0
  6. package/config/workflows/feature-dev.yaml +8 -0
  7. package/config/workflows/idea-pipeline.yaml +10 -0
  8. package/config/workflows/planning-pipeline.yaml +4 -0
  9. package/config/workflows/pr-review.yaml +338 -0
  10. package/config/workflows/task-pipeline.yaml +8 -0
  11. package/config/workflows/wayfinder-resolution.yaml +4 -0
  12. package/config/workflows/wrapup-pipeline.yaml +18 -1
  13. package/package.json +8 -8
  14. package/plugins/sp/README.md +9 -6
  15. package/plugins/sp/agents/expert-spur.md +1 -0
  16. package/plugins/sp/commands/dev-arch.md +2 -1
  17. package/plugins/sp/commands/dev-brainstorm.md +2 -1
  18. package/plugins/sp/commands/dev-changelog.md +1 -0
  19. package/plugins/sp/commands/dev-daily.md +1 -0
  20. package/plugins/sp/commands/dev-debug.md +2 -1
  21. package/plugins/sp/commands/dev-dogfood.md +2 -1
  22. package/plugins/sp/commands/{dev-featurechange.md → dev-feature-change.md} +8 -10
  23. package/plugins/sp/commands/dev-find-conflict.md +2 -1
  24. package/plugins/sp/commands/dev-find-issue.md +36 -43
  25. package/plugins/sp/commands/dev-find-next.md +5 -4
  26. package/plugins/sp/commands/dev-fixall.md +1 -0
  27. package/plugins/sp/commands/dev-gitmsg.md +1 -0
  28. package/plugins/sp/commands/dev-gtd.md +12 -12
  29. package/plugins/sp/commands/dev-handover.md +1 -0
  30. package/plugins/sp/commands/dev-history-load.md +63 -0
  31. package/plugins/sp/commands/dev-idea.md +1 -0
  32. package/plugins/sp/commands/dev-next.md +2 -1
  33. package/plugins/sp/commands/dev-parallel.md +2 -1
  34. package/plugins/sp/commands/dev-plan.md +2 -1
  35. package/plugins/sp/commands/dev-pr-review.md +39 -0
  36. package/plugins/sp/commands/dev-refine.md +5 -3
  37. package/plugins/sp/commands/dev-refineall.md +2 -1
  38. package/plugins/sp/commands/dev-refresh.md +2 -1
  39. package/plugins/sp/commands/dev-reverse.md +2 -1
  40. package/plugins/sp/commands/dev-review.md +2 -1
  41. package/plugins/sp/commands/dev-run.md +3 -2
  42. package/plugins/sp/commands/dev-runall.md +3 -2
  43. package/plugins/sp/commands/dev-simplify.md +2 -1
  44. package/plugins/sp/commands/dev-unit.md +2 -1
  45. package/plugins/sp/commands/dev-verify.md +2 -1
  46. package/plugins/sp/commands/dev-verifyall.md +2 -1
  47. package/plugins/sp/commands/dev-wrap.md +7 -5
  48. package/plugins/sp/commands/dev-wrapall.md +7 -5
  49. package/plugins/sp/commands/rule-add.md +1 -0
  50. package/plugins/sp/commands/rule-refine.md +1 -0
  51. package/plugins/sp/commands/rule-scan.md +1 -0
  52. package/plugins/sp/commands/spur-init.md +1 -0
  53. package/plugins/sp/commands/workflow-add.md +1 -0
  54. package/plugins/sp/commands/workflow-refine.md +1 -0
  55. package/plugins/sp/hooks/careful-guard.ts +5 -80
  56. package/plugins/sp/hooks/destructive-policy.ts +146 -0
  57. package/plugins/sp/hooks/pi/guard-extension.ts +33 -46
  58. package/plugins/sp/hooks/task-file-policy.ts +31 -0
  59. package/plugins/sp/hooks/task-write-guard.ts +4 -0
  60. package/plugins/sp/plugin.json +1 -1
  61. package/plugins/sp/references/roles.md +106 -0
  62. package/plugins/sp/scripts/feature-sync-bounded.ts +28 -2
  63. package/plugins/sp/scripts/history-load.ts +400 -0
  64. package/plugins/sp/scripts/pr-reviewing.ts +867 -0
  65. package/plugins/sp/scripts/stage-registry-adapter.ts +66 -31
  66. package/plugins/sp/scripts/surface-drift-inventory.ts +908 -0
  67. package/plugins/sp/scripts/task-size-precheck.ts +30 -4
  68. package/plugins/sp/scripts/transition-shim-check.ts +238 -0
  69. package/plugins/sp/scripts/validate-commands.ts +33 -2
  70. package/plugins/sp/scripts/validate-flag-contracts.ts +5 -2
  71. package/plugins/sp/skills/code-implementation/SKILL.md +9 -1
  72. package/plugins/sp/skills/code-verification/SKILL.md +29 -28
  73. package/plugins/sp/skills/issue-finding/SKILL.md +123 -141
  74. package/plugins/sp/skills/issue-finding/examples/expected-findings.json +1 -1
  75. package/plugins/sp/skills/issue-finding/references/session-formats.md +87 -90
  76. package/plugins/sp/skills/next-feature/SKILL.md +6 -6
  77. package/plugins/sp/skills/next-feature/references/handoff-routing.md +5 -5
  78. package/plugins/sp/skills/next-feature/references/signal-derivation.md +7 -2
  79. package/plugins/sp/skills/next-router/SKILL.md +1 -1
  80. package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +40 -2
  81. package/plugins/sp/skills/pr-reviewing/SKILL.md +285 -0
  82. package/plugins/sp/skills/spur-cli/SKILL.md +3 -0
  83. package/plugins/sp/skills/spur-cli/references/agent.md +12 -7
  84. package/plugins/sp/skills/spur-cli/references/features/hierarchy-mece.md +5 -5
  85. package/plugins/sp/skills/spur-cli/references/features.md +1 -1
  86. package/plugins/sp/skills/spur-cli/references/team.md +10 -3
  87. package/plugins/sp/skills/spur-dev/SKILL.md +2 -0
  88. package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +17 -0
  89. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +44 -23
  90. package/plugins/sp/skills/spur-dev/references/dev-operations.md +14 -11
  91. package/plugins/sp/skills/spur-dev/references/execution-workflow.md +14 -12
  92. package/plugins/sp/skills/spur-dev/references/flag-glossary.md +28 -7
  93. package/plugins/sp/skills/spur-dev/references/gate-checklists.md +2 -0
  94. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +12 -2
  95. package/schemas/spur-config.schema.json +47 -3
  96. package/spur.js +12223 -7716
  97. package/web/_astro/BoardApp.8hiqShQn.js +1 -0
  98. package/web/_astro/{BoardApp.DKyrGxdo.js → BoardApp.BjQUNhuj.js} +74 -74
  99. package/web/_astro/{TaskDetail.6-27_LMa.js → TaskDetail.CVBuD6dF.js} +1 -1
  100. package/web/_astro/{arc.Df-9AQvS.js → arc.BMMjdODi.js} +1 -1
  101. package/web/_astro/{architectureDiagram-3BPJPVTR.VAI_-paS.js → architectureDiagram-3BPJPVTR.BU5ShzXf.js} +1 -1
  102. package/web/_astro/{blockDiagram-GPEHLZMM.DFpUY1ue.js → blockDiagram-GPEHLZMM.Bj1iEqPD.js} +1 -1
  103. package/web/_astro/{c4Diagram-AAUBKEIU.CF8doOpg.js → c4Diagram-AAUBKEIU.vX8wepCL.js} +1 -1
  104. package/web/_astro/channel.EwdSemIC.js +1 -0
  105. package/web/_astro/{chunk-2J33WTMH.BnjK3fjt.js → chunk-2J33WTMH.BKAipTym.js} +1 -1
  106. package/web/_astro/{chunk-4BX2VUAB.x6ZDnJKq.js → chunk-4BX2VUAB.B68XkPG7.js} +1 -1
  107. package/web/_astro/{chunk-55IACEB6.zY-0uu7w.js → chunk-55IACEB6.BmeDLcrc.js} +1 -1
  108. package/web/_astro/{chunk-727SXJPM.BZxKg_Vi.js → chunk-727SXJPM.PDuBA3Kw.js} +1 -1
  109. package/web/_astro/{chunk-AQP2D5EJ.Cpi9G9Td.js → chunk-AQP2D5EJ.C7A044za.js} +1 -1
  110. package/web/_astro/{chunk-FMBD7UC4.DWTB-Pif.js → chunk-FMBD7UC4.BtzKKFqR.js} +1 -1
  111. package/web/_astro/{chunk-ND2GUHAM.BPDQbiOG.js → chunk-ND2GUHAM.BJuDeeOy.js} +1 -1
  112. package/web/_astro/{chunk-QZHKN3VN.BRWIcuoM.js → chunk-QZHKN3VN.DSeMDgcQ.js} +1 -1
  113. package/web/_astro/{classDiagram-4FO5ZUOK.mGTCZsDO.js → classDiagram-4FO5ZUOK.D53Q4tCw.js} +1 -1
  114. package/web/_astro/{classDiagram-v2-Q7XG4LA2.mGTCZsDO.js → classDiagram-v2-Q7XG4LA2.D53Q4tCw.js} +1 -1
  115. package/web/_astro/{cose-bilkent-S5V4N54A.D1GEut-z.js → cose-bilkent-S5V4N54A.c712AFRH.js} +1 -1
  116. package/web/_astro/{dagre-BM42HDAG.BV0XG9Do.js → dagre-BM42HDAG.D-idisph.js} +1 -1
  117. package/web/_astro/{diagram-2AECGRRQ.DzpYxsjo.js → diagram-2AECGRRQ.DLgnsJCU.js} +1 -1
  118. package/web/_astro/{diagram-5GNKFQAL.Cm9YzJh4.js → diagram-5GNKFQAL.BiaxBVqx.js} +1 -1
  119. package/web/_astro/{diagram-KO2AKTUF.BjhottUj.js → diagram-KO2AKTUF.C8HX1vd8.js} +1 -1
  120. package/web/_astro/{diagram-LMA3HP47.BFsQW5kb.js → diagram-LMA3HP47.CfqDLLes.js} +1 -1
  121. package/web/_astro/{diagram-OG6HWLK6.8pdpzSWO.js → diagram-OG6HWLK6.15SDiEed.js} +1 -1
  122. package/web/_astro/{erDiagram-TEJ5UH35.Bd7KUJmJ.js → erDiagram-TEJ5UH35.DksYtOYM.js} +1 -1
  123. package/web/_astro/{flowDiagram-I6XJVG4X.7LWffkaE.js → flowDiagram-I6XJVG4X.DR_Au-HV.js} +1 -1
  124. package/web/_astro/{ganttDiagram-6RSMTGT7.BeDcO5tI.js → ganttDiagram-6RSMTGT7.CHhHrffI.js} +1 -1
  125. package/web/_astro/{gitGraphDiagram-PVQCEYII.Ca4n730A.js → gitGraphDiagram-PVQCEYII.B2Xehvam.js} +1 -1
  126. package/web/_astro/{index.Dbvuw6d4.css → index.DAxu50UF.css} +1 -1
  127. package/web/_astro/{infoDiagram-5YYISTIA.B0OakQYb.js → infoDiagram-5YYISTIA.C9c3CNNN.js} +1 -1
  128. package/web/_astro/{ishikawaDiagram-YF4QCWOH.DSmNQe-1.js → ishikawaDiagram-YF4QCWOH.BibUHkh8.js} +1 -1
  129. package/web/_astro/{journeyDiagram-JHISSGLW.Cy5ruEUu.js → journeyDiagram-JHISSGLW.BYoVHiyO.js} +1 -1
  130. package/web/_astro/{kanban-definition-UN3LZRKU.CUJXub0p.js → kanban-definition-UN3LZRKU.CM1K5wHE.js} +1 -1
  131. package/web/_astro/{linear.DC1jCCXn.js → linear.SPpjJUb-.js} +1 -1
  132. package/web/_astro/{mermaid.core.DxVP99Ab.js → mermaid.core.BAgx3nnb.js} +4 -4
  133. package/web/_astro/{mindmap-definition-RKZ34NQL.D0MaV6sJ.js → mindmap-definition-RKZ34NQL.D35oPG1R.js} +1 -1
  134. package/web/_astro/{pieDiagram-4H26LBE5.DCC6_q32.js → pieDiagram-4H26LBE5.DiWuRwk7.js} +1 -1
  135. package/web/_astro/{quadrantDiagram-W4KKPZXB.BeUOAM7C.js → quadrantDiagram-W4KKPZXB.B9PBzTWn.js} +1 -1
  136. package/web/_astro/{requirementDiagram-4Y6WPE33.Dbl4MASO.js → requirementDiagram-4Y6WPE33.CYuuamFN.js} +1 -1
  137. package/web/_astro/{sankeyDiagram-5OEKKPKP.HsLg0VS4.js → sankeyDiagram-5OEKKPKP.W24UhhtD.js} +1 -1
  138. package/web/_astro/{sequenceDiagram-3UESZ5HK.DT7DJTnZ.js → sequenceDiagram-3UESZ5HK.BpbNjA51.js} +1 -1
  139. package/web/_astro/{stateDiagram-AJRCARHV.d_ju1Vr1.js → stateDiagram-AJRCARHV.DqVsHudf.js} +1 -1
  140. package/web/_astro/{stateDiagram-v2-BHNVJYJU.DMCAjMJ4.js → stateDiagram-v2-BHNVJYJU.CzwHYX81.js} +1 -1
  141. package/web/_astro/{timeline-definition-PNZ67QCA.DNOHr62_.js → timeline-definition-PNZ67QCA.Bc3B6djw.js} +1 -1
  142. package/web/_astro/{vennDiagram-CIIHVFJN.B7dUy-1W.js → vennDiagram-CIIHVFJN.C-D5rh8O.js} +1 -1
  143. package/web/_astro/{wardley-L42UT6IY.DEqOXvBh.js → wardley-L42UT6IY.D7PdYCqn.js} +1 -1
  144. package/web/_astro/{wardleyDiagram-YWT4CUSO.BCRb2p6x.js → wardleyDiagram-YWT4CUSO.CwmJKXF3.js} +1 -1
  145. package/web/_astro/{xychartDiagram-2RQKCTM6.NxVQLdBh.js → xychartDiagram-2RQKCTM6.avDYnLsb.js} +1 -1
  146. package/web/index.html +2 -2
  147. package/web/_astro/BoardApp.Ce6zJYAH.js +0 -1
  148. package/web/_astro/channel.Uhm9O3UV.js +0 -1
@@ -0,0 +1,338 @@
1
+ # PR-review workflow: deterministic spine for /sp:dev-pr-review (skill sp:pr-reviewing).
2
+ # Authored for the @gobing-ai/ts-dual-workflow-engine state-machine schema
3
+ # (initialState / states[].id / onEnter / top-level transitions), same family as
4
+ # basic.yaml / task-pipeline.yaml. Seeded into projects by `spur init` (scaffold manifest).
5
+ #
6
+ # Shape: preflight → hygiene → precheck → push → ensure-pr → request → wait → collect → done
7
+ # (soft probes everywhere: red gates route to `failed`/`pending` via transitions,
8
+ # never a raw lifecycle abort — same reliability contract as basic.yaml)
9
+ #
10
+ # This YAML is the SSOT for the review spine's state order and guards. Every state shells
11
+ # out to the staged pr-reviewing.ts entrypoint (the tested deterministic core); no gh/git
12
+ # logic lives in this file. All model-bearing work — finding triage, `fix` mode, `rules`
13
+ # mode — stays in the sp:pr-reviewing skill and never enters this machine.
14
+ #
15
+ # Non-negotiable: the external review goes through the GitHub PR + an `@codex review`
16
+ # comment. Never substitute a local Codex review mechanism.
17
+ #
18
+ # Vars (override per run: --vars '{"mode":"submit","focus":"migration safety"}'):
19
+ # mode — full (default) | submit | rerun
20
+ # full: dedupe an up-to-date Codex review, else request + wait + collect
21
+ # submit: request and stop at `pending` (no wait)
22
+ # rerun: request with --force even when HEAD is already reviewed
23
+ # baseBranch — base for a newly created PR (default: existing PR base, else repo default)
24
+ # focus — extra review focus appended to the @codex request
25
+ # noWait — "true" returns pending right after the request instead of polling
26
+ # waitTimeoutSec — poll budget for Codex output (default 600)
27
+ # waitIntervalSec — poll interval (default 30; do not poll aggressively)
28
+ # preReviewCmd — project fast check run before requesting (empty = skipped).
29
+ # TRUSTED CONFIG ONLY — executed via `sh -c` (task 0436 SECUA residual).
30
+ # Never interpolate untrusted operator/LLM input into it.
31
+ # __runId — injected by WorkflowAppService.run(); scopes .spur/run artifacts.
32
+
33
+ "$schema": "@gobing-ai/spur/schemas/state-machine-workflow.schema.json"
34
+ name: pr-review
35
+ kind: state-machine
36
+ description: GitHub Codex PR-review spine — preflight → hygiene → precheck → push → ensure-pr → request → wait → collect
37
+ iterationBound: 16
38
+ initialState: preflight
39
+ terminalStates:
40
+ - done
41
+ - pending
42
+ - failed
43
+ failureStates:
44
+ - failed
45
+ vars:
46
+ mode: 'full'
47
+ baseBranch: ''
48
+ focus: ''
49
+ noWait: 'false'
50
+ waitTimeoutSec: '600'
51
+ waitIntervalSec: '30'
52
+ preReviewCmd: ''
53
+ __runId: ''
54
+
55
+ states:
56
+ - id: preflight
57
+ description: >
58
+ Soft probe: git/gh/repo checks (detached HEAD, dirty tree, gh auth, GitHub remote).
59
+ Writes PASS|FAIL to .spur/run/${vars.__runId}-pr-preflight.status; always exit 0.
60
+ onEnter:
61
+ - kind: shell
62
+ options:
63
+ command: >-
64
+ mkdir -p .spur/run &&
65
+ STATUS_FILE=".spur/run/$__runId-pr-preflight.status" &&
66
+ set +e &&
67
+ bun "$(superskill script path sp pr-reviewing.ts)" preflight --json > ".spur/run/$__runId-pr-context.json";
68
+ rc=$?; set -e &&
69
+ if [ "$rc" -eq 0 ]; then printf 'PASS\n' > "$STATUS_FILE"; else printf 'FAIL\n' > "$STATUS_FILE"; fi &&
70
+ exit 0
71
+
72
+ - id: hygiene
73
+ description: >
74
+ Submission sanity scan of base...HEAD: secrets/.env/conflict markers BLOCK the run;
75
+ debug residue only WARNs. Not a replacement for the independent Codex review.
76
+ onEnter:
77
+ - kind: shell
78
+ options:
79
+ command: >-
80
+ mkdir -p .spur/run &&
81
+ STATUS_FILE=".spur/run/$__runId-pr-hygiene.status" &&
82
+ set +e &&
83
+ bun "$(superskill script path sp pr-reviewing.ts)" hygiene --base "$baseBranch" --json
84
+ --status-file "$STATUS_FILE" > ".spur/run/$__runId-pr-hygiene.json";
85
+ rc=$?; set -e &&
86
+ if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
87
+ exit 0
88
+
89
+ - id: precheck
90
+ description: >
91
+ Optional project fast check (vars.preReviewCmd) before spending a review request.
92
+ Empty command records SKIP; a red check stops the run before request (fail loud).
93
+ onEnter:
94
+ - kind: shell
95
+ options:
96
+ command: >-
97
+ mkdir -p .spur/run &&
98
+ STATUS_FILE=".spur/run/$__runId-pr-precheck.status" &&
99
+ if [ -z "$preReviewCmd" ]; then
100
+ printf 'SKIP\n' > "$STATUS_FILE";
101
+ else
102
+ set +e; sh -c "$preReviewCmd"; rc=$?; set -e;
103
+ if [ "$rc" -eq 0 ]; then printf 'PASS\n' > "$STATUS_FILE"; else printf 'FAIL\n' > "$STATUS_FILE"; fi;
104
+ fi &&
105
+ exit 0
106
+
107
+ - id: push
108
+ description: >
109
+ Publish the branch (normal push only, never force; sets upstream when missing).
110
+ A PR reviews pushed commits only.
111
+ onEnter:
112
+ - kind: shell
113
+ options:
114
+ command: >-
115
+ mkdir -p .spur/run &&
116
+ STATUS_FILE=".spur/run/$__runId-pr-push.status" &&
117
+ set +e &&
118
+ bun "$(superskill script path sp pr-reviewing.ts)" push --json --status-file "$STATUS_FILE"
119
+ > ".spur/run/$__runId-pr-push.json";
120
+ rc=$?; set -e &&
121
+ if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
122
+ exit 0
123
+
124
+ - id: ensure-pr
125
+ description: Find or create the GitHub PR for the current branch — never a duplicate.
126
+ onEnter:
127
+ - kind: shell
128
+ options:
129
+ command: >-
130
+ mkdir -p .spur/run &&
131
+ STATUS_FILE=".spur/run/$__runId-pr-ensure.status" &&
132
+ set +e &&
133
+ bun "$(superskill script path sp pr-reviewing.ts)" ensure-pr --base "$baseBranch" --json
134
+ --status-file "$STATUS_FILE" > ".spur/run/$__runId-pr.json";
135
+ rc=$?; set -e &&
136
+ if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
137
+ exit 0
138
+
139
+ - id: request
140
+ description: >
141
+ Post the `@codex review` request (per-HEAD dedupe unless mode=rerun forces).
142
+ Records the request under .spur/run/${vars.__runId}-pr-request.json.
143
+ onEnter:
144
+ - kind: shell
145
+ options:
146
+ command: >-
147
+ mkdir -p .spur/run &&
148
+ STATUS_FILE=".spur/run/$__runId-pr-request.status" &&
149
+ FORCE_FLAG="" &&
150
+ if [ "$mode" = "rerun" ]; then FORCE_FLAG="--force"; fi &&
151
+ set +e &&
152
+ bun "$(superskill script path sp pr-reviewing.ts)" request --focus "$focus" $FORCE_FLAG --json
153
+ --status-file "$STATUS_FILE" > ".spur/run/$__runId-pr-request.json";
154
+ rc=$?; set -e &&
155
+ if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
156
+ exit 0
157
+
158
+ - id: wait
159
+ description: >
160
+ Bounded poll for Codex output on the current pushed HEAD. Timeout records TIMEOUT
161
+ and routes to `pending` — never a failure (collect later with /sp:dev-pr-review collect).
162
+ onEnter:
163
+ - kind: shell
164
+ options:
165
+ command: >-
166
+ mkdir -p .spur/run &&
167
+ STATUS_FILE=".spur/run/$__runId-pr-wait.status" &&
168
+ set +e &&
169
+ SINCE="$(bun -e 'const fs=require("node:fs");const value=JSON.parse(fs.readFileSync(process.argv[1],"utf8")).requestedAt;process.stdout.write(value ?? "")' ".spur/run/$__runId-pr-request.json")" &&
170
+ REQUEST_HEAD="$(bun -e 'const fs=require("node:fs");const value=JSON.parse(fs.readFileSync(process.argv[1],"utf8")).head;process.stdout.write(value ?? "")' ".spur/run/$__runId-pr-request.json")" &&
171
+ bun "$(superskill script path sp pr-reviewing.ts)" wait --since "$SINCE" --head "$REQUEST_HEAD" --timeout "$waitTimeoutSec" --interval "$waitIntervalSec"
172
+ --json --status-file "$STATUS_FILE" > ".spur/run/$__runId-pr-wait.json";
173
+ rc=$?; set -e &&
174
+ if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
175
+ exit 0
176
+
177
+ - id: collect
178
+ description: Normalize the latest current-HEAD Codex result and record composite PR/CI status.
179
+ onEnter:
180
+ - kind: shell
181
+ options:
182
+ command: >-
183
+ mkdir -p .spur/run &&
184
+ STATUS_FILE=".spur/run/$__runId-pr-collect.status" &&
185
+ set +e &&
186
+ SINCE="$(bun -e 'const fs=require("node:fs");const value=JSON.parse(fs.readFileSync(process.argv[1],"utf8")).requestedAt;process.stdout.write(value ?? "")' ".spur/run/$__runId-pr-request.json")" &&
187
+ REQUEST_HEAD="$(bun -e 'const fs=require("node:fs");const value=JSON.parse(fs.readFileSync(process.argv[1],"utf8")).head;process.stdout.write(value ?? "")' ".spur/run/$__runId-pr-request.json")" &&
188
+ bun "$(superskill script path sp pr-reviewing.ts)" collect --since "$SINCE" --head "$REQUEST_HEAD" --json
189
+ --status-file "$STATUS_FILE" > ".spur/run/$__runId-pr-findings.json";
190
+ collect_rc=$?;
191
+ bun "$(superskill script path sp pr-reviewing.ts)" status --since "$SINCE" --head "$REQUEST_HEAD" --json > ".spur/run/$__runId-pr-status.json";
192
+ status_rc=$?; set -e &&
193
+ if [ "$collect_rc" -ne 0 ] || [ "$status_rc" -ne 0 ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
194
+ if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
195
+ { cat ".spur/run/$__runId-pr-findings.json" 2>/dev/null || true; } &&
196
+ exit 0
197
+
198
+ - id: done
199
+ description: Terminal — review collected; findings artifact at .spur/run/${vars.__runId}-pr-findings.json
200
+ - id: pending
201
+ description: Terminal — review requested (or timed out) but not yet collected; run /sp:dev-pr-review collect later
202
+ - id: failed
203
+ description: Terminal — a gate went red; the stage .status/.json artifacts under .spur/run name the blocker
204
+
205
+ transitions:
206
+ - from: preflight
207
+ to: hygiene
208
+ description: Repo, gh auth, and clean tree verified
209
+ guard:
210
+ kind: shell
211
+ options:
212
+ command: 'test "$(cat .spur/run/$__runId-pr-preflight.status 2>/dev/null)" = PASS'
213
+ - from: preflight
214
+ to: failed
215
+ description: Preflight red (detached HEAD, dirty tree, gh auth, no GitHub remote) — stop before any publishing
216
+ guard:
217
+ kind: always
218
+
219
+ - from: hygiene
220
+ to: precheck
221
+ description: Clean or warn-only — warnings ride along to the report
222
+ guard:
223
+ kind: shell
224
+ options:
225
+ command: 'grep -qE "^(PASS|WARN)$" .spur/run/$__runId-pr-hygiene.status 2>/dev/null'
226
+ - from: hygiene
227
+ to: failed
228
+ description: BLOCK (secrets/.env/conflict markers) or probe failure — never submit a tainted diff
229
+ guard:
230
+ kind: always
231
+
232
+ - from: precheck
233
+ to: push
234
+ description: Project fast check passed or was skipped
235
+ guard:
236
+ kind: shell
237
+ options:
238
+ command: 'grep -qE "^(PASS|SKIP)$" .spur/run/$__runId-pr-precheck.status 2>/dev/null'
239
+ - from: precheck
240
+ to: failed
241
+ description: Project checks red — do not spend a review request on code that fails its own gate
242
+ guard:
243
+ kind: always
244
+
245
+ - from: push
246
+ to: ensure-pr
247
+ description: Branch published (or already up to date)
248
+ guard:
249
+ kind: shell
250
+ options:
251
+ command: 'grep -qE "^(PUSHED|UP_TO_DATE)$" .spur/run/$__runId-pr-push.status 2>/dev/null'
252
+ - from: push
253
+ to: failed
254
+ description: Push rejected (e.g. non-fast-forward) — report; never force-push as a workaround
255
+ guard:
256
+ kind: always
257
+
258
+ - from: ensure-pr
259
+ to: request
260
+ description: PR found or created
261
+ guard:
262
+ kind: shell
263
+ options:
264
+ command: 'grep -qE "^(FOUND|CREATED)$" .spur/run/$__runId-pr-ensure.status 2>/dev/null'
265
+ - from: ensure-pr
266
+ to: failed
267
+ description: No reviewable delta or PR creation failed — report the actual git/GitHub state
268
+ guard:
269
+ kind: always
270
+
271
+ # Declaration order matters: ALREADY_REVIEWED routes straight to collect (full mode dedupe);
272
+ # submit/noWait stop at pending; everything else waits.
273
+ - from: request
274
+ to: collect
275
+ description: Current HEAD already carries a Codex review — collect instead of duplicating
276
+ guard:
277
+ kind: shell
278
+ options:
279
+ command: 'test "$(cat .spur/run/$__runId-pr-request.status 2>/dev/null)" = ALREADY_REVIEWED'
280
+ - from: request
281
+ to: pending
282
+ description: Request already in flight, or mode=submit/--no-wait after posting — return pending
283
+ guard:
284
+ kind: shell
285
+ options:
286
+ command: 'test "$(cat .spur/run/$__runId-pr-request.status 2>/dev/null)" = ALREADY_REQUESTED || { test "$(cat .spur/run/$__runId-pr-request.status 2>/dev/null)" = REQUESTED && { test "$mode" = "submit" || test "$noWait" = "true"; }; }'
287
+ - from: request
288
+ to: wait
289
+ description: Request posted — poll for the result
290
+ guard:
291
+ kind: shell
292
+ options:
293
+ command: 'test "$(cat .spur/run/$__runId-pr-request.status 2>/dev/null)" = REQUESTED'
294
+ - from: request
295
+ to: failed
296
+ description: Request failed (no PR, gh error) — report the preserved error
297
+ guard:
298
+ kind: always
299
+
300
+ - from: wait
301
+ to: collect
302
+ description: Codex findings or an explicit clean result on the current HEAD found
303
+ guard:
304
+ kind: shell
305
+ options:
306
+ command: 'grep -qE "^(FOUND|CLEAN)$" .spur/run/$__runId-pr-wait.status 2>/dev/null'
307
+ - from: wait
308
+ to: pending
309
+ description: Poll budget exhausted — pending, not failed
310
+ guard:
311
+ kind: shell
312
+ options:
313
+ command: 'test "$(cat .spur/run/$__runId-pr-wait.status 2>/dev/null)" = TIMEOUT'
314
+ - from: wait
315
+ to: failed
316
+ description: Poll probe itself failed
317
+ guard:
318
+ kind: always
319
+
320
+ - from: collect
321
+ to: done
322
+ description: Current-HEAD review collected (CLEAN/FINDINGS)
323
+ guard:
324
+ kind: shell
325
+ options:
326
+ command: 'grep -qE "^(FINDINGS|CLEAN)$" .spur/run/$__runId-pr-collect.status 2>/dev/null'
327
+ - from: collect
328
+ to: pending
329
+ description: No current-HEAD result yet — pending, never clean
330
+ guard:
331
+ kind: shell
332
+ options:
333
+ command: 'test "$(cat .spur/run/$__runId-pr-collect.status 2>/dev/null)" = PENDING'
334
+ - from: collect
335
+ to: failed
336
+ description: Collect probe failed
337
+ guard:
338
+ kind: always
@@ -262,6 +262,8 @@ states:
262
262
  options:
263
263
  agent: ${vars.implementAgent}
264
264
  # Pure slash command only (ADR-043). Anti-recursion / implement discipline
265
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
266
+ role: coder
265
267
  # lives in /sp:dev-run --mode implement → sp:code-implementation, not YAML prose.
266
268
  input: /sp:dev-run --mode implement ${vars.wbs} --auto
267
269
  timeoutMs: ${vars.implementTimeoutMs}
@@ -374,6 +376,8 @@ states:
374
376
  options:
375
377
  agent: ${vars.agent}
376
378
  # R3 (0482): `--findings` names the failing anchors inline; `--gate-log` remains
379
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
380
+ role: coder
377
381
  # the full-context escape hatch when the digest is not enough.
378
382
  input: /sp:dev-fixall "${vars.qualityGateCmd}" --gate-log .spur/run/${vars.wbs}-test-gate.log --findings "${vars.gateFindings}"
379
383
  timeoutMs: ${vars.stepTimeoutMs}
@@ -422,6 +426,8 @@ states:
422
426
  options:
423
427
  agent: ${vars.agent}
424
428
  input: /sp:dev-review ${vars.wbs} --auto
429
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
430
+ role: reviewer
425
431
  timeoutMs: ${vars.stepTimeoutMs}
426
432
 
427
433
  - id: approve
@@ -452,6 +458,8 @@ states:
452
458
  options:
453
459
  agent: ${vars.agent}
454
460
  input: /sp:dev-verify ${vars.wbs} --auto --fix all --focus all
461
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
462
+ role: reviewer
455
463
  timeoutMs: ${vars.stepTimeoutMs}
456
464
  answerFile: .spur/run/${vars.wbs}-verify-answer.txt
457
465
  - kind: shell
@@ -82,6 +82,8 @@ states:
82
82
  options:
83
83
  agent: ${vars.agent}
84
84
  capture: true
85
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
86
+ role: planner
85
87
  mode: text
86
88
  input: >-
87
89
  Resolve task ${vars.wbs} in resolution mode ${vars.resolutionMode} using the prepared
@@ -115,6 +117,8 @@ states:
115
117
  options:
116
118
  agent: ${vars.agent}
117
119
  capture: true
120
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
121
+ role: reviewer
118
122
  mode: text
119
123
  input: >-
120
124
  Verify resolved task ${vars.wbs} using only local reads and `spur` CLI. Check its
@@ -80,7 +80,9 @@ states:
80
80
  - kind: agent.run
81
81
  options:
82
82
  agent: ${vars.agent}
83
- input: "Skill(skill=\"sp:doc-evolve\", args=\"wrapup tasks=${vars.tasks}\"). Repair drift in docs/00_ADR.md, docs/03_ARCHITECTURE.md, docs/04_DESIGN.md, docs/design/* per constitution edit rules. Do not write task/feature corpus."
83
+ input: 'Skill(skill="sp:doc-evolve", args="wrapup tasks=${vars.tasks}"). Repair drift in docs/00_ADR.md, docs/03_ARCHITECTURE.md, docs/04_DESIGN.md, docs/design/* per constitution edit rules. Do not write task/feature corpus.'
84
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
85
+ role: coder
84
86
  timeoutMs: ${vars.stepTimeoutMs}
85
87
 
86
88
  - id: learning-capture
@@ -93,6 +95,8 @@ states:
93
95
  options:
94
96
  agent: ${vars.agent}
95
97
  input: "Extract working learnings from tasks ${vars.tasks}. Output raw markdown (no fences) grouped by date and task WBS: conventions, errors fixed, patterns, gotchas. Captured to .spur/run/wrapup-learnings.md."
98
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
99
+ role: coder
96
100
  answerFile: .spur/run/wrapup-learnings.md
97
101
  expectFile: .spur/run/wrapup-learnings.md
98
102
  timeoutMs: ${vars.stepTimeoutMs}
@@ -103,6 +107,8 @@ states:
103
107
  if test -s .spur/run/wrapup-learnings.md; then
104
108
  cat .spur/run/wrapup-learnings.md >> .spur/memory/learnings.md &&
105
109
  printf '\n' >> .spur/memory/learnings.md;
110
+ else
111
+ echo "wrapup: learning capture missing or empty at $PWD/.spur/run/wrapup-learnings.md - append skipped" >&2;
106
112
  fi &&
107
113
  exit 0
108
114
 
@@ -115,6 +121,8 @@ states:
115
121
  options:
116
122
  agent: ${vars.agent}
117
123
  input: "For each task in ${vars.tasks}, output one JSONL line (no fences) with fields: wbs, feature_id, status, verdict, timestamp. Captured to .spur/run/wrapup-metrics.jsonl."
124
+ # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
125
+ role: scribe
118
126
  answerFile: .spur/run/wrapup-metrics.jsonl
119
127
  expectFile: .spur/run/wrapup-metrics.jsonl
120
128
  timeoutMs: ${vars.stepTimeoutMs}
@@ -124,6 +132,8 @@ states:
124
132
  mkdir -p .spur/memory &&
125
133
  if test -s .spur/run/wrapup-metrics.jsonl; then
126
134
  cat .spur/run/wrapup-metrics.jsonl >> .spur/memory/wrapup-metrics.jsonl;
135
+ else
136
+ echo "wrapup: metrics capture missing or empty at $PWD/.spur/run/wrapup-metrics.jsonl - append skipped" >&2;
127
137
  fi &&
128
138
  exit 0
129
139
 
@@ -131,6 +141,9 @@ states:
131
141
  description: >
132
142
  If vars.feature is set, sync feature status via bounded feature-sync-bounded
133
143
  (0411). Soft shell — blocked/failed sync must not abort wrap-up after metrics.
144
+ Empty vars.feature is NOT a blocked sync but a mis-invocation (the engine only
145
+ enters this state when vars.feature is set) and fails loud (dogfood 2026-08-15,
146
+ feature I3: a silent exit 0 made the wrap look complete with no transition).
134
147
  onEnter:
135
148
  # Genuinely soft: the terminating `exit 0` must be reached on BOTH branches, so
136
149
  # the sync is chained with `;` — with `&&` a non-zero sync skipped `exit 0` and
@@ -142,6 +155,10 @@ states:
142
155
  - kind: shell
143
156
  options:
144
157
  command: >-
158
+ if [ -z "$feature" ]; then
159
+ echo "feature-transition: vars.feature is empty — refusing no-op feature sync (mis-invocation, not a blocked sync)" >&2;
160
+ exit 1;
161
+ fi;
145
162
  if [ -f plugins/sp/scripts/feature-sync-bounded.ts ]; then
146
163
  bun plugins/sp/scripts/feature-sync-bounded.ts "$feature" --spur-bin "$spurBin" --json;
147
164
  else
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobing-ai/spur",
3
- "version": "0.3.47",
3
+ "version": "0.3.49",
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",
@@ -53,14 +53,14 @@
53
53
  },
54
54
  "devDependencies": {
55
55
  "@commander-js/extra-typings": "^14.0.0",
56
- "@gobing-ai/ts-db": "^0.4.31",
57
- "@gobing-ai/ts-ai-runner": "^0.4.31",
58
- "@gobing-ai/ts-dual-workflow-engine": "^0.4.31",
59
- "@gobing-ai/ts-infra": "^0.4.31",
56
+ "@gobing-ai/ts-db": "^0.4.35",
57
+ "@gobing-ai/ts-ai-runner": "^0.4.35",
58
+ "@gobing-ai/ts-dual-workflow-engine": "^0.4.35",
59
+ "@gobing-ai/ts-infra": "^0.4.35",
60
60
  "@gobing-ai/ts-llm-jsonl-importer": "^0.4.31",
61
- "@gobing-ai/ts-rule-engine": "^0.4.31",
62
- "@gobing-ai/ts-runtime": "^0.4.31",
63
- "@gobing-ai/ts-utils": "^0.4.31",
61
+ "@gobing-ai/ts-rule-engine": "^0.4.35",
62
+ "@gobing-ai/ts-runtime": "^0.4.35",
63
+ "@gobing-ai/ts-utils": "^0.4.35",
64
64
  "@types/bun": "1.3.14",
65
65
  "@types/figlet": "^1.7.0",
66
66
  "@types/node-notifier": "8.0.5",
@@ -103,11 +103,12 @@ list this README is checked against.
103
103
  | `dev-next` | Status-aware router — inspect a task (or next frontier under a feature), dispatch the best existing `/sp:dev-*` command, chain on clean success |
104
104
  | `dev-run` | Run a task — full pipeline (precheck→implement→test→review→approve→verify→record→done) or single-step (implement) |
105
105
  | `dev-review` | Multi-dimensional review for a task or path — functional requirements traceability, SECUA framework, and architectural depth |
106
+ | `dev-pr-review` | GitHub Codex PR review — prepare/reuse a PR, request `@codex review`, collect findings, validate/fix/re-review (fix mode); workflow-backed spine |
106
107
  | `dev-verify` | Verify a task against its requirements and Acceptance Criteria — traceability check producing a PASS/PARTIAL/FAIL verdict with evidence |
107
108
  | `dev-unit` | Generate or extend tests until the unit target is met |
108
109
  | `dev-wrap` | Wrap up a single completed task — learnings, metrics, doc-sync, optional feature transition and branch cleanup |
109
110
  | `dev-refresh` | Refresh feature status by feature ID, task WBS, or batch sweep via spur feature sync |
110
- | `dev-featurechange` | Restructure feature tree from a mapping file — dry-run/apply via `spur feature move`, task edges, root `docs/*.md` only |
111
+ | `dev-feature-change` | Restructure feature tree from a mapping file — dry-run/apply via `spur feature move`, task edges, root `docs/*.md` only |
111
112
 
112
113
  #### Lifecycle — batch and parallel
113
114
 
@@ -126,6 +127,7 @@ list this README is checked against.
126
127
  | `dev-handover` | Generate a structured handover document when blocked — captures goal, progress, blocker, rejected approaches, and next steps |
127
128
  | `dev-debug` | Systematic debugging protocol — reproduce, isolate, diagnose root cause, apply minimal fix, and verify with regression tests |
128
129
  | `dev-daily` | Generate a daily summary report from agent usage data, git history, and notes |
130
+ | `dev-history-load` | On-demand cumulative history load + narrowed analyze — import (checkpoint-resume) then analyze, optionally by session/task/window, with optional forensics render |
129
131
  | `dev-dogfood` | Dogfood an agent skill/command/CLI — drive it end-to-end with bounded auto-fix, self-monitor, and emit a comprehensive report |
130
132
  | `dev-find-issue` | Review agent session logs, identify performance bottlenecks and behavioral anti-patterns, and generate a structured task file with proposed fixes |
131
133
  | `dev-find-conflict` | Authority-aware semantic audit across source, task, feature, and project authority files — detect conflicts, resolve claim-specific authority, and route confirmed repairs through owner surfaces |
@@ -135,7 +137,7 @@ list this README is checked against.
135
137
  | `dev-arch` | Survey a codebase (or module tree) for shallow modules and deepening opportunities — emit a ranked MARKDOWN candidate report that feeds the planning half; never auto-refactors |
136
138
  | `dev-reverse` | Reverse-engineer a codebase — analyze unfamiliar repos, generate HLD/architecture docs, audit quality/security, and produce onboarding documentation |
137
139
  | `dev-gitmsg` | Generate conventional commit message(s) from staged changes via per-file summarization, optionally commit |
138
- | `dev-gtd` | Get things done — quality gate (auto-fix) → act CI simulation → conventional commit → push → gh verify in one flow |
140
+ | `dev-gtd` | Get things done — quality gate (auto-fix) → conventional commit → push → gh verify in one flow; optional act CI simulation via `--act` |
139
141
  | `dev-changelog` | Generate changelog from git commits |
140
142
 
141
143
  #### Rule authoring
@@ -313,6 +315,7 @@ surface or run one workflow. All skills target the same five core platforms: `cl
313
315
  | `issue-finding` | 1.1 | Session-log forensics — multi-source discovery, bottleneck ranking, optional topic focus, CLI-gated fix task generation; backs `/sp:dev-find-issue` |
314
316
  | `conflict-finding` | 1.0 | Authority-aware semantic audit — four-pillar (source/task/feature/authority) conflict discovery, claim-specific authority resolution, reproducible evidence, confirmed owner-routed remediation; backs `/sp:dev-find-conflict` |
315
317
  | `next-feature` | 1.0 | Prompt-first feature frontier prioritizer — sync-first precondition, B3 actionability gate (cited, never restated), tiered rubric over measured signals, D1–D4 defect proposals conforming to the restructure map schema; backs `/sp:dev-find-next` |
318
+ | `pr-reviewing` | 1.0 | GitHub Codex PR review — PR prepare/reuse, `@codex review` request with per-HEAD dedupe, bounded polling, findings normalization, validated fix + re-review; spine SSOT `pr-review.yaml` + `scripts/pr-reviewing.ts`; backs `/sp:dev-pr-review` |
316
319
  | `indexed-context` | 1.0 | Cross-agent project context — anatomy/learnings/pitfalls/buglog/memory in `.spur/context/`; hook-tracked token-ledger; graceful degradation on agents without hooks |
317
320
 
318
321
  Each skill directory contains:
@@ -335,11 +338,11 @@ Skills contain zero validation logic — the CLI is the gate.
335
338
 
336
339
  Thin slash-command wrappers that parse user arguments and delegate to the corresponding skill. Each
337
340
  command is a user-facing entry point that bridges natural language to skill invocation. There are
338
- **37 commands** (see the Command index above for the full list), organized by the surface they wrap:
341
+ **39 commands** (see the Command index above for the full list), organized by the surface they wrap:
339
342
 
340
343
  | Prefix | Count | Delegates to | Purpose |
341
344
  | ------------ | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
342
- | `dev-*` | 31 | `sp:spur-dev`, `sp:code-implementation`, `sp:code-testing`, `sp:code-verification`, `sp:code-simplification`, `sp:next-router`, `sp:brainstorm`, `sp:dogfood-testing`, `sp:parallel-execution`, `sp:sys-debugging`, `sp:daily-summary`, `sp:issue-finding`, `sp:conflict-finding`, `sp:reverse-engineering`, inline | The dev-workflow surface — planning, execution, batch, wrap-up, review/verify, hygiene |
345
+ | `dev-*` | 33 | `sp:spur-dev`, `sp:code-implementation`, `sp:code-testing`, `sp:code-verification`, `sp:code-simplification`, `sp:next-router`, `sp:brainstorm`, `sp:dogfood-testing`, `sp:parallel-execution`, `sp:sys-debugging`, `sp:daily-summary`, `sp:issue-finding`, `sp:conflict-finding`, `sp:reverse-engineering`, `sp:pr-reviewing`, inline | The dev-workflow surface — planning, execution, batch, wrap-up, review/verify, hygiene |
343
346
  | `rule-*` | 3 | `sp:spur-cli` | The rule surface — `rule-add`, `rule-refine`, `rule-scan` |
344
347
  | `workflow-*` | 2 | `sp:spur-cli` | The workflow surface — `workflow-add`, `workflow-refine` |
345
348
  | `spur-init` | 1 | `sp:doc-evolve` | Project bootstrap (`spur init`) with doc-evolve integration |
@@ -349,7 +352,7 @@ Each command file contains:
349
352
  - YAML frontmatter (`description`, `argument-hint`, `allowed-tools`).
350
353
  - A delegation block: `Skill(skill="sp:<skill-name>", args="<operation> $ARGUMENTS")`.
351
354
 
352
- **Commands as SSOT (ADR-032).** The 37 `.md` files in `commands/` are the authoritative,
355
+ **Commands as SSOT (ADR-032).** The 39 `.md` files in `commands/` are the authoritative,
353
356
  hand-editable source for the operator command surface. Per-platform adapters are **install-time
354
357
  output** owned by `superskill` (`superskill install sp`) and never committed here. Plugin `sp` ships
355
358
  no per-platform artifacts — only the platform-independent thin wrappers.
@@ -357,7 +360,7 @@ no per-platform artifacts — only the platform-independent thin wrappers.
357
360
  **Thin-wrapper contract** is enforced by `scripts/validate-commands.ts`:
358
361
 
359
362
  ```bash
360
- bun plugins/sp/scripts/validate-commands.ts # validate all 37 commands
363
+ bun plugins/sp/scripts/validate-commands.ts # validate all 39 commands
361
364
  bun plugins/sp/scripts/validate-commands.ts --json # machine-readable output
362
365
  ```
363
366
 
@@ -66,6 +66,7 @@ Invoke `sp:spur-cli` for verb guidance and per-noun conventions:
66
66
 
67
67
  - [ ] Delegate verb guidance to `sp:spur-cli`; use the `spur` CLI for all mutations.
68
68
  - [ ] Run the noun's `check`/`validate` verb before and after editing (e.g. `spur task check <wbs> --json`).
69
+ - [ ] Run the corpus-wide sweep after batch edits: `spur task check --corpus --json` (fails on structural errors outside `config/corpus-baseline.json`).
69
70
  - [ ] Use `spur task update --section --from-file` for all task section edits.
70
71
  - [ ] Run the noun's `refresh` after batch operations where one exists (`spur task refresh`, `spur feature refresh`).
71
72
 
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  description: Survey a codebase (or module tree) for shallow modules and deepening opportunities — emit a ranked MARKDOWN candidate report that feeds the planning half; never auto-refactors
3
+ role: planner
3
4
  argument-hint: "[<module-path>] [--scope <all|path>] [--agent <inline|auto|name>] [--json]"
4
5
  allowed-tools: ["Bash", "Read", "Grep", "Glob", "Skill"]
5
6
  ---
@@ -14,7 +15,7 @@ Wraps the **sp:sys-architecture** skill.
14
15
  | --- | --- | --- |
15
16
  | `[<module-path>]` | Module path to scope the architecture survey. | omitted (whole repo) |
16
17
  | `--scope` `<all\|path>` | Limit the survey to a path or expand to the whole repo. | all |
17
- | `--agent` `<inline\|auto\|name>` | Who runs the model-bearing survey work. | inline |
18
+ | `--agent` `<inline\|auto\|name>` | Who runs the model-bearing survey work. | omit |
18
19
  | `--json` | Emit structured JSON instead of markdown. | off |
19
20
 
20
21
  For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag-glossary.md).
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  description: Interactive solution design — heuristic discovery interview followed by structured ideation with trade-offs and confidence scoring
3
+ role: planner
3
4
  argument-hint: "<topic> [--depth <basic|detailed|comprehensive>] [--options <n>] [--agent <inline|auto|name>] [--skip-discovery] [--wayfind] [--task [<feature-id>]] [--feature [<parent-id>]] [--next]"
4
5
  allowed-tools: ["Bash", "Read", "Skill", "AskUserQuestion"]
5
6
  ---
@@ -15,7 +16,7 @@ Wraps the **sp:brainstorm** and **sp:wayfinder** skills.
15
16
  | `<topic>` | Topic or problem statement to explore. | required |
16
17
  | `--depth` `<basic\|detailed\|comprehensive>` | Breadth vs. depth of the exploration. | detailed |
17
18
  | `--options` `<n>` | Number of solution options to generate. | 3 |
18
- | `--agent` `<inline\|auto\|name>` | Who runs the model-bearing ideation. | inline |
19
+ | `--agent` `<inline\|auto\|name>` | Who runs the model-bearing ideation. | omit |
19
20
  | `--skip-discovery` | Skip the discovery interview; ideate immediately. | off |
20
21
  | `--wayfind` | Spawn a wayfinder feature for multi-session routing. | off |
21
22
  | `--task` `[<feature-id>]` | Create a tracking task under a feature. | omitted |
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  description: Generate changelog from git commits
3
+ role: scribe
3
4
  argument-hint: "[--since <tag|commit>] [--until <tag|commit>] [--version <version>]"
4
5
  allowed-tools: ["Bash", "Read"]
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  description: "Generate a daily summary report from agent usage data, git history, and notes"
3
+ role: scribe
3
4
  argument-hint: "[--date <YYYY-MM-DD>] [--dry-run] [--output <path>] [--no-git] [--no-ccusage]"
4
5
  allowed-tools: ["Bash", "Read"]
5
6
  ---
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  description: "Systematic debugging protocol — reproduce, isolate, diagnose root cause, apply minimal fix, and verify with regression tests"
3
+ role: coder
3
4
  argument-hint: "\"<symptom | failing command>\" [--scope <path>] [--task [<wbs>]] [--agent <inline|auto|name>]"
4
5
  allowed-tools: ["Bash", "Read", "Write", "Skill"]
5
6
  ---
@@ -15,7 +16,7 @@ Wraps the **sp:sys-debugging** skill.
15
16
  | `"<symptom \| failing command>"` | Symptom or failing command to diagnose. | required |
16
17
  | `--scope` `<path>` | Scope the reproduction/isolation to a path. | cwd |
17
18
  | `--task` `[<wbs>]` | Attach findings to a task. | omitted |
18
- | `--agent` `<inline\|auto\|name>` | Who runs the model-bearing diagnosis. | inline |
19
+ | `--agent` `<inline\|auto\|name>` | Who runs the model-bearing diagnosis. | omit |
19
20
 
20
21
  For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag-glossary.md).
21
22