@gobing-ai/spur 0.3.67 → 0.3.68
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 +109 -59
- package/config/workflows/docs-pipeline.yaml +98 -22
- package/config/workflows/idea-pipeline.yaml +20 -22
- package/config/workflows/task-pipeline.yaml +207 -108
- 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/skills/session-review/SKILL.md +16 -0
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +40 -16
- 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 +2069 -597
- 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
|
@@ -78,15 +78,25 @@ vars:
|
|
|
78
78
|
# Answer captured by the approve gate's hitl.confirm (R1): "yes" | "no" | "cancel".
|
|
79
79
|
# Empty by default; only meaningful once the approve state has been entered.
|
|
80
80
|
__hitlAnswer: ""
|
|
81
|
-
# Proof-state bracket (task 0612, ADR-071). `proofDigest` is
|
|
82
|
-
#
|
|
83
|
-
#
|
|
84
|
-
# the
|
|
85
|
-
# the
|
|
86
|
-
#
|
|
81
|
+
# Proof-state bracket (task 0612, ADR-071; restructured by task 0703). `proofDigest` is the
|
|
82
|
+
# canonical capture taken at quality-gate ENTRY — immediately before the evidence-producing
|
|
83
|
+
# final chain (quality → review → verify) — and re-captured at `test-recheck` when bounded
|
|
84
|
+
# remediation mutated the tree, so every evidence stage names one fresh digest (R2/R4).
|
|
85
|
+
# `proofDigestNow` is the live re-capture compared against `proofDigest` at verify entry and
|
|
86
|
+
# immediately before `record`; a mismatch means a proof input changed after evidence was
|
|
87
|
+
# established, so the run routes to `failed` instead of crossing the completion boundary (R5).
|
|
88
|
+
# `taskSpecPath` carries the task file path because `docs/tasks*` is excluded from the digest's
|
|
89
|
+
# git-tree half — spec content is folded in explicitly or a task-file edit would go undetected.
|
|
90
|
+
# The fingerprint scopes task content to the proof-input sections only (Background, Requirements,
|
|
91
|
+
# Acceptance Criteria, Design, Plan), so record-time Solution/Testing/Review evidence writes do
|
|
92
|
+
# not retroactively invalidate the certified input set (R6).
|
|
87
93
|
proofDigest: ""
|
|
88
94
|
proofDigestNow: ""
|
|
89
95
|
taskSpecPath: ""
|
|
96
|
+
# 0710 R4: task priority tier (P0..P4) extracted from the task frontmatter at the
|
|
97
|
+
# quality-gate stage. P0/P1 make the review/verify distinct-executor policy apply;
|
|
98
|
+
# unknown/empty priority means fresh-context-only (executor reuse allowed).
|
|
99
|
+
taskPriority: ""
|
|
90
100
|
# Project quality gate for the `test` hop (probe + fixall + recheck). Override per project
|
|
91
101
|
# with the same package-manager surface (this monorepo is Bun-only):
|
|
92
102
|
# `--vars '{"qualityGateCmd":"bun run lint && bun run test"}'`. Soft probe, hard recheck,
|
|
@@ -114,11 +124,11 @@ vars:
|
|
|
114
124
|
# file:line instead of re-deriving it from a fresh gate run (0482 R3).
|
|
115
125
|
gateFindings: ""
|
|
116
126
|
# Max R-items in ## Requirements before size precheck fails (R2, task 0454).
|
|
117
|
-
# Override with `--vars '{"maxImplementReqs":"
|
|
118
|
-
maxImplementReqs: "
|
|
127
|
+
# Override with `--vars '{"maxImplementReqs":"20"}'`.
|
|
128
|
+
maxImplementReqs: "10"
|
|
119
129
|
# Max checklist items under ## Plan before size precheck fails (R2, task 0454).
|
|
120
|
-
# Override with `--vars '{"maxImplementPlanItems":"
|
|
121
|
-
maxImplementPlanItems: "
|
|
130
|
+
# Override with `--vars '{"maxImplementPlanItems":"32"}'`.
|
|
131
|
+
maxImplementPlanItems: "16"
|
|
122
132
|
# Diff-scope guard on the implement hop (R1, task 0487). When the target task
|
|
123
133
|
# body backticks at least one path, non-corpus changes outside those paths
|
|
124
134
|
# fail the step by name. New files beside a declared file are allowed. Empty
|
|
@@ -129,37 +139,9 @@ vars:
|
|
|
129
139
|
states:
|
|
130
140
|
- id: precheck
|
|
131
141
|
description: >
|
|
132
|
-
|
|
133
|
-
`
|
|
134
|
-
(not a raw lifecycle abort mid-enter).
|
|
142
|
+
Fast deterministic task readiness and size checks. Failures route to the
|
|
143
|
+
`failed` terminal state (not a raw lifecycle abort mid-enter).
|
|
135
144
|
onEnter:
|
|
136
|
-
# Pre-launch executor doctor probe (task 0608 / D6 R4–R5). The auth classifier —
|
|
137
|
-
# per-agent-family classification (omp/pi env-key misses soft, explicit auth
|
|
138
|
-
# failures hard) plus the executor-divergence line — now lives in the
|
|
139
|
-
# `doctor.probe` built-in action kind (`packages/app/src/workflow/actions/doctor-probe.ts`)
|
|
140
|
-
# instead of this shell program; that is the ownership-surface landing for the
|
|
141
|
-
# task-pipeline precheck doctor probe (option c, least-privilege built-in).
|
|
142
|
-
#
|
|
143
|
-
# Semantics preserved from the replaced shell (behavior parity is covered by
|
|
144
|
-
# `packages/app/tests/workflow/actions/doctor-probe.test.ts`):
|
|
145
|
-
# R2 (0487): probe BOTH resolved executors ($agent and $implementAgent) and
|
|
146
|
-
# FAIL on `authenticated: unauthenticated`. Previously only $agent was probed
|
|
147
|
-
# and auth was informational, so a run whose implement executor had no
|
|
148
|
-
# provider key sailed through precheck into a guaranteed implement failure
|
|
149
|
-
# (runs e8cb00e7 / b16bfbf4). `unknown` auth keeps the old soft behavior —
|
|
150
|
-
# some agents expose no auth-status verb. `spur agent doctor` CLI exit-code
|
|
151
|
-
# semantics are deliberately untouched; the gate lives here.
|
|
152
|
-
# R4 (0487): one divergence line when the two executors differ.
|
|
153
|
-
# R2 (0503): omp/pi env-key probe misses are soft because the CLI process
|
|
154
|
-
# cannot see relay-owned credentials; explicit non-omp auth failures remain hard.
|
|
155
|
-
# Soft probe: writes PASS/FAIL to the status file and always succeeds so the
|
|
156
|
-
# transition guards below route on the token (never a raw lifecycle abort).
|
|
157
|
-
- kind: doctor.probe
|
|
158
|
-
options:
|
|
159
|
-
resultFile: ".spur/run/${vars.wbs}-precheck-doctor.status"
|
|
160
|
-
spurBin: "${vars.spurBin}"
|
|
161
|
-
agent: "${vars.agent}"
|
|
162
|
-
implementAgent: "${vars.implementAgent}"
|
|
163
145
|
# R6 (0487): pre-launch hygiene WARNING (never a block) — starting a task on
|
|
164
146
|
# a tree already dirty with another task's implementation is how 0485's diff
|
|
165
147
|
# got swept into 0486's run. Corpus dirs are excluded: the pipeline writes
|
|
@@ -207,9 +189,9 @@ states:
|
|
|
207
189
|
# R2 (0454): task size precheck — evaluate R-item and Plan-item counts.
|
|
208
190
|
# Writes PASS/FAIL to .spur/run/<wbs>-precheck-size.status. Always exit 0
|
|
209
191
|
# (soft check, like doctor). The precheck→implement guard reads the file.
|
|
210
|
-
#
|
|
211
|
-
#
|
|
212
|
-
#
|
|
192
|
+
# Temporary config-only bypass (0723): keep deterministic size limits but defer
|
|
193
|
+
# the executor-tier policy to the dedicated task-pipeline upgrade. This avoids
|
|
194
|
+
# the script's second `spur agent doctor` call while the precheck path is repaired.
|
|
213
195
|
- kind: shell
|
|
214
196
|
options:
|
|
215
197
|
command: >-
|
|
@@ -217,8 +199,7 @@ states:
|
|
|
217
199
|
mkdir -p .spur/run &&
|
|
218
200
|
if [ -f plugins/sp/scripts/task-size-precheck.ts ]; then
|
|
219
201
|
bun plugins/sp/scripts/task-size-precheck.ts "$wbs"
|
|
220
|
-
--spur-bin "$spurBin" --max-reqs "$maxImplementReqs" --max-plan-items "$maxImplementPlanItems"
|
|
221
|
-
--executor "$implementAgent";
|
|
202
|
+
--spur-bin "$spurBin" --max-reqs "$maxImplementReqs" --max-plan-items "$maxImplementPlanItems";
|
|
222
203
|
else
|
|
223
204
|
echo "task-size-precheck skipped — plugins/sp/scripts/task-size-precheck.ts not present in project." >&2 &&
|
|
224
205
|
echo "PASS" > "$SIZE_FILE";
|
|
@@ -243,7 +224,7 @@ states:
|
|
|
243
224
|
options:
|
|
244
225
|
agent: ${vars.implementAgent}
|
|
245
226
|
# Pure slash command only (ADR-043). Anti-recursion / implement discipline
|
|
246
|
-
# Declared Layer-1 role (0538 R2): routing reason
|
|
227
|
+
# Declared Layer-1 role (0538 R2/0710 R7): routing reason; no executor pin — role routing feeds the distinctness gate.
|
|
247
228
|
role: coder
|
|
248
229
|
# lives in /sp:dev-run --mode implement → sp:code-implementation, not YAML prose.
|
|
249
230
|
input: /sp:dev-run --mode implement ${vars.wbs} --auto
|
|
@@ -253,6 +234,14 @@ states:
|
|
|
253
234
|
# a silent no-op routes the run to `failed` here instead of drifting
|
|
254
235
|
# into test/review and being caught a full pass later.
|
|
255
236
|
requireDiff: true
|
|
237
|
+
# 0706 R6: this stage mutates the working tree unattended under the
|
|
238
|
+
# auto profile, so it declares minimum execution-capability
|
|
239
|
+
# requirements. Dispatch fails closed (before spawn) when the
|
|
240
|
+
# resolved executor's attestation cannot satisfy them — attest the
|
|
241
|
+
# executor in agent config.
|
|
242
|
+
requiresCapabilities:
|
|
243
|
+
fsWrite: available
|
|
244
|
+
processSpawn: available
|
|
256
245
|
- kind: shell
|
|
257
246
|
options:
|
|
258
247
|
command: >-
|
|
@@ -296,11 +285,37 @@ states:
|
|
|
296
285
|
# test-recheck — soft recheck → review | test-fix | failed (never silent lifecycle abort)
|
|
297
286
|
- id: test
|
|
298
287
|
description: >
|
|
299
|
-
|
|
300
|
-
for SQLite lock contention).
|
|
288
|
+
Proof-chain entry + soft quality-gate probe (single logical gate on the green path; bounded retries only
|
|
289
|
+
for SQLite lock contention). Capture of the canonical proof-input digest happens HERE — before any
|
|
290
|
+
evidence-producing final check (task 0703, ADR-071) — so the gate, review, and verification evidence
|
|
291
|
+
all name one digest. Then runs
|
|
301
292
|
`${vars.qualityGateCmd}`, records PASS|FAIL under
|
|
302
293
|
`.spur/run/<wbs>-test-gate.status`, resets the fix attempt counter, always exit 0.
|
|
303
294
|
onEnter:
|
|
295
|
+
# R6/R2 (0703): resolve the task-spec path BEFORE the digest capture. `docs/tasks*` is excluded
|
|
296
|
+
# from the digest's git-tree half, so the spec is folded in explicitly via `taskSpecPath`.
|
|
297
|
+
- kind: shell
|
|
298
|
+
options:
|
|
299
|
+
# 0710 R4: resolve the spec path, then extract `priority:` from the TASK FILE itself (not the
|
|
300
|
+
# path listing); normalize to upper so requiresDistinctExecutor's exact 'P0'/'P1' match hits.
|
|
301
|
+
# Missing spec/line -> empty var -> back-compat (no distinctness requirement).
|
|
302
|
+
command: '$spurBin task path $wbs --json 2>/dev/null | jq -r ".path // .filePath // empty" > ".spur/run/$wbs-taskpath.txt" || true; sed -n "s/^priority:[[:space:]]*//p" "$(cat ".spur/run/$wbs-taskpath.txt" 2>/dev/null)" 2>/dev/null | head -1 | tr -d "[:space:]" | tr "[:lower:]" "[:upper:]" > ".spur/run/$wbs-priority.txt"; exit 0'
|
|
303
|
+
- kind: file.read.into-var
|
|
304
|
+
options:
|
|
305
|
+
path: .spur/run/${vars.wbs}-taskpath.txt
|
|
306
|
+
var: taskSpecPath
|
|
307
|
+
# 0710 R4: carry the task's priority tier into the review/verify risk policy.
|
|
308
|
+
- kind: file.read.into-var
|
|
309
|
+
options:
|
|
310
|
+
path: .spur/run/${vars.wbs}-priority.txt
|
|
311
|
+
var: taskPriority
|
|
312
|
+
# R2 (0703, ADR-071): THE canonical proof capture. Placement is load-bearing: immediately before
|
|
313
|
+
# the final evidence chain, after every implement mutation (including the post-implement format).
|
|
314
|
+
# Capture-only here; `record` compares. A remediation pass re-captures at `test-recheck` (R4).
|
|
315
|
+
- kind: proof.fingerprint
|
|
316
|
+
options:
|
|
317
|
+
var: proofDigest
|
|
318
|
+
taskFile: ${vars.taskSpecPath}
|
|
304
319
|
- kind: shell
|
|
305
320
|
options:
|
|
306
321
|
command: >-
|
|
@@ -331,13 +346,17 @@ states:
|
|
|
331
346
|
else
|
|
332
347
|
printf 'FAIL\n' > "$STATUS_FILE";
|
|
333
348
|
fi &&
|
|
349
|
+
printf 'proof-digest: %s\n' "$proofDigest" >> "$LOG_FILE" &&
|
|
334
350
|
exit 0
|
|
335
351
|
|
|
336
352
|
- id: test-fix
|
|
337
353
|
description: >
|
|
338
|
-
Bounded auto-fix hop when the quality gate is red
|
|
339
|
-
|
|
340
|
-
|
|
354
|
+
Bounded auto-fix hop when the quality gate is red OR final verification returned a
|
|
355
|
+
repairable non-PASS (task 0703 R4: remediation never happens inside verify — it loops
|
|
356
|
+
through here, then re-enters quality → review → verify on a fresh digest). Increments
|
|
357
|
+
`.spur/run/<wbs>-test-fix-attempt` (the shared bound with the quality path), projects the
|
|
358
|
+
verify verdict into the gate log when one exists so the repair hop sees it, then pure
|
|
359
|
+
slash (ADR-043) `/sp:dev-fixall` against `${vars.qualityGateCmd}`.
|
|
341
360
|
onEnter:
|
|
342
361
|
- kind: shell
|
|
343
362
|
options:
|
|
@@ -345,7 +364,13 @@ states:
|
|
|
345
364
|
mkdir -p .spur/run &&
|
|
346
365
|
ATTEMPT_FILE=".spur/run/$wbs-test-fix-attempt" &&
|
|
347
366
|
n=$(cat "$ATTEMPT_FILE" 2>/dev/null || echo 0) &&
|
|
348
|
-
printf '%s\n' "$((n + 1))" > "$ATTEMPT_FILE"
|
|
367
|
+
printf '%s\n' "$((n + 1))" > "$ATTEMPT_FILE" &&
|
|
368
|
+
if [ -f ".spur/run/$wbs-verdict.json" ]; then
|
|
369
|
+
{ echo '--- verify verdict (remediation input, task 0703 R4) ---';
|
|
370
|
+
cat ".spur/run/$wbs-verdict.json";
|
|
371
|
+
} >> ".spur/run/$wbs-test-gate.log";
|
|
372
|
+
fi;
|
|
373
|
+
exit 0
|
|
349
374
|
# R3 (0482): project the extracted gate anchors into a var so the dispatch input
|
|
350
375
|
# can NAME the failing file:line, not merely point at a log. A vars template cannot
|
|
351
376
|
# run a shell, so the read is an action, not an inline `$(cat ...)` substitution.
|
|
@@ -357,11 +382,16 @@ states:
|
|
|
357
382
|
options:
|
|
358
383
|
agent: ${vars.agent}
|
|
359
384
|
# R3 (0482): `--findings` names the failing anchors inline; `--gate-log` remains
|
|
360
|
-
# Declared Layer-1 role (0538 R2): routing reason
|
|
385
|
+
# Declared Layer-1 role (0538 R2/0710 R7): routing reason; no executor pin — role routing feeds the distinctness gate.
|
|
361
386
|
role: coder
|
|
362
387
|
# the full-context escape hatch when the digest is not enough.
|
|
363
388
|
input: /sp:dev-fixall "${vars.qualityGateCmd}" --gate-log .spur/run/${vars.wbs}-test-gate.log --findings "${vars.gateFindings}"
|
|
364
389
|
timeoutMs: ${vars.stepTimeoutMs}
|
|
390
|
+
# 0706 R6: bounded remediation hop — unattended and tree-mutating,
|
|
391
|
+
# so it declares the same minimum requirements as `implement`.
|
|
392
|
+
requiresCapabilities:
|
|
393
|
+
fsWrite: available
|
|
394
|
+
processSpawn: available
|
|
365
395
|
|
|
366
396
|
- id: test-recheck
|
|
367
397
|
description: >
|
|
@@ -370,6 +400,13 @@ states:
|
|
|
370
400
|
or the pipeline `failed` state (FAIL and attempts exhausted) — never a
|
|
371
401
|
raw lifecycle abort that skips the terminal `failed` state.
|
|
372
402
|
onEnter:
|
|
403
|
+
# R4 (0703, ADR-071): bounded remediation mutated the tree by design, so the fresh evidence
|
|
404
|
+
# chain (recheck gate → review → verify) must start from a NEWLY captured digest. Capture-only;
|
|
405
|
+
# the guards and `record` compare against this value.
|
|
406
|
+
- kind: proof.fingerprint
|
|
407
|
+
options:
|
|
408
|
+
var: proofDigest
|
|
409
|
+
taskFile: ${vars.taskSpecPath}
|
|
373
410
|
# 0587 R3: probe-then-full recheck. A red gateProbeCmd records FAIL and skips the full
|
|
374
411
|
# gate (the measured waste is re-running a 110–140s gate to learn the tree is still red);
|
|
375
412
|
# a green probe (or empty gateProbeCmd) falls through to the full-gate loop unchanged.
|
|
@@ -413,6 +450,7 @@ states:
|
|
|
413
450
|
else
|
|
414
451
|
printf 'FAIL\n' > "$STATUS_FILE";
|
|
415
452
|
fi &&
|
|
453
|
+
printf 'proof-digest: %s\n' "$proofDigest" >> "$LOG_FILE" &&
|
|
416
454
|
exit 0
|
|
417
455
|
|
|
418
456
|
- id: review
|
|
@@ -420,10 +458,19 @@ states:
|
|
|
420
458
|
onEnter:
|
|
421
459
|
- kind: agent.run
|
|
422
460
|
options:
|
|
423
|
-
|
|
461
|
+
# 0710 R2: review always runs on a fresh session — no implementation-session
|
|
462
|
+
# inheritance, no latch resume; implementation context reaches the reviewer
|
|
463
|
+
# only via the persisted task spec, the recorded diff, and run artifacts.
|
|
464
|
+
# 0710 R4/R5: the agent pin is deliberately gone — role: reviewer routes
|
|
465
|
+
# through the executor registry, and the runner enforces (pre-dispatch,
|
|
466
|
+
# fail-closed) that a P0/P1 task's review resolves a DIFFERENT executor
|
|
467
|
+
# spec than the implement stage recorded in __agentRouting_implement.
|
|
424
468
|
input: /sp:dev-review ${vars.wbs} --auto
|
|
425
|
-
# Declared Layer-1 role (0538 R2): routing reason
|
|
469
|
+
# Declared Layer-1 role (0538 R2/0710 R7): routing reason; no executor pin — role routing feeds the distinctness gate.
|
|
426
470
|
role: reviewer
|
|
471
|
+
freshSession: true
|
|
472
|
+
priority: ${vars.taskPriority}
|
|
473
|
+
compareExecutorWith: implement
|
|
427
474
|
timeoutMs: ${vars.stepTimeoutMs}
|
|
428
475
|
|
|
429
476
|
- id: approve
|
|
@@ -441,47 +488,64 @@ states:
|
|
|
441
488
|
|
|
442
489
|
- id: verify
|
|
443
490
|
description: >
|
|
444
|
-
|
|
491
|
+
Observe-only functional verification (BDD + traceability) via /sp:dev-verify --fix none
|
|
492
|
+
(task 0703 R1, ADR-071): the verifier certifies the state, it never repairs its own subject.
|
|
493
|
+
A live digest compare BEFORE the agent refuses to certify a state that drifted after the
|
|
494
|
+
quality/review evidence was produced (R2). The agent's
|
|
445
495
|
captured answer is written to `.spur/run/<wbs>-verify-answer.txt` and MUST follow
|
|
446
496
|
the answer-file schema contract (explicit `Verdict: PASS|PARTIAL|FAIL` line plus
|
|
447
497
|
`| Req | Status | Evidence |` and `| AC | Status | Evidence Type | Evidence |` tables);
|
|
448
498
|
a deterministic shell step then derives the verdict and writes the gate artifact
|
|
449
499
|
`.spur/run/<wbs>-verdict.json` (so the completion gate reads a real verdict, not
|
|
450
|
-
agent discretion — R9)
|
|
451
|
-
|
|
500
|
+
agent discretion — R9) with a proof block naming the digest and the per-stage results (R3).
|
|
501
|
+
Repairable non-PASS routes once through the bounded remediation hop (verify → test-fix,
|
|
502
|
+
R4); the chain reruns on a fresh digest.
|
|
452
503
|
onEnter:
|
|
504
|
+
# R2 (0703): midpoint bracket compare — refuse to spend verification on a state that no
|
|
505
|
+
# longer matches the digest the quality/review evidence names. Reuses `proofDigestNow`:
|
|
506
|
+
# set here and re-set by the final compare at `record` entry.
|
|
507
|
+
- kind: proof.fingerprint
|
|
508
|
+
options:
|
|
509
|
+
var: proofDigestNow
|
|
510
|
+
taskFile: ${vars.taskSpecPath}
|
|
511
|
+
expect: ${vars.proofDigest}
|
|
453
512
|
- kind: agent.run
|
|
454
513
|
options:
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
#
|
|
514
|
+
# 0710 R2: verify is a separate fresh-session execution — never the review
|
|
515
|
+
# session, never the implement session (R6).
|
|
516
|
+
# 0710 R4/R5: role-routed like review; P0/P1 demands a distinct executor.
|
|
517
|
+
# R1 (0703, ADR-071): `--fix none` — final verification is observe-only. Remediation
|
|
518
|
+
# belongs to the bounded test-fix hop, never to the certifying pass.
|
|
519
|
+
input: /sp:dev-verify ${vars.wbs} --auto --fix none --focus all
|
|
520
|
+
# Declared Layer-1 role (0538 R2/0710 R7): routing reason; no executor pin — role routing feeds the distinctness gate.
|
|
458
521
|
role: reviewer
|
|
522
|
+
freshSession: true
|
|
523
|
+
priority: ${vars.taskPriority}
|
|
524
|
+
compareExecutorWith: implement
|
|
459
525
|
timeoutMs: ${vars.stepTimeoutMs}
|
|
460
526
|
answerFile: .spur/run/${vars.wbs}-verify-answer.txt
|
|
461
527
|
- kind: shell
|
|
462
528
|
options:
|
|
463
529
|
command: "$spurBin task verdict $wbs --from-answer .spur/run/$wbs-verify-answer.txt"
|
|
464
|
-
#
|
|
465
|
-
#
|
|
466
|
-
#
|
|
467
|
-
#
|
|
468
|
-
|
|
469
|
-
options:
|
|
470
|
-
command: '$spurBin task path $wbs --json 2>/dev/null | jq -r ".path // empty" > ".spur/run/$wbs-taskpath.txt" || true; exit 0'
|
|
471
|
-
- kind: file.read.into-var
|
|
472
|
-
options:
|
|
473
|
-
path: .spur/run/${vars.wbs}-taskpath.txt
|
|
474
|
-
var: taskSpecPath
|
|
475
|
-
- kind: proof.fingerprint
|
|
476
|
-
options:
|
|
477
|
-
var: proofDigest
|
|
478
|
-
taskFile: ${vars.taskSpecPath}
|
|
479
|
-
# R3: the evidence must NAME the digest, not just assert proof validity in prose. Stamp it
|
|
480
|
-
# into the verdict artifact's checks[] so the document that aggregates quality, review, and
|
|
481
|
-
# verification results carries the value `record`'s compare then proves unchanged.
|
|
530
|
+
# R3 (0703): write the required proof block into the verdict artifact — the digest, the
|
|
531
|
+
# capture point, and the named per-stage results, each stage carrying the SAME digest
|
|
532
|
+
# value (prose asserting proof validity is insufficient). Also keeps the flat
|
|
533
|
+
# `proof-input-digest` check row for consumers that read `checks[]`. Soft action + hard
|
|
534
|
+
# guard: a missing/malformed stamp fails the `verify → record` guard below, not this step.
|
|
482
535
|
- kind: shell
|
|
483
536
|
options:
|
|
484
|
-
command:
|
|
537
|
+
command: >-
|
|
538
|
+
V=".spur/run/$wbs-verdict.json";
|
|
539
|
+
if [ -f "$V" ] && [ -n "$proofDigest" ]; then
|
|
540
|
+
jq --arg d "$proofDigest" --arg g "$(cat .spur/run/$wbs-test-gate.status 2>/dev/null || echo UNKNOWN)"
|
|
541
|
+
'. + {proof: {digest: $d, capturePoint: "quality-gate-entry", stages: {
|
|
542
|
+
qualityGate: {status: $g, digest: $d},
|
|
543
|
+
review: {status: "completed", digest: $d},
|
|
544
|
+
verification: {status: .verdict, digest: $d}}}}
|
|
545
|
+
| .checks += [{name: "proof-input-digest", status: "pass", evidence: $d}]'
|
|
546
|
+
"$V" > "$V.tmp" && mv "$V.tmp" "$V";
|
|
547
|
+
fi;
|
|
548
|
+
exit 0
|
|
485
549
|
|
|
486
550
|
- id: record
|
|
487
551
|
description: >
|
|
@@ -492,10 +556,15 @@ states:
|
|
|
492
556
|
retry-suppression) if `feature_id` is present, or appends an orphan link proposal
|
|
493
557
|
to the run report if absent (task 0328 / ADR-0322).
|
|
494
558
|
onEnter:
|
|
495
|
-
# Proof-state compare (task 0612, ADR-071
|
|
496
|
-
#
|
|
497
|
-
#
|
|
498
|
-
#
|
|
559
|
+
# Proof-state compare (task 0612, ADR-071; bracket closed against the pre-chain
|
|
560
|
+
# capture per task 0703) — FIRST action in the state, before any record write.
|
|
561
|
+
# Re-captures the digest and asserts it equals the value the evidence chain started
|
|
562
|
+
# from. A mismatch means a proof input changed after evidence was established; the
|
|
563
|
+
# default `fail` policy halts the sequence and routes the run to `failed` rather
|
|
564
|
+
# than crossing into `record`. Task-spec evidence writes (Testing/Review/Solution,
|
|
565
|
+
# R6) happen only in the actions AFTER this comparison, and the fingerprint scopes
|
|
566
|
+
# task content to the proof-input sections, so they cannot invalidate the certified
|
|
567
|
+
# input set.
|
|
499
568
|
- kind: proof.fingerprint
|
|
500
569
|
options:
|
|
501
570
|
var: proofDigestNow
|
|
@@ -573,10 +642,17 @@ states:
|
|
|
573
642
|
- kind: note
|
|
574
643
|
options:
|
|
575
644
|
message: "Pipeline complete for task ${vars.wbs} (done gate cleared)."
|
|
576
|
-
# Checkpoint write: record session state for resume (
|
|
645
|
+
# Checkpoint write: record session state for resume (0711 R1–R3) —
|
|
646
|
+
# canonical frontmatter contract; mirrors the Session Checkpoint
|
|
647
|
+
# Convention in plugins/sp/skills/spur-dev/references/cross-cutting.md.
|
|
648
|
+
# Advisory only: the task file and the persisted run row stay authoritative.
|
|
577
649
|
- kind: shell
|
|
578
650
|
options:
|
|
579
|
-
|
|
651
|
+
# Single logical line: the composition-baseline argument-split lint flags any
|
|
652
|
+
# command whose continuation lines look like argument lists (heredocs with
|
|
653
|
+
# `- item` entries trip it), so the checkpoint body is one printf with \n escapes.
|
|
654
|
+
command: >-
|
|
655
|
+
mkdir -p .spur/memory/sessions; CP_TS="$(date -u +%Y-%m-%dT%H:%M:%SZ)"; CP_COMMIT="$(git rev-parse HEAD 2>/dev/null || echo unknown)"; CP_DIGEST="$(cut -d= -f2 .spur/run/$wbs-proofdigest.txt 2>/dev/null || echo '')"; CP_RUN="$SPUR_RUN_ID"; [ -z "$CP_RUN" ] && CP_RUN="$RUN_ID"; printf '%s\n' '---' 'schema_version: 1' "session_id: $(date -u +%Y-%m-%d)-$wbs" 'workflow: task-pipeline' "run_id: $CP_RUN" "task_wbs: $wbs" 'feature_id: ""' 'phase: done' 'status: done' 'last_gate: record' "source_commit: $CP_COMMIT" "digest: $CP_DIGEST" "generated_at: $CP_TS" "updated_at: $CP_TS" "next_action: none - task $wbs complete (terminal; advisory only)" 'artifacts:' ' - .spur/run/$wbs-verdict.json' ' - .spur/run/$wbs-test-gate.log' '---' '' '## Session Notes' '' "Terminal checkpoint for task $wbs (task-pipeline done)." 'Advisory only; the task file is authoritative.' > .spur/memory/sessions/$wbs-checkpoint.md; exit 0
|
|
580
656
|
|
|
581
657
|
- id: failed
|
|
582
658
|
description: >
|
|
@@ -587,17 +663,17 @@ states:
|
|
|
587
663
|
description: Terminal — pipeline cancelled by operator at the approval gate (R1).
|
|
588
664
|
|
|
589
665
|
transitions:
|
|
590
|
-
# ── precheck:
|
|
666
|
+
# ── precheck: size PASS + task check → implement; else → failed ──
|
|
591
667
|
- from: precheck
|
|
592
668
|
to: implement
|
|
593
|
-
description:
|
|
669
|
+
description: Deterministic size and task checks are green — begin implementation.
|
|
594
670
|
guard:
|
|
595
671
|
kind: shell
|
|
596
672
|
options:
|
|
597
|
-
command: 'test "$(cat .spur/run/$wbs-precheck-
|
|
673
|
+
command: 'test "$(cat .spur/run/$wbs-precheck-size.status 2>/dev/null)" = PASS && $spurBin task check $wbs'
|
|
598
674
|
- from: precheck
|
|
599
675
|
to: failed
|
|
600
|
-
description:
|
|
676
|
+
description: Size and/or task check failed — stop before implement.
|
|
601
677
|
guard:
|
|
602
678
|
kind: always
|
|
603
679
|
|
|
@@ -707,39 +783,62 @@ transitions:
|
|
|
707
783
|
command: 'test "$__hitlAnswer" = cancel'
|
|
708
784
|
|
|
709
785
|
# ── completion gate (the YAML-native replacement for rd3's default-on --postflight-verify) ──
|
|
710
|
-
# The verify step emits .spur/run/<wbs>-verdict.json
|
|
711
|
-
#
|
|
712
|
-
#
|
|
786
|
+
# The verify step emits .spur/run/<wbs>-verdict.json with a required proof block (task 0703 R3/R5).
|
|
787
|
+
# Only `verdict: PASS` PLUS a proof block whose digest — top level and every named stage — equals
|
|
788
|
+
# the captured `proofDigest` clears the gate to `record`; any non-PASS, a missing file, malformed
|
|
789
|
+
# JSON, or missing/mismatched proof evidence does not. Declaration order: PASS+proof guard FIRST,
|
|
790
|
+
# then the bounded remediation route (R4), then the always catch-all so a PASS verdict with a
|
|
791
|
+
# missing/malformed proof block still terminates at `failed` instead of hanging the state.
|
|
713
792
|
- from: verify
|
|
714
793
|
to: record
|
|
715
|
-
description: Verification verdict is PASS — record results and proceed to done.
|
|
794
|
+
description: Verification verdict is PASS and its proof block names the captured digest on every stage — record results and proceed to done.
|
|
716
795
|
guard:
|
|
717
796
|
kind: shell
|
|
718
797
|
options:
|
|
719
|
-
command:
|
|
798
|
+
command: >-
|
|
799
|
+
V=".spur/run/$wbs-verdict.json";
|
|
800
|
+
test "$(jq -r .verdict "$V" 2>/dev/null)" = PASS &&
|
|
801
|
+
test "$(jq -r '.proof.digest // ""' "$V" 2>/dev/null)" = "$proofDigest" &&
|
|
802
|
+
test "$(jq -r '.proof.stages.qualityGate.digest // ""' "$V" 2>/dev/null)" = "$proofDigest" &&
|
|
803
|
+
test "$(jq -r '.proof.stages.review.digest // ""' "$V" 2>/dev/null)" = "$proofDigest" &&
|
|
804
|
+
test "$(jq -r '.proof.stages.verification.digest // ""' "$V" 2>/dev/null)" = "$proofDigest"
|
|
720
805
|
- from: verify
|
|
721
|
-
to:
|
|
722
|
-
description:
|
|
806
|
+
to: test-fix
|
|
807
|
+
description: >-
|
|
808
|
+
Verification returned a repairable non-PASS and the shared fix budget is not exhausted —
|
|
809
|
+
bounded remediation hop (task 0703 R4); the chain re-enters quality → review → verify on a
|
|
810
|
+
freshly captured digest. Never reached on PASS: remediation cannot follow certification.
|
|
723
811
|
guard:
|
|
724
812
|
kind: shell
|
|
725
813
|
options:
|
|
726
|
-
command:
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
814
|
+
command: >-
|
|
815
|
+
V="$(jq -r .verdict .spur/run/$wbs-verdict.json 2>/dev/null)";
|
|
816
|
+
test -n "$V" && test "$V" != PASS &&
|
|
817
|
+
test "$(cat .spur/run/$wbs-test-fix-attempt 2>/dev/null || echo 0)" -lt "$qualityGateMaxFixAttempts"
|
|
818
|
+
- from: verify
|
|
819
|
+
to: failed
|
|
820
|
+
description: >-
|
|
821
|
+
Non-PASS with the fix budget exhausted, or a PASS/missing/malformed verdict whose proof
|
|
822
|
+
block is absent or mismatched (task 0703 R5) — block before done; defense catch-all so the
|
|
823
|
+
state always has a viable outgoing edge.
|
|
824
|
+
guard:
|
|
825
|
+
kind: always
|
|
826
|
+
# ── done gate: record → done/failed gated on `spur task check` (ADR-026 amendment 2026-06-23)
|
|
827
|
+
# PLUS the proof-block re-assertion (task 0703 R5): the verdict artifact must still be PASS and
|
|
828
|
+
# still name the captured digest — a forged or mutated completion artifact fails closed here.
|
|
731
829
|
# Declaration order: pass guard first.
|
|
732
830
|
- from: record
|
|
733
831
|
to: done
|
|
734
|
-
description: Task check passed — certify done.
|
|
832
|
+
description: Task check passed and the verdict proof block still names the captured digest — certify done.
|
|
735
833
|
guard:
|
|
736
834
|
kind: shell
|
|
737
835
|
options:
|
|
738
|
-
command:
|
|
836
|
+
command: >-
|
|
837
|
+
$spurBin task check $wbs &&
|
|
838
|
+
test "$(jq -r .verdict .spur/run/$wbs-verdict.json 2>/dev/null)" = PASS &&
|
|
839
|
+
test "$(jq -r '.proof.digest // ""' .spur/run/$wbs-verdict.json 2>/dev/null)" = "$proofDigest"
|
|
739
840
|
- from: record
|
|
740
841
|
to: failed
|
|
741
|
-
description: Task check failed — block before done
|
|
842
|
+
description: Task check failed or proof evidence missing/malformed/mismatched — block before done.
|
|
742
843
|
guard:
|
|
743
|
-
kind:
|
|
744
|
-
options:
|
|
745
|
-
command: "! $spurBin task check $wbs"
|
|
844
|
+
kind: always
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/spur",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.68",
|
|
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.
|
|
57
|
-
"@gobing-ai/ts-ai-runner": "^0.4.
|
|
58
|
-
"@gobing-ai/ts-dual-workflow-engine": "^0.4.
|
|
59
|
-
"@gobing-ai/ts-infra": "^0.4.
|
|
60
|
-
"@gobing-ai/ts-llm-jsonl-importer": "^0.4.
|
|
61
|
-
"@gobing-ai/ts-rule-engine": "^0.4.
|
|
62
|
-
"@gobing-ai/ts-runtime": "^0.4.
|
|
63
|
-
"@gobing-ai/ts-utils": "^0.4.
|
|
56
|
+
"@gobing-ai/ts-db": "^0.4.48",
|
|
57
|
+
"@gobing-ai/ts-ai-runner": "^0.4.48",
|
|
58
|
+
"@gobing-ai/ts-dual-workflow-engine": "^0.4.48",
|
|
59
|
+
"@gobing-ai/ts-infra": "^0.4.48",
|
|
60
|
+
"@gobing-ai/ts-llm-jsonl-importer": "^0.4.48",
|
|
61
|
+
"@gobing-ai/ts-rule-engine": "^0.4.48",
|
|
62
|
+
"@gobing-ai/ts-runtime": "^0.4.48",
|
|
63
|
+
"@gobing-ai/ts-utils": "^0.4.48",
|
|
64
64
|
"@types/bun": "1.3.14",
|
|
65
65
|
"@types/figlet": "^1.7.0",
|
|
66
66
|
"@types/node-notifier": "8.0.5",
|
package/plugins/sp/README.md
CHANGED
|
@@ -567,8 +567,9 @@ graph TB
|
|
|
567
567
|
1. User types `/sp:dev-plan "add task body write API"`.
|
|
568
568
|
2. **Command** (`dev-plan.md`) parses `$ARGUMENTS` and calls
|
|
569
569
|
`Skill(skill="sp:spur-dev", args="plan $ARGUMENTS")`.
|
|
570
|
-
3. **Skill** (`spur-dev/SKILL.md`)
|
|
571
|
-
|
|
570
|
+
3. **Skill** (`spur-dev/SKILL.md`) reads `idea-pipeline.yaml` and drives its states in the current
|
|
571
|
+
session by default: intake → `spur feature create` → AC generation → `spur feature check` gate →
|
|
572
|
+
decomposition → `spur task batch-create`. Explicit `--agent auto|<name>` uses the async worker.
|
|
572
573
|
4. **CLI** validates each step before writing — feature IDs are race-safe, WBS allocation is atomic,
|
|
573
574
|
`check` is the readiness matrix.
|
|
574
575
|
5. Result: validated feature file + decomposed task batch in `docs/features/` and `docs/tasks/`.
|
|
@@ -577,10 +578,9 @@ graph TB
|
|
|
577
578
|
|
|
578
579
|
1. User types `/sp:dev-run 0090`.
|
|
579
580
|
2. **Command** delegates to `sp:spur-dev` skill (execution half).
|
|
580
|
-
3. **Skill** reads the task
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
persists run state.
|
|
581
|
+
3. **Skill** reads the task and `task-pipeline.yaml`, then drives its actions and guards in-session.
|
|
582
|
+
4. **CLI** supplies deterministic actions and lifecycle gates; explicit executors use the async
|
|
583
|
+
workflow worker and persisted run state.
|
|
584
584
|
5. Result: task driven through implement → check → fix → verify lifecycle.
|
|
585
585
|
|
|
586
586
|
**Task-corpus write protection.**
|
|
@@ -606,7 +606,6 @@ pipeline owns one lifecycle phase:
|
|
|
606
606
|
| `task-pipeline.yaml` | Single-task execution | `/sp:dev-run` |
|
|
607
607
|
| `idea-pipeline.yaml` | Idea/planning → feature + tasks | `/sp:dev-idea`, `/sp:dev-plan` |
|
|
608
608
|
| `feature-dev.yaml` | Feature umbrella execution | `/sp:dev-runall --feature` |
|
|
609
|
-
| `idea-pipeline.yaml` | Idea to feature + AC + task batch | `/sp:dev-idea` |
|
|
610
609
|
| `wrapup-pipeline.yaml` | Post-execution wrap-up | `/sp:dev-wrap`, `/sp:dev-wrapall` |
|
|
611
610
|
| `docs-pipeline.yaml` | Docs-only task execution | `/sp:dev-run --mode implement` |
|
|
612
611
|
| `wayfinder-resolution.yaml` | Wayfinder ticket resolution loop | `spur workflow run` (free-form) |
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Turn a vague idea into a feature with AC and a decomposed task batch — discovery, idea-eval, feature-create, AC, feature-check, system-design, decompose, batch-create (Design by default), handoff
|
|
3
3
|
role: planner
|
|
4
|
-
argument-hint: "\"<idea>\" [--auto] [--skip-design] [--approve-taste] [--agent <auto|name>]"
|
|
4
|
+
argument-hint: "\"<idea>\" [--auto] [--skip-design] [--approve-taste] [--agent <inline|auto|name>]"
|
|
5
5
|
allowed-tools: ["Bash", "Read", "Skill", "AskUserQuestion"]
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -20,7 +20,7 @@ contract below maps to that workflow's transitions.
|
|
|
20
20
|
| `--approve-taste` | With `--auto`: set idea_approved + design_approved so idea-eval / design-approval do not pause. | off |
|
|
21
21
|
| `--idea-approved` | Compatibility alias for idea_approved=true (subset of --approve-taste). | off |
|
|
22
22
|
| `--design-approved` | Compatibility alias for design_approved=true (subset of --approve-taste). | off |
|
|
23
|
-
| `--agent` `<auto\|name>` | Who runs the model-bearing ideation.
|
|
23
|
+
| `--agent` `<inline\|auto\|name>` | Who runs the model-bearing ideation. Omission and `inline` drive `idea-pipeline.yaml` in this session with zero external agent/workflow processes; `auto` tier-resolves an executor and a name pins one, both through the async workflow worker. | inline |
|
|
24
24
|
|
|
25
25
|
For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag-glossary.md).
|
|
26
26
|
|
|
@@ -31,7 +31,7 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
|
|
|
31
31
|
[--auto] # skip objective HITL only (feature-check, batch-create)
|
|
32
32
|
[--skip-design] # design package off (system-design + task Design)
|
|
33
33
|
[--approve-taste] # with --auto: skip idea-eval + design-approval pauses
|
|
34
|
-
[--agent <auto|name>]
|
|
34
|
+
[--agent <inline|auto|name>] # inline is the current session; auto/name are async workers
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
There is **no** `--design` force flag. Design is default-on; only `--skip-design` opts out.
|
|
@@ -42,6 +42,8 @@ vars as subsets of `--approve-taste` (`idea_approved` / `design_approved`). Pref
|
|
|
42
42
|
## Implementation
|
|
43
43
|
|
|
44
44
|
- Apply the [inline-default execution-surface contract](../skills/spur-dev/references/cross-cutting.md#inline-default-execution-surface).
|
|
45
|
+
- Omitted/`inline`: drive `idea-pipeline.yaml` through the [inline pipeline driver](../skills/spur-dev/references/inline-pipeline-driver.md). Do not launch `spur workflow run`, `spur agent run`, or a native subagent unless the operator explicitly requests delegation.
|
|
46
|
+
- `auto`/name: launch `spur workflow run idea-pipeline.yaml --async`, observe with one `workflow trace --follow`, and only report cancellation as stopped when `workflow cancel --json` returns `killed: true`.
|
|
45
47
|
- `Skill(skill="sp:spur-dev", args="idea $ARGUMENTS")`
|
|
46
48
|
- Stage contract (discovery → idea-eval → feature-create → AC → feature-check → system-design →
|
|
47
49
|
decompose → batch-create → handoff): `plugins/sp/skills/spur-dev/references/dev-operations.md` § idea.
|