@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.
- package/.claude-plugin/marketplace.json +1 -1
- package/config/corpus-baseline.json +2 -50
- package/config/templates/docs/99_PROJECT_CONSTITUTION.md +21 -16
- package/config/workflow-composition-baseline.json +110 -60
- package/config/workflows/basic.yaml +1 -1
- package/config/workflows/docs-pipeline.yaml +99 -23
- package/config/workflows/feature-dev.yaml +1 -1
- package/config/workflows/idea-pipeline.yaml +21 -23
- package/config/workflows/task-pipeline.yaml +233 -121
- package/config/workflows/wayfinder-resolution.yaml +1 -1
- package/config/workflows/wrapup-pipeline.yaml +1 -1
- package/package.json +9 -9
- package/plugins/sp/README.md +6 -7
- package/plugins/sp/commands/dev-idea.md +5 -3
- package/plugins/sp/commands/dev-plan.md +3 -1
- package/plugins/sp/commands/dev-review-session.md +2 -1
- package/plugins/sp/hooks/context-post-tool.ts +101 -2
- package/plugins/sp/hooks/context-session-start.ts +22 -1
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/scripts/stage-registry-adapter.ts +144 -2
- package/plugins/sp/scripts/surface-drift-inventory.ts +2 -15
- package/plugins/sp/scripts/task-size-precheck.ts +21 -79
- package/plugins/sp/skills/session-review/SKILL.md +16 -0
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +42 -17
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +6 -6
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +80 -11
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +18 -13
- package/spur.js +2062 -609
- package/web/_astro/{BoardApp.BEtcJqde.js → BoardApp.BQFbkeqq.js} +15 -15
- package/web/_astro/BoardApp.CTkqrhWd.js +1 -0
- package/web/_astro/{TaskDetail.ClAbCXom.js → TaskDetail.Dl2Eaj1w.js} +1 -1
- package/web/_astro/{arc.CCvf51_y.js → arc.uG14rp8A.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.C0cb0J5M.js → architectureDiagram-3BPJPVTR.Dye6uD_x.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.CIyjqoCE.js → blockDiagram-GPEHLZMM.B9Pkh7Hb.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.fs14IuFs.js → c4Diagram-AAUBKEIU.C2x7SC_X.js} +1 -1
- package/web/_astro/channel.Dsvulp7W.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.CaBKv4ZO.js → chunk-2J33WTMH.D2p4-nWk.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.BOllTPto.js → chunk-4BX2VUAB.S-6jf33o.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.ChEof0O4.js → chunk-55IACEB6.DVXj4Fdh.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.Co2kdjD8.js → chunk-727SXJPM.Dz689FMN.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.SWmfcnog.js → chunk-AQP2D5EJ.KxYj5TnI.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.rDAFifF3.js → chunk-FMBD7UC4.itTQyHQB.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.BCnoXKCw.js → chunk-ND2GUHAM.euSrbJf5.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.RSmy2hDO.js → chunk-QZHKN3VN.OWASJRQy.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.Be7PEfrX.js → classDiagram-4FO5ZUOK.BLvrlpNO.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.Be7PEfrX.js → classDiagram-v2-Q7XG4LA2.BLvrlpNO.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.BkUp2aSK.js → cose-bilkent-S5V4N54A.XBF-rmyD.js} +1 -1
- package/web/_astro/{cynefin-OW5HDTMX.BegGGlUV.js → cynefin-OW5HDTMX.DlCx762Z.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.BkUdjsaC.js → dagre-BM42HDAG.D17Rshxv.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.E9vugt3-.js → diagram-2AECGRRQ.AhBIVJC8.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.Dj4yeHXB.js → diagram-5GNKFQAL.C9ximjyC.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.Buaquwli.js → diagram-KO2AKTUF.CZb7Ru_9.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.BV3dgGgm.js → diagram-LMA3HP47.BW7LwqoS.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.Cnx3s-tc.js → diagram-OG6HWLK6.XC025W0V.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.DKK_abu4.js → erDiagram-TEJ5UH35.CpMXmBDP.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.BNuu9fbm.js → flowDiagram-I6XJVG4X.D2ednJWg.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.b16KUMjy.js → ganttDiagram-6RSMTGT7.BjL9FGKO.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.Kh41lbG5.js → gitGraphDiagram-PVQCEYII.B90g1VGk.js} +1 -1
- package/web/_astro/{infoDiagram-5YYISTIA.DEWBXkp-.js → infoDiagram-5YYISTIA.RqgycKtQ.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.DiAdmcL6.js → ishikawaDiagram-YF4QCWOH.Ctn-zt6a.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.D1Ki7IRm.js → journeyDiagram-JHISSGLW.DJhT8Ctp.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.CWUhrQpc.js → kanban-definition-UN3LZRKU.BY1QdejI.js} +1 -1
- package/web/_astro/{linear.BaFsgcCe.js → linear.Di7YObSt.js} +1 -1
- package/web/_astro/{mermaid.core.CHw_AsGy.js → mermaid.core.CbxtJS3Q.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.UIhghgmN.js → mindmap-definition-RKZ34NQL.CxvR4g_J.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.D05l3JUA.js → pieDiagram-4H26LBE5.jNWqnBHH.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.BcWIhIcE.js → quadrantDiagram-W4KKPZXB.BCp12MbA.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.B1rYvKGn.js → requirementDiagram-4Y6WPE33.Dxhm4TyR.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.CKylVRC4.js → sankeyDiagram-5OEKKPKP.BtQXp4J9.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.Dm3uA_s4.js → sequenceDiagram-3UESZ5HK.BWEM1R_Q.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.Bgca_BLe.js → stateDiagram-AJRCARHV.BG3wUkWB.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.C1T7YFrG.js → stateDiagram-v2-BHNVJYJU.BLtMeFVP.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.ZOHJn3Sn.js → timeline-definition-PNZ67QCA.D5fHo0az.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.DegZitjD.js → vennDiagram-CIIHVFJN.0DcuMluU.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.BDsC115d.js → wardleyDiagram-YWT4CUSO.BZ-dxgHm.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.D0MO70ea.js → xychartDiagram-2RQKCTM6.Bg-XWF7z.js} +1 -1
- package/web/index.html +1 -1
- package/web/_astro/BoardApp.DBEin4N5.js +0 -1
- 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
|
-
# -
|
|
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: "
|
|
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
|
-
#
|
|
116
|
-
#
|
|
117
|
-
#
|
|
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
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
-
|
|
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
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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:
|
|
259
|
+
description: Measured PASS with the proof bracket intact (R4/R5).
|
|
193
260
|
guard:
|
|
194
261
|
kind: shell
|
|
195
262
|
options:
|
|
196
|
-
|
|
197
|
-
|
|
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:
|
|
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:
|
|
202
|
-
options:
|
|
203
|
-
command: '! $spurBin task check $wbs'
|
|
279
|
+
kind: always
|
|
@@ -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: "
|
|
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
|
-
|
|
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.
|
|
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.
|
|
144
|
-
input:
|
|
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:
|
|
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.
|
|
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.
|
|
247
|
-
input:
|
|
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:
|
|
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:
|
|
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.
|
|
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:
|
|
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)."
|