@gobing-ai/spur 0.3.67 → 0.3.69

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 (79) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/corpus-baseline.json +2 -50
  3. package/config/templates/docs/99_PROJECT_CONSTITUTION.md +21 -16
  4. package/config/workflow-composition-baseline.json +110 -60
  5. package/config/workflows/basic.yaml +1 -1
  6. package/config/workflows/docs-pipeline.yaml +99 -23
  7. package/config/workflows/feature-dev.yaml +1 -1
  8. package/config/workflows/idea-pipeline.yaml +21 -23
  9. package/config/workflows/task-pipeline.yaml +233 -121
  10. package/config/workflows/wayfinder-resolution.yaml +1 -1
  11. package/config/workflows/wrapup-pipeline.yaml +1 -1
  12. package/package.json +9 -9
  13. package/plugins/sp/README.md +6 -7
  14. package/plugins/sp/commands/dev-idea.md +5 -3
  15. package/plugins/sp/commands/dev-plan.md +3 -1
  16. package/plugins/sp/commands/dev-review-session.md +2 -1
  17. package/plugins/sp/hooks/context-post-tool.ts +101 -2
  18. package/plugins/sp/hooks/context-session-start.ts +22 -1
  19. package/plugins/sp/plugin.json +1 -1
  20. package/plugins/sp/scripts/stage-registry-adapter.ts +144 -2
  21. package/plugins/sp/scripts/surface-drift-inventory.ts +2 -15
  22. package/plugins/sp/scripts/task-size-precheck.ts +21 -79
  23. package/plugins/sp/skills/session-review/SKILL.md +16 -0
  24. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +42 -17
  25. package/plugins/sp/skills/spur-dev/references/dev-operations.md +6 -6
  26. package/plugins/sp/skills/spur-dev/references/execution-batch.md +80 -11
  27. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +18 -13
  28. package/spur.js +2062 -609
  29. package/web/_astro/{BoardApp.BEtcJqde.js → BoardApp.BQFbkeqq.js} +15 -15
  30. package/web/_astro/BoardApp.CTkqrhWd.js +1 -0
  31. package/web/_astro/{TaskDetail.ClAbCXom.js → TaskDetail.Dl2Eaj1w.js} +1 -1
  32. package/web/_astro/{arc.CCvf51_y.js → arc.uG14rp8A.js} +1 -1
  33. package/web/_astro/{architectureDiagram-3BPJPVTR.C0cb0J5M.js → architectureDiagram-3BPJPVTR.Dye6uD_x.js} +1 -1
  34. package/web/_astro/{blockDiagram-GPEHLZMM.CIyjqoCE.js → blockDiagram-GPEHLZMM.B9Pkh7Hb.js} +1 -1
  35. package/web/_astro/{c4Diagram-AAUBKEIU.fs14IuFs.js → c4Diagram-AAUBKEIU.C2x7SC_X.js} +1 -1
  36. package/web/_astro/channel.Dsvulp7W.js +1 -0
  37. package/web/_astro/{chunk-2J33WTMH.CaBKv4ZO.js → chunk-2J33WTMH.D2p4-nWk.js} +1 -1
  38. package/web/_astro/{chunk-4BX2VUAB.BOllTPto.js → chunk-4BX2VUAB.S-6jf33o.js} +1 -1
  39. package/web/_astro/{chunk-55IACEB6.ChEof0O4.js → chunk-55IACEB6.DVXj4Fdh.js} +1 -1
  40. package/web/_astro/{chunk-727SXJPM.Co2kdjD8.js → chunk-727SXJPM.Dz689FMN.js} +1 -1
  41. package/web/_astro/{chunk-AQP2D5EJ.SWmfcnog.js → chunk-AQP2D5EJ.KxYj5TnI.js} +1 -1
  42. package/web/_astro/{chunk-FMBD7UC4.rDAFifF3.js → chunk-FMBD7UC4.itTQyHQB.js} +1 -1
  43. package/web/_astro/{chunk-ND2GUHAM.BCnoXKCw.js → chunk-ND2GUHAM.euSrbJf5.js} +1 -1
  44. package/web/_astro/{chunk-QZHKN3VN.RSmy2hDO.js → chunk-QZHKN3VN.OWASJRQy.js} +1 -1
  45. package/web/_astro/{classDiagram-4FO5ZUOK.Be7PEfrX.js → classDiagram-4FO5ZUOK.BLvrlpNO.js} +1 -1
  46. package/web/_astro/{classDiagram-v2-Q7XG4LA2.Be7PEfrX.js → classDiagram-v2-Q7XG4LA2.BLvrlpNO.js} +1 -1
  47. package/web/_astro/{cose-bilkent-S5V4N54A.BkUp2aSK.js → cose-bilkent-S5V4N54A.XBF-rmyD.js} +1 -1
  48. package/web/_astro/{cynefin-OW5HDTMX.BegGGlUV.js → cynefin-OW5HDTMX.DlCx762Z.js} +1 -1
  49. package/web/_astro/{dagre-BM42HDAG.BkUdjsaC.js → dagre-BM42HDAG.D17Rshxv.js} +1 -1
  50. package/web/_astro/{diagram-2AECGRRQ.E9vugt3-.js → diagram-2AECGRRQ.AhBIVJC8.js} +1 -1
  51. package/web/_astro/{diagram-5GNKFQAL.Dj4yeHXB.js → diagram-5GNKFQAL.C9ximjyC.js} +1 -1
  52. package/web/_astro/{diagram-KO2AKTUF.Buaquwli.js → diagram-KO2AKTUF.CZb7Ru_9.js} +1 -1
  53. package/web/_astro/{diagram-LMA3HP47.BV3dgGgm.js → diagram-LMA3HP47.BW7LwqoS.js} +1 -1
  54. package/web/_astro/{diagram-OG6HWLK6.Cnx3s-tc.js → diagram-OG6HWLK6.XC025W0V.js} +1 -1
  55. package/web/_astro/{erDiagram-TEJ5UH35.DKK_abu4.js → erDiagram-TEJ5UH35.CpMXmBDP.js} +1 -1
  56. package/web/_astro/{flowDiagram-I6XJVG4X.BNuu9fbm.js → flowDiagram-I6XJVG4X.D2ednJWg.js} +1 -1
  57. package/web/_astro/{ganttDiagram-6RSMTGT7.b16KUMjy.js → ganttDiagram-6RSMTGT7.BjL9FGKO.js} +1 -1
  58. package/web/_astro/{gitGraphDiagram-PVQCEYII.Kh41lbG5.js → gitGraphDiagram-PVQCEYII.B90g1VGk.js} +1 -1
  59. package/web/_astro/{infoDiagram-5YYISTIA.DEWBXkp-.js → infoDiagram-5YYISTIA.RqgycKtQ.js} +1 -1
  60. package/web/_astro/{ishikawaDiagram-YF4QCWOH.DiAdmcL6.js → ishikawaDiagram-YF4QCWOH.Ctn-zt6a.js} +1 -1
  61. package/web/_astro/{journeyDiagram-JHISSGLW.D1Ki7IRm.js → journeyDiagram-JHISSGLW.DJhT8Ctp.js} +1 -1
  62. package/web/_astro/{kanban-definition-UN3LZRKU.CWUhrQpc.js → kanban-definition-UN3LZRKU.BY1QdejI.js} +1 -1
  63. package/web/_astro/{linear.BaFsgcCe.js → linear.Di7YObSt.js} +1 -1
  64. package/web/_astro/{mermaid.core.CHw_AsGy.js → mermaid.core.CbxtJS3Q.js} +4 -4
  65. package/web/_astro/{mindmap-definition-RKZ34NQL.UIhghgmN.js → mindmap-definition-RKZ34NQL.CxvR4g_J.js} +1 -1
  66. package/web/_astro/{pieDiagram-4H26LBE5.D05l3JUA.js → pieDiagram-4H26LBE5.jNWqnBHH.js} +1 -1
  67. package/web/_astro/{quadrantDiagram-W4KKPZXB.BcWIhIcE.js → quadrantDiagram-W4KKPZXB.BCp12MbA.js} +1 -1
  68. package/web/_astro/{requirementDiagram-4Y6WPE33.B1rYvKGn.js → requirementDiagram-4Y6WPE33.Dxhm4TyR.js} +1 -1
  69. package/web/_astro/{sankeyDiagram-5OEKKPKP.CKylVRC4.js → sankeyDiagram-5OEKKPKP.BtQXp4J9.js} +1 -1
  70. package/web/_astro/{sequenceDiagram-3UESZ5HK.Dm3uA_s4.js → sequenceDiagram-3UESZ5HK.BWEM1R_Q.js} +1 -1
  71. package/web/_astro/{stateDiagram-AJRCARHV.Bgca_BLe.js → stateDiagram-AJRCARHV.BG3wUkWB.js} +1 -1
  72. package/web/_astro/{stateDiagram-v2-BHNVJYJU.C1T7YFrG.js → stateDiagram-v2-BHNVJYJU.BLtMeFVP.js} +1 -1
  73. package/web/_astro/{timeline-definition-PNZ67QCA.ZOHJn3Sn.js → timeline-definition-PNZ67QCA.D5fHo0az.js} +1 -1
  74. package/web/_astro/{vennDiagram-CIIHVFJN.DegZitjD.js → vennDiagram-CIIHVFJN.0DcuMluU.js} +1 -1
  75. package/web/_astro/{wardleyDiagram-YWT4CUSO.BDsC115d.js → wardleyDiagram-YWT4CUSO.BZ-dxgHm.js} +1 -1
  76. package/web/_astro/{xychartDiagram-2RQKCTM6.D0MO70ea.js → xychartDiagram-2RQKCTM6.Bg-XWF7z.js} +1 -1
  77. package/web/index.html +1 -1
  78. package/web/_astro/BoardApp.DBEin4N5.js +0 -1
  79. package/web/_astro/channel.BGn_DUCD.js +0 -1
@@ -10,12 +10,13 @@
10
10
  # /sp:dev-run --mode implement + sp:code-implementation, not YAML prose)
11
11
  # - requireDiff fails silent no-op drafts
12
12
  # - HITL answer routing is exhaustive (yes/no/cancel)
13
- # - record done is fail-closed on `spur task check`
13
+ # - verify measures the deliverable read-only (answer file + `spur task verdict` + proof
14
+ # digest bracket) — record → done is fail-closed on measured PASS, never on a stub
14
15
 
15
16
  "$schema": "@gobing-ai/spur/schemas/state-machine-workflow.schema.json"
16
17
  kind: state-machine
17
18
  name: docs-pipeline
18
- description: "Docs-only execution pipeline (precheck -> draft -> docs-review -> record -> done)"
19
+ description: "Docs-only execution pipeline (precheck -> draft -> docs-review -> record -> verify -> done)"
19
20
  iterationBound: 12
20
21
  initialState: precheck
21
22
  terminalStates:
@@ -29,8 +30,16 @@ vars:
29
30
  wbs: "0000"
30
31
  profile: "standard"
31
32
  spurBin: "spur"
32
- agent: "omp"
33
+ agent: "auto"
33
34
  stepTimeoutMs: "1800000"
35
+ # Proof-state bracket (task 0704, mirroring task-pipeline 0612/0703). `proofDigest` is the
36
+ # canonical capture at verify entry; `proofDigestNow` is the live re-capture compared against
37
+ # it by the `verify → done` guard so verifier-time mutation fails closed (R4/R5).
38
+ proofDigest: ""
39
+ proofDigestNow: ""
40
+ # `taskSpecPath` carries the task file path because `docs/tasks*` is excluded from the digest's
41
+ # git-tree half (task 0704 R4); resolved per-run by the verify state's taskpath shell step.
42
+ taskSpecPath: ""
34
43
  __hitlAnswer: ""
35
44
 
36
45
  states:
@@ -110,27 +119,78 @@ states:
110
119
  command: "$spurBin task record $wbs --solution-from-diff --transition testing"
111
120
 
112
121
  - id: done
113
- description: Terminal — docs deliverable reviewed and recorded.
122
+ description: Terminal — docs deliverable measured, reviewed, and recorded.
114
123
  onEnter:
115
- # Done gate requires a PASS verdict artifact (no silent no-artifact allow).
116
- # Docs-only pipelines do not run /sp:dev-verify; write a docs-only PASS stub
117
- # then transition. Override path remains: --force-done --reason.
124
+ # R1 (0704): no synthetic verdict writer. The verdict artifact is produced by measured
125
+ # verification in `verify` and registered there; done only performs the guarded
126
+ # transition. Override path remains: --force-done --reason.
118
127
  - kind: shell
119
128
  options:
120
- command: >
121
- mkdir -p .spur/run &&
122
- printf '%s\n' "{\"wbs\":\"$wbs\",\"verdict\":\"PASS\",\"source\":\"docs-pipeline\",\"requirements\":[{\"id\":\"docs-deliverable\",\"status\":\"MET\",\"evidence\":\"docs-pipeline record step\"}],\"acceptanceCriteria\":[],\"checks\":[{\"name\":\"docs-only\",\"status\":\"pass\",\"evidence\":\"docs-pipeline\"}]}"
123
- > ".spur/run/$wbs-verdict.json"
129
+ command: "$spurBin task update $wbs done --no-lifecycle"
130
+ - kind: note
131
+ options:
132
+ message: "Docs pipeline complete for task ${vars.wbs}."
133
+ - id: verify
134
+ description: >
135
+ Read-only measured verification (task 0704, R2/R4/R7): dispatch /sp:dev-verify --fix none
136
+ with an answer file, derive the ONE standard verdict via `spur task verdict`, register the
137
+ standard verify-verdict artifact, and bracket the verifier with proof-input digest capture/compare so any
138
+ task-spec or document mutation during certification fails closed (R4). No docs assurance
139
+ subclass — PASS semantics are identical to task-pipeline (R7).
140
+ onEnter:
141
+ # R4 (0703 R6 precedent): resolve the task-spec path BEFORE capture. `docs/tasks*` is
142
+ # excluded from the digest's git-tree half, so the spec is folded in via `taskFile`.
143
+ - kind: shell
144
+ options:
145
+ command: '$spurBin task path $wbs --json 2>/dev/null | jq -r ".path // .filePath // empty" > ".spur/run/$wbs-docs-taskpath.txt" || true; exit 0'
146
+ - kind: file.read.into-var
147
+ options:
148
+ path: .spur/run/${vars.wbs}-docs-taskpath.txt
149
+ var: taskSpecPath
150
+ # R4: canonical capture BEFORE the verifier runs. Same fingerprint input as the
151
+ # re-capture below so the bracket compares like for like.
152
+ - kind: proof.fingerprint
153
+ options:
154
+ var: proofDigest
155
+ taskFile: ${vars.taskSpecPath}
156
+ input: /sp:dev-verify ${vars.wbs} --auto --fix none --focus all
157
+ timeoutMs: ${vars.stepTimeoutMs}
158
+ - kind: agent.run
159
+ options:
160
+ agent: ${vars.agent}
161
+ # Observe-only (ADR-071 precedent): the verifier certifies, it never repairs.
162
+ # 0710 R2: verify runs in a fresh session — never inherits the implement hop's session.
163
+ freshSession: true
164
+ input: /sp:dev-verify ${vars.wbs} --auto --fix none --focus all
165
+ role: reviewer
166
+ timeoutMs: ${vars.stepTimeoutMs}
167
+ answerFile: .spur/run/${vars.wbs}-verify-answer.txt
168
+ - kind: shell
169
+ options:
170
+ command: "$spurBin task verdict $wbs --from-answer .spur/run/$wbs-verify-answer.txt"
171
+ # R7: stamp the proof block into the standard verdict artifact, then register it.
172
+ # Soft action + hard guard: a missing/malformed stamp fails the `verify -> done`
173
+ # guard below, not this step.
174
+ - kind: shell
175
+ options:
176
+ command: >-
177
+ V=".spur/run/$wbs-verdict.json";
178
+ if [ -f "$V" ] && [ -n "$proofDigest" ]; then
179
+ jq --arg d "$proofDigest" '. + {proof: {digest: $d, capturePoint: "docs-verify-entry"}}' "$V" > "$V.tmp" && mv "$V.tmp" "$V";
180
+ fi;
181
+ exit 0
124
182
  - kind: run.artifact
125
183
  options:
126
184
  path: .spur/run/${vars.wbs}-verdict.json
127
185
  artifactKind: verify-verdict
128
- - kind: shell
186
+ # R4: re-capture AFTER the verifier. No `expect` here — an action-level abort would
187
+ # bypass the `failed` state; the `verify -> done` guard compares instead (R5).
188
+ - kind: proof.fingerprint
129
189
  options:
130
- command: "$spurBin task update $wbs done --no-lifecycle"
131
- - kind: note
132
- options:
133
- message: "Docs pipeline complete for task ${vars.wbs}."
190
+ var: proofDigestNow
191
+ taskFile: ${vars.taskSpecPath}
192
+ input: /sp:dev-verify ${vars.wbs} --auto --fix none --focus all
193
+ timeoutMs: ${vars.stepTimeoutMs}
134
194
 
135
195
  - id: failed
136
196
  description: Terminal — docs pipeline failed or was rejected.
@@ -188,16 +248,32 @@ transitions:
188
248
  command: 'test "$__hitlAnswer" = cancel'
189
249
 
190
250
  - from: record
251
+ to: verify
252
+ description: Recorded — measure the deliverable (R2). Structural task-check gates remain
253
+ at precheck, record (wip→testing), and done (verdict-artifact guard, R3).
254
+ guard:
255
+ kind: always
256
+
257
+ - from: verify
191
258
  to: done
192
- description: Task check passed certify done.
259
+ description: Measured PASS with the proof bracket intact (R4/R5).
193
260
  guard:
194
261
  kind: shell
195
262
  options:
196
- command: "$spurBin task check $wbs"
197
- - from: record
263
+ # Hardened (0703 P2 carry): every operand is required non-empty (`test -n`) so a
264
+ # missing file or empty var fails closed instead of empty-equals-empty passing.
265
+ command: >-
266
+ test -n "$proofDigest" &&
267
+ test -n "$proofDigestNow" &&
268
+ test "$proofDigestNow" = "$proofDigest" &&
269
+ test -f ".spur/run/$wbs-verdict.json" &&
270
+ test -n "$(jq -r '.verdict // empty' .spur/run/$wbs-verdict.json 2>/dev/null)" &&
271
+ test "$(jq -r '.verdict // empty' .spur/run/$wbs-verdict.json 2>/dev/null)" = PASS &&
272
+ test -n "$(jq -r '.proof.digest // empty' .spur/run/$wbs-verdict.json 2>/dev/null)" &&
273
+ test "$(jq -r '.proof.digest // empty' .spur/run/$wbs-verdict.json 2>/dev/null)" = "$proofDigest"
274
+ - from: verify
198
275
  to: failed
199
- description: Task check failedblock before done.
276
+ description: Non-PASS verdict, missing/malformed answer, or digest mismatch (R5) the run
277
+ reaches failed and no PASS artifact is certified.
200
278
  guard:
201
- kind: shell
202
- options:
203
- command: '! $spurBin task check $wbs'
279
+ kind: always
@@ -44,7 +44,7 @@ failureStates:
44
44
  - failed
45
45
  vars:
46
46
  featureId: ""
47
- agent: "omp"
47
+ agent: "auto"
48
48
  profile: "standard"
49
49
  spurBin: "spur"
50
50
  stepTimeoutMs: "1800000"
@@ -65,7 +65,8 @@ vars:
65
65
  spurBin: "spur"
66
66
  # R8 (0366): injected by WorkflowAppService.run(); stamps discovery artifact provenance.
67
67
  __runId: ""
68
- agent: "omp"
68
+ agent: "auto"
69
+ planningAgent: ""
69
70
  stepTimeoutMs: "1800000"
70
71
 
71
72
  states:
@@ -78,20 +79,17 @@ states:
78
79
  - kind: note
79
80
  options:
80
81
  message: "Idea pipeline start for idea: ${vars.idea}"
82
+ - kind: doctor.probe
83
+ options:
84
+ resultFile: ".spur/run/${vars.__runId}-idea-precheck-doctor.status"
85
+ spurBin: "${vars.spurBin}"
86
+ agent: "${vars.agent}"
87
+ role: planner
88
+ resolvedAgentVar: planningAgent
81
89
  - kind: shell
82
90
  options:
83
91
  command: >-
84
- mkdir -p .spur/run &&
85
- DOCTOR_FILE=".spur/run/$__runId-idea-precheck-doctor.status" &&
86
- set +e &&
87
- $spurBin agent doctor $agent; doctor_rc=$?;
88
- set -e &&
89
- if [ "$doctor_rc" -eq 0 ] && test -n "$idea"; then
90
- printf 'PASS\n' > "$DOCTOR_FILE";
91
- else
92
- printf 'FAIL\n' > "$DOCTOR_FILE";
93
- fi &&
94
- exit 0
92
+ test -n "$idea" || printf 'FAIL\n' > ".spur/run/$__runId-idea-precheck-doctor.status"
95
93
 
96
94
  - id: discovery
97
95
  description: >
@@ -106,7 +104,7 @@ states:
106
104
  onEnter:
107
105
  - kind: agent.run
108
106
  options:
109
- agent: ${vars.agent}
107
+ agent: ${vars.planningAgent}
110
108
  input: "Run sp:brainstorm for the idea: ${vars.idea}. The skill owns the approach-generation, design summary, and `needs_design` signal criteria; emit .spur/run/${vars.__runId}-idea-needs-design.json ({\"needs_design\": true|false}) and the design summary per the skill's `Design Approval Gate` and `The needs_design signal` sections. Also emit the idea-evaluation report to .spur/run/${vars.__runId}-idea-eval-report.md per plugins/sp/skills/spur-dev/references/idea-evaluation.md (urgency/necessity 0–5, premises, pros/cons, alternatives, enhanced idea, recommendation). At the END of the report, append a provenance footer block of the exact form: `---\\nrun_id: ${vars.__runId}\\ngenerated_at: <RFC3339 timestamp>\\n---` (omit the footer only if run_id is empty)."
111
109
  # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
112
110
  role: planner
@@ -140,8 +138,8 @@ states:
140
138
  onEnter:
141
139
  - kind: agent.run
142
140
  options:
143
- agent: ${vars.agent}
144
- input: "Create a feature for the idea: ${vars.idea}. Read .spur/run/${vars.__runId}-idea-eval-report.md if present for the enhanced idea and scores. Use 'spur feature create \"<name>\" --json' to create it. Write the feature id to .spur/run/${vars.__runId}-idea-feature-id.txt. If an existing feature is appropriate, use its id instead. Also write two body-only intent artifacts: .spur/run/${vars.__runId}-idea-goal.md with concise Goal intent only (a short statement of what the feature achieves; never task breakdowns, checklists, or how-to steps), and .spur/run/${vars.__runId}-idea-scope.md with explicit in-scope and out-of-scope boundary bullets."
141
+ agent: ${vars.planningAgent}
142
+ input: 'Create a feature for the idea: ${vars.idea}. Read .spur/run/${vars.__runId}-idea-eval-report.md if present for the enhanced idea and scores. Use ''spur feature create "<name>" --json'' to create it. Write the feature id to .spur/run/${vars.__runId}-idea-feature-id.txt. If an existing feature is appropriate, use its id instead. Also write two body-only intent artifacts: .spur/run/${vars.__runId}-idea-goal.md with concise Goal intent only (a short statement of what the feature achieves; never task breakdowns, checklists, or how-to steps), and .spur/run/${vars.__runId}-idea-scope.md with explicit in-scope and out-of-scope boundary bullets.'
145
143
  # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
146
144
  role: planner
147
145
  expectFile: .spur/run/${vars.__runId}-idea-feature-id.txt
@@ -178,10 +176,10 @@ states:
178
176
  onEnter:
179
177
  - kind: shell
180
178
  options:
181
- command: 'mkdir -p .spur/run && count=$(cat .spur/run/$__runId-idea-ac-retry-count 2>/dev/null || echo 0); echo $((count + 1)) > .spur/run/$__runId-idea-ac-retry-count; rm -f .spur/run/$__runId-idea-ac-content.md .spur/run/$__runId-idea-ac-done.txt'
179
+ command: "mkdir -p .spur/run && count=$(cat .spur/run/$__runId-idea-ac-retry-count 2>/dev/null || echo 0); echo $((count + 1)) > .spur/run/$__runId-idea-ac-retry-count; rm -f .spur/run/$__runId-idea-ac-content.md .spur/run/$__runId-idea-ac-done.txt"
182
180
  - kind: agent.run
183
181
  options:
184
- agent: ${vars.agent}
182
+ agent: ${vars.planningAgent}
185
183
  input: "Generate acceptance criteria for feature ${vars.featureId}. Read the feature file and author R-numbered BDD Gherkin scenarios per ac-style-guide.md. Output only the complete Acceptance Criteria section body, including the gherkin code fence, with no surrounding commentary and no section heading."
186
184
  # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
187
185
  role: planner
@@ -243,8 +241,8 @@ states:
243
241
  test -f "$REVIEW" || printf '## Proposed design\n\n## Operator feedback\n\n## Reconciliation\n' > "$REVIEW"
244
242
  - kind: agent.run
245
243
  options:
246
- agent: ${vars.agent}
247
- input: "Run sp:sys-architecture for feature ${vars.featureId}. Read the brainstorm artifact, feature AC, and .spur/run/${vars.__runId}-idea-design-review.md. Produce ADR entries, architecture updates, and design satellites (docs/design/<slug>.md) following the constitution edit rules. Do not write task or feature corpus files directly. Design-review contract (.spur/run/${vars.__runId}-idea-design-review.md, fixed headings `## Proposed design`, `## Operator feedback`, `## Reconciliation`): on the first pass write the proposed design summary under `## Proposed design` and leave `## Operator feedback` empty; on retry with operator feedback present, revise the design/ADR artifacts, document the changes under `## Reconciliation`, and when the feedback invalidates an Acceptance Criteria scenario write the revised AC section body to a file and persist it via `$spurBin feature update \"$featureId\" --section \"Acceptance Criteria\" --from-file <file>` — never edit feature corpus files directly."
244
+ agent: ${vars.planningAgent}
245
+ input: 'Run sp:sys-architecture for feature ${vars.featureId}. Read the brainstorm artifact, feature AC, and .spur/run/${vars.__runId}-idea-design-review.md. Produce ADR entries, architecture updates, and design satellites (docs/design/<slug>.md) following the constitution edit rules. Do not write task or feature corpus files directly. Design-review contract (.spur/run/${vars.__runId}-idea-design-review.md, fixed headings `## Proposed design`, `## Operator feedback`, `## Reconciliation`): on the first pass write the proposed design summary under `## Proposed design` and leave `## Operator feedback` empty; on retry with operator feedback present, revise the design/ADR artifacts, document the changes under `## Reconciliation`, and when the feedback invalidates an Acceptance Criteria scenario write the revised AC section body to a file and persist it via `$spurBin feature update "$featureId" --section "Acceptance Criteria" --from-file <file>` — never edit feature corpus files directly.'
248
246
  # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
249
247
  role: planner
250
248
  expectFile: .spur/run/${vars.__runId}-idea-design-review.md
@@ -279,7 +277,7 @@ states:
279
277
  onEnter:
280
278
  - kind: shell
281
279
  options:
282
- command: 'mkdir -p .spur/run && count=$(cat .spur/run/$__runId-idea-design-reject-count 2>/dev/null || echo 0); echo $((count + 1)) > .spur/run/$__runId-idea-design-reject-count'
280
+ command: "mkdir -p .spur/run && count=$(cat .spur/run/$__runId-idea-design-reject-count 2>/dev/null || echo 0); echo $((count + 1)) > .spur/run/$__runId-idea-design-reject-count"
283
281
  - kind: hitl.confirm
284
282
  options:
285
283
  prompt: "Review the system design for feature ${vars.featureId}. Approve to proceed to decomposition? To reject, first record your feedback in .spur/run/${vars.__runId}-idea-design-review.md under the `## Operator feedback` heading, then answer no."
@@ -296,10 +294,10 @@ states:
296
294
  onEnter:
297
295
  - kind: shell
298
296
  options:
299
- command: 'mkdir -p .spur/run && count=$(cat .spur/run/$__runId-idea-decompose-retry-count 2>/dev/null || echo 0); echo $((count + 1)) > .spur/run/$__runId-idea-decompose-retry-count; rm -f .spur/run/$__runId-idea-task-batch.json .spur/run/$__runId-idea-task-order.json .spur/run/$__runId-idea-batch-create.done .spur/run/$__runId-idea-batch-create.failed .spur/run/$__runId-idea-batch-create-result.json .spur/run/$__runId-idea-handoff.md'
297
+ command: "mkdir -p .spur/run && count=$(cat .spur/run/$__runId-idea-decompose-retry-count 2>/dev/null || echo 0); echo $((count + 1)) > .spur/run/$__runId-idea-decompose-retry-count; rm -f .spur/run/$__runId-idea-task-batch.json .spur/run/$__runId-idea-task-order.json .spur/run/$__runId-idea-batch-create.done .spur/run/$__runId-idea-batch-create.failed .spur/run/$__runId-idea-batch-create-result.json .spur/run/$__runId-idea-handoff.md"
300
298
  - kind: agent.run
301
299
  options:
302
- agent: ${vars.agent}
300
+ agent: ${vars.planningAgent}
303
301
  input: "Run sp:spec-decomposition for feature ${vars.featureId}. Read the brainstorm artifact, feature AC, and design doc. SIZING FIRST, before any JSON: apply the skill's `Default to NOT decomposing` rubric to the whole unit of work — if it scores 0-2 the correct output is a ONE-entry batch, not many. Scenario count is not task count: merge scenarios that one task delivers (same file surface, same subsystem, or unreadable apart in review), and list every scenario a task covers in its background. Merging never costs AC coverage — one task may carry several scenarios. Do not emit one entry per scenario or per requirement by reflex. Then produce a task-batch JSON array at .spur/run/${vars.__runId}-idea-task-batch.json, validated against apps/cli/schemas/task-batch.schema.json. Schema-permitted fields per entry: `name`, `background`, `requirements`, `feature_id`, `parent_wbs`, `priority`, `tags`, `template` — schema validation rejects anything else. Acceptance Criteria, Design, and Plan sections are filled in by the per-task refine step after batch-create, NOT at decompose time. Validate locally against the schema before emitting. Also emit the private task-order sidecar at .spur/run/${vars.__runId}-idea-task-order.json: a JSON array (one entry per batch item) of `{ name: <exact batch item name>, depends_on_names: [<batch item names>] }` declaring ordering/dependencies between the batch items; use `[]` when no ordering exists. Every `name` and every dependency must match exactly one batch item `name` — it is private workflow data, not part of task-batch.schema.json."
304
302
  # Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
305
303
  role: planner
@@ -723,7 +721,7 @@ transitions:
723
721
  guard:
724
722
  kind: shell
725
723
  options:
726
- command: 'test -f .spur/run/$__runId-idea-batch-create.done'
724
+ command: "test -f .spur/run/$__runId-idea-batch-create.done"
727
725
  - from: batch-create-run
728
726
  to: decompose
729
727
  description: "Batch-create failed — revise decomposition (retry cap: 3)."