@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
|
@@ -54,15 +54,16 @@ vars:
|
|
|
54
54
|
# runs and `workflow validate` resolve the template. (See AGENTS.md / ADR-026.)
|
|
55
55
|
spurBin: "spur"
|
|
56
56
|
# Agent the pipeline's agent.run steps invoke. Override per run with
|
|
57
|
-
# `--vars '{"agent":"claude"}'`.
|
|
58
|
-
#
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
#
|
|
57
|
+
# `--vars '{"agent":"claude"}'`. `auto` is the reserved config-resolving selector:
|
|
58
|
+
# `agent.default` role -> tier -> cheapest USABLE executor. A named literal here would
|
|
59
|
+
# pin a box-specific binary into tracked SSOT and escape that usability ladder.
|
|
60
|
+
agent: "auto"
|
|
61
|
+
# Implement-only executor override (R1, task 0454). Resolves like `agent` unless
|
|
62
|
+
# overridden. The `--agent` flag (execution-batch.md §3.2) forwards into BOTH
|
|
62
63
|
# `agent` and `implementAgent`, so a pinned `--agent X` reaches implement too. To
|
|
63
64
|
# pin ONLY implement while other hops keep the default, pass
|
|
64
65
|
# `--vars '{"implementAgent":"omp-zai"}'`.
|
|
65
|
-
implementAgent: "
|
|
66
|
+
implementAgent: "auto"
|
|
66
67
|
# Step-level timeout for agentic hops (review / verify / test-fix) in ms.
|
|
67
68
|
# Soft quality-gate shells are unbounded by this var (host shell only).
|
|
68
69
|
# Raised 600s → 1800s (task 0398 R4 / H6 dogfood). Override:
|
|
@@ -78,15 +79,25 @@ vars:
|
|
|
78
79
|
# Answer captured by the approve gate's hitl.confirm (R1): "yes" | "no" | "cancel".
|
|
79
80
|
# Empty by default; only meaningful once the approve state has been entered.
|
|
80
81
|
__hitlAnswer: ""
|
|
81
|
-
# Proof-state bracket (task 0612, ADR-071). `proofDigest` is
|
|
82
|
-
#
|
|
83
|
-
#
|
|
84
|
-
# the
|
|
85
|
-
# the
|
|
86
|
-
#
|
|
82
|
+
# Proof-state bracket (task 0612, ADR-071; restructured by task 0703). `proofDigest` is the
|
|
83
|
+
# canonical capture taken at quality-gate ENTRY — immediately before the evidence-producing
|
|
84
|
+
# final chain (quality → review → verify) — and re-captured at `test-recheck` when bounded
|
|
85
|
+
# remediation mutated the tree, so every evidence stage names one fresh digest (R2/R4).
|
|
86
|
+
# `proofDigestNow` is the live re-capture compared against `proofDigest` at verify entry and
|
|
87
|
+
# immediately before `record`; a mismatch means a proof input changed after evidence was
|
|
88
|
+
# established, so the run routes to `failed` instead of crossing the completion boundary (R5).
|
|
89
|
+
# `taskSpecPath` carries the task file path because `docs/tasks*` is excluded from the digest's
|
|
90
|
+
# git-tree half — spec content is folded in explicitly or a task-file edit would go undetected.
|
|
91
|
+
# The fingerprint scopes task content to the proof-input sections only (Background, Requirements,
|
|
92
|
+
# Acceptance Criteria, Design, Plan), so record-time Solution/Testing/Review evidence writes do
|
|
93
|
+
# not retroactively invalidate the certified input set (R6).
|
|
87
94
|
proofDigest: ""
|
|
88
95
|
proofDigestNow: ""
|
|
89
96
|
taskSpecPath: ""
|
|
97
|
+
# 0710 R4: task priority tier (P0..P4) extracted from the task frontmatter at the
|
|
98
|
+
# quality-gate stage. P0/P1 make the review/verify distinct-executor policy apply;
|
|
99
|
+
# unknown/empty priority means fresh-context-only (executor reuse allowed).
|
|
100
|
+
taskPriority: ""
|
|
90
101
|
# Project quality gate for the `test` hop (probe + fixall + recheck). Override per project
|
|
91
102
|
# with the same package-manager surface (this monorepo is Bun-only):
|
|
92
103
|
# `--vars '{"qualityGateCmd":"bun run lint && bun run test"}'`. Soft probe, hard recheck,
|
|
@@ -114,11 +125,11 @@ vars:
|
|
|
114
125
|
# file:line instead of re-deriving it from a fresh gate run (0482 R3).
|
|
115
126
|
gateFindings: ""
|
|
116
127
|
# Max R-items in ## Requirements before size precheck fails (R2, task 0454).
|
|
117
|
-
# Override with `--vars '{"maxImplementReqs":"
|
|
118
|
-
maxImplementReqs: "
|
|
128
|
+
# Override with `--vars '{"maxImplementReqs":"20"}'`.
|
|
129
|
+
maxImplementReqs: "10"
|
|
119
130
|
# Max checklist items under ## Plan before size precheck fails (R2, task 0454).
|
|
120
|
-
# Override with `--vars '{"maxImplementPlanItems":"
|
|
121
|
-
maxImplementPlanItems: "
|
|
131
|
+
# Override with `--vars '{"maxImplementPlanItems":"32"}'`.
|
|
132
|
+
maxImplementPlanItems: "16"
|
|
122
133
|
# Diff-scope guard on the implement hop (R1, task 0487). When the target task
|
|
123
134
|
# body backticks at least one path, non-corpus changes outside those paths
|
|
124
135
|
# fail the step by name. New files beside a declared file are allowed. Empty
|
|
@@ -129,37 +140,9 @@ vars:
|
|
|
129
140
|
states:
|
|
130
141
|
- id: precheck
|
|
131
142
|
description: >
|
|
132
|
-
|
|
133
|
-
`
|
|
134
|
-
(not a raw lifecycle abort mid-enter).
|
|
143
|
+
Fast deterministic task readiness and size checks. Failures route to the
|
|
144
|
+
`failed` terminal state (not a raw lifecycle abort mid-enter).
|
|
135
145
|
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
146
|
# R6 (0487): pre-launch hygiene WARNING (never a block) — starting a task on
|
|
164
147
|
# a tree already dirty with another task's implementation is how 0485's diff
|
|
165
148
|
# got swept into 0486's run. Corpus dirs are excluded: the pipeline writes
|
|
@@ -192,6 +175,10 @@ states:
|
|
|
192
175
|
# R1 (0453): auto-profile precheck reopens a done feature before task check.
|
|
193
176
|
# Under profile=auto, resolve feature_id, sync (preferred) or update to active.
|
|
194
177
|
# Under non-auto, leave R4 message to guide the operator.
|
|
178
|
+
# R3 (0723): a real reactivation failure is surfaced, not swallowed —
|
|
179
|
+
# the default 'fail' onEnter policy halts the sequence and routes the
|
|
180
|
+
# run to `failed` before implementation. Verbs stay single-shot:
|
|
181
|
+
# one sync, then one update fallback, never retried in a loop.
|
|
195
182
|
- kind: shell
|
|
196
183
|
options:
|
|
197
184
|
command: >-
|
|
@@ -199,17 +186,23 @@ states:
|
|
|
199
186
|
FID=$($spurBin task show $wbs --json 2>/dev/null |
|
|
200
187
|
jq -r '.feature_id // .frontmatter.feature_id // empty' 2>/dev/null);
|
|
201
188
|
if [ -n "$FID" ]; then
|
|
202
|
-
$spurBin feature sync "$FID" --force
|
|
203
|
-
$spurBin feature update "$FID" active 2>/dev/null
|
|
189
|
+
if ! $spurBin feature sync "$FID" --force 2>/dev/null; then
|
|
190
|
+
if ! $spurBin feature update "$FID" active 2>/dev/null; then
|
|
191
|
+
echo "precheck: FAIL - feature reactivation $FID failed;" >&2;
|
|
192
|
+
echo "precheck: feature sync + feature update both errored" >&2;
|
|
193
|
+
exit 1;
|
|
194
|
+
fi;
|
|
195
|
+
fi;
|
|
204
196
|
fi;
|
|
205
197
|
fi;
|
|
206
198
|
exit 0
|
|
207
|
-
# R2 (0454): task size precheck —
|
|
208
|
-
#
|
|
209
|
-
#
|
|
210
|
-
#
|
|
211
|
-
#
|
|
212
|
-
#
|
|
199
|
+
# R2 (0454, 0723): task size precheck — deterministic count-only
|
|
200
|
+
# evaluation of R-item and Plan-item counts. No executor-tier policy:
|
|
201
|
+
# dispatch-time requiresCapabilities at `agent.run` is the
|
|
202
|
+
# authoritative capability check. Writes PASS/FAIL to
|
|
203
|
+
# .spur/run/<wbs>-precheck-size.status. Always exit 0 (soft action);
|
|
204
|
+
# the precheck→implement guard reads the file, so a missing checker
|
|
205
|
+
# fails closed (writes FAIL, never PASS).
|
|
213
206
|
- kind: shell
|
|
214
207
|
options:
|
|
215
208
|
command: >-
|
|
@@ -217,11 +210,12 @@ states:
|
|
|
217
210
|
mkdir -p .spur/run &&
|
|
218
211
|
if [ -f plugins/sp/scripts/task-size-precheck.ts ]; then
|
|
219
212
|
bun plugins/sp/scripts/task-size-precheck.ts "$wbs"
|
|
220
|
-
--spur-bin "$spurBin" --max-reqs "$maxImplementReqs"
|
|
221
|
-
--
|
|
213
|
+
--spur-bin "$spurBin" --max-reqs "$maxImplementReqs"
|
|
214
|
+
--max-plan-items "$maxImplementPlanItems";
|
|
222
215
|
else
|
|
223
|
-
echo "task-size-precheck
|
|
224
|
-
echo "
|
|
216
|
+
echo "task-size-precheck failed closed — checker script" >&2 &&
|
|
217
|
+
echo "plugins/sp/scripts/task-size-precheck.ts absent." >&2 &&
|
|
218
|
+
echo "FAIL" > "$SIZE_FILE";
|
|
225
219
|
fi &&
|
|
226
220
|
exit 0
|
|
227
221
|
|
|
@@ -243,7 +237,7 @@ states:
|
|
|
243
237
|
options:
|
|
244
238
|
agent: ${vars.implementAgent}
|
|
245
239
|
# Pure slash command only (ADR-043). Anti-recursion / implement discipline
|
|
246
|
-
# Declared Layer-1 role (0538 R2): routing reason
|
|
240
|
+
# Declared Layer-1 role (0538 R2/0710 R7): routing reason; no executor pin — role routing feeds the distinctness gate.
|
|
247
241
|
role: coder
|
|
248
242
|
# lives in /sp:dev-run --mode implement → sp:code-implementation, not YAML prose.
|
|
249
243
|
input: /sp:dev-run --mode implement ${vars.wbs} --auto
|
|
@@ -253,6 +247,14 @@ states:
|
|
|
253
247
|
# a silent no-op routes the run to `failed` here instead of drifting
|
|
254
248
|
# into test/review and being caught a full pass later.
|
|
255
249
|
requireDiff: true
|
|
250
|
+
# 0706 R6: this stage mutates the working tree unattended under the
|
|
251
|
+
# auto profile, so it declares minimum execution-capability
|
|
252
|
+
# requirements. Dispatch fails closed (before spawn) when the
|
|
253
|
+
# resolved executor's attestation cannot satisfy them — attest the
|
|
254
|
+
# executor in agent config.
|
|
255
|
+
requiresCapabilities:
|
|
256
|
+
fsWrite: available
|
|
257
|
+
processSpawn: available
|
|
256
258
|
- kind: shell
|
|
257
259
|
options:
|
|
258
260
|
command: >-
|
|
@@ -296,11 +298,37 @@ states:
|
|
|
296
298
|
# test-recheck — soft recheck → review | test-fix | failed (never silent lifecycle abort)
|
|
297
299
|
- id: test
|
|
298
300
|
description: >
|
|
299
|
-
|
|
300
|
-
for SQLite lock contention).
|
|
301
|
+
Proof-chain entry + soft quality-gate probe (single logical gate on the green path; bounded retries only
|
|
302
|
+
for SQLite lock contention). Capture of the canonical proof-input digest happens HERE — before any
|
|
303
|
+
evidence-producing final check (task 0703, ADR-071) — so the gate, review, and verification evidence
|
|
304
|
+
all name one digest. Then runs
|
|
301
305
|
`${vars.qualityGateCmd}`, records PASS|FAIL under
|
|
302
306
|
`.spur/run/<wbs>-test-gate.status`, resets the fix attempt counter, always exit 0.
|
|
303
307
|
onEnter:
|
|
308
|
+
# R6/R2 (0703): resolve the task-spec path BEFORE the digest capture. `docs/tasks*` is excluded
|
|
309
|
+
# from the digest's git-tree half, so the spec is folded in explicitly via `taskSpecPath`.
|
|
310
|
+
- kind: shell
|
|
311
|
+
options:
|
|
312
|
+
# 0710 R4: resolve the spec path, then extract `priority:` from the TASK FILE itself (not the
|
|
313
|
+
# path listing); normalize to upper so requiresDistinctExecutor's exact 'P0'/'P1' match hits.
|
|
314
|
+
# Missing spec/line -> empty var -> back-compat (no distinctness requirement).
|
|
315
|
+
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'
|
|
316
|
+
- kind: file.read.into-var
|
|
317
|
+
options:
|
|
318
|
+
path: .spur/run/${vars.wbs}-taskpath.txt
|
|
319
|
+
var: taskSpecPath
|
|
320
|
+
# 0710 R4: carry the task's priority tier into the review/verify risk policy.
|
|
321
|
+
- kind: file.read.into-var
|
|
322
|
+
options:
|
|
323
|
+
path: .spur/run/${vars.wbs}-priority.txt
|
|
324
|
+
var: taskPriority
|
|
325
|
+
# R2 (0703, ADR-071): THE canonical proof capture. Placement is load-bearing: immediately before
|
|
326
|
+
# the final evidence chain, after every implement mutation (including the post-implement format).
|
|
327
|
+
# Capture-only here; `record` compares. A remediation pass re-captures at `test-recheck` (R4).
|
|
328
|
+
- kind: proof.fingerprint
|
|
329
|
+
options:
|
|
330
|
+
var: proofDigest
|
|
331
|
+
taskFile: ${vars.taskSpecPath}
|
|
304
332
|
- kind: shell
|
|
305
333
|
options:
|
|
306
334
|
command: >-
|
|
@@ -331,13 +359,17 @@ states:
|
|
|
331
359
|
else
|
|
332
360
|
printf 'FAIL\n' > "$STATUS_FILE";
|
|
333
361
|
fi &&
|
|
362
|
+
printf 'proof-digest: %s\n' "$proofDigest" >> "$LOG_FILE" &&
|
|
334
363
|
exit 0
|
|
335
364
|
|
|
336
365
|
- id: test-fix
|
|
337
366
|
description: >
|
|
338
|
-
Bounded auto-fix hop when the quality gate is red
|
|
339
|
-
|
|
340
|
-
|
|
367
|
+
Bounded auto-fix hop when the quality gate is red OR final verification returned a
|
|
368
|
+
repairable non-PASS (task 0703 R4: remediation never happens inside verify — it loops
|
|
369
|
+
through here, then re-enters quality → review → verify on a fresh digest). Increments
|
|
370
|
+
`.spur/run/<wbs>-test-fix-attempt` (the shared bound with the quality path), projects the
|
|
371
|
+
verify verdict into the gate log when one exists so the repair hop sees it, then pure
|
|
372
|
+
slash (ADR-043) `/sp:dev-fixall` against `${vars.qualityGateCmd}`.
|
|
341
373
|
onEnter:
|
|
342
374
|
- kind: shell
|
|
343
375
|
options:
|
|
@@ -345,7 +377,13 @@ states:
|
|
|
345
377
|
mkdir -p .spur/run &&
|
|
346
378
|
ATTEMPT_FILE=".spur/run/$wbs-test-fix-attempt" &&
|
|
347
379
|
n=$(cat "$ATTEMPT_FILE" 2>/dev/null || echo 0) &&
|
|
348
|
-
printf '%s\n' "$((n + 1))" > "$ATTEMPT_FILE"
|
|
380
|
+
printf '%s\n' "$((n + 1))" > "$ATTEMPT_FILE" &&
|
|
381
|
+
if [ -f ".spur/run/$wbs-verdict.json" ]; then
|
|
382
|
+
{ echo '--- verify verdict (remediation input, task 0703 R4) ---';
|
|
383
|
+
cat ".spur/run/$wbs-verdict.json";
|
|
384
|
+
} >> ".spur/run/$wbs-test-gate.log";
|
|
385
|
+
fi;
|
|
386
|
+
exit 0
|
|
349
387
|
# R3 (0482): project the extracted gate anchors into a var so the dispatch input
|
|
350
388
|
# can NAME the failing file:line, not merely point at a log. A vars template cannot
|
|
351
389
|
# run a shell, so the read is an action, not an inline `$(cat ...)` substitution.
|
|
@@ -357,11 +395,16 @@ states:
|
|
|
357
395
|
options:
|
|
358
396
|
agent: ${vars.agent}
|
|
359
397
|
# R3 (0482): `--findings` names the failing anchors inline; `--gate-log` remains
|
|
360
|
-
# Declared Layer-1 role (0538 R2): routing reason
|
|
398
|
+
# Declared Layer-1 role (0538 R2/0710 R7): routing reason; no executor pin — role routing feeds the distinctness gate.
|
|
361
399
|
role: coder
|
|
362
400
|
# the full-context escape hatch when the digest is not enough.
|
|
363
401
|
input: /sp:dev-fixall "${vars.qualityGateCmd}" --gate-log .spur/run/${vars.wbs}-test-gate.log --findings "${vars.gateFindings}"
|
|
364
402
|
timeoutMs: ${vars.stepTimeoutMs}
|
|
403
|
+
# 0706 R6: bounded remediation hop — unattended and tree-mutating,
|
|
404
|
+
# so it declares the same minimum requirements as `implement`.
|
|
405
|
+
requiresCapabilities:
|
|
406
|
+
fsWrite: available
|
|
407
|
+
processSpawn: available
|
|
365
408
|
|
|
366
409
|
- id: test-recheck
|
|
367
410
|
description: >
|
|
@@ -370,6 +413,13 @@ states:
|
|
|
370
413
|
or the pipeline `failed` state (FAIL and attempts exhausted) — never a
|
|
371
414
|
raw lifecycle abort that skips the terminal `failed` state.
|
|
372
415
|
onEnter:
|
|
416
|
+
# R4 (0703, ADR-071): bounded remediation mutated the tree by design, so the fresh evidence
|
|
417
|
+
# chain (recheck gate → review → verify) must start from a NEWLY captured digest. Capture-only;
|
|
418
|
+
# the guards and `record` compare against this value.
|
|
419
|
+
- kind: proof.fingerprint
|
|
420
|
+
options:
|
|
421
|
+
var: proofDigest
|
|
422
|
+
taskFile: ${vars.taskSpecPath}
|
|
373
423
|
# 0587 R3: probe-then-full recheck. A red gateProbeCmd records FAIL and skips the full
|
|
374
424
|
# gate (the measured waste is re-running a 110–140s gate to learn the tree is still red);
|
|
375
425
|
# a green probe (or empty gateProbeCmd) falls through to the full-gate loop unchanged.
|
|
@@ -413,6 +463,7 @@ states:
|
|
|
413
463
|
else
|
|
414
464
|
printf 'FAIL\n' > "$STATUS_FILE";
|
|
415
465
|
fi &&
|
|
466
|
+
printf 'proof-digest: %s\n' "$proofDigest" >> "$LOG_FILE" &&
|
|
416
467
|
exit 0
|
|
417
468
|
|
|
418
469
|
- id: review
|
|
@@ -420,10 +471,19 @@ states:
|
|
|
420
471
|
onEnter:
|
|
421
472
|
- kind: agent.run
|
|
422
473
|
options:
|
|
423
|
-
|
|
474
|
+
# 0710 R2: review always runs on a fresh session — no implementation-session
|
|
475
|
+
# inheritance, no latch resume; implementation context reaches the reviewer
|
|
476
|
+
# only via the persisted task spec, the recorded diff, and run artifacts.
|
|
477
|
+
# 0710 R4/R5: the agent pin is deliberately gone — role: reviewer routes
|
|
478
|
+
# through the executor registry, and the runner enforces (pre-dispatch,
|
|
479
|
+
# fail-closed) that a P0/P1 task's review resolves a DIFFERENT executor
|
|
480
|
+
# spec than the implement stage recorded in __agentRouting_implement.
|
|
424
481
|
input: /sp:dev-review ${vars.wbs} --auto
|
|
425
|
-
# Declared Layer-1 role (0538 R2): routing reason
|
|
482
|
+
# Declared Layer-1 role (0538 R2/0710 R7): routing reason; no executor pin — role routing feeds the distinctness gate.
|
|
426
483
|
role: reviewer
|
|
484
|
+
freshSession: true
|
|
485
|
+
priority: ${vars.taskPriority}
|
|
486
|
+
compareExecutorWith: implement
|
|
427
487
|
timeoutMs: ${vars.stepTimeoutMs}
|
|
428
488
|
|
|
429
489
|
- id: approve
|
|
@@ -441,47 +501,64 @@ states:
|
|
|
441
501
|
|
|
442
502
|
- id: verify
|
|
443
503
|
description: >
|
|
444
|
-
|
|
504
|
+
Observe-only functional verification (BDD + traceability) via /sp:dev-verify --fix none
|
|
505
|
+
(task 0703 R1, ADR-071): the verifier certifies the state, it never repairs its own subject.
|
|
506
|
+
A live digest compare BEFORE the agent refuses to certify a state that drifted after the
|
|
507
|
+
quality/review evidence was produced (R2). The agent's
|
|
445
508
|
captured answer is written to `.spur/run/<wbs>-verify-answer.txt` and MUST follow
|
|
446
509
|
the answer-file schema contract (explicit `Verdict: PASS|PARTIAL|FAIL` line plus
|
|
447
510
|
`| Req | Status | Evidence |` and `| AC | Status | Evidence Type | Evidence |` tables);
|
|
448
511
|
a deterministic shell step then derives the verdict and writes the gate artifact
|
|
449
512
|
`.spur/run/<wbs>-verdict.json` (so the completion gate reads a real verdict, not
|
|
450
|
-
agent discretion — R9)
|
|
451
|
-
|
|
513
|
+
agent discretion — R9) with a proof block naming the digest and the per-stage results (R3).
|
|
514
|
+
Repairable non-PASS routes once through the bounded remediation hop (verify → test-fix,
|
|
515
|
+
R4); the chain reruns on a fresh digest.
|
|
452
516
|
onEnter:
|
|
517
|
+
# R2 (0703): midpoint bracket compare — refuse to spend verification on a state that no
|
|
518
|
+
# longer matches the digest the quality/review evidence names. Reuses `proofDigestNow`:
|
|
519
|
+
# set here and re-set by the final compare at `record` entry.
|
|
520
|
+
- kind: proof.fingerprint
|
|
521
|
+
options:
|
|
522
|
+
var: proofDigestNow
|
|
523
|
+
taskFile: ${vars.taskSpecPath}
|
|
524
|
+
expect: ${vars.proofDigest}
|
|
453
525
|
- kind: agent.run
|
|
454
526
|
options:
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
#
|
|
527
|
+
# 0710 R2: verify is a separate fresh-session execution — never the review
|
|
528
|
+
# session, never the implement session (R6).
|
|
529
|
+
# 0710 R4/R5: role-routed like review; P0/P1 demands a distinct executor.
|
|
530
|
+
# R1 (0703, ADR-071): `--fix none` — final verification is observe-only. Remediation
|
|
531
|
+
# belongs to the bounded test-fix hop, never to the certifying pass.
|
|
532
|
+
input: /sp:dev-verify ${vars.wbs} --auto --fix none --focus all
|
|
533
|
+
# Declared Layer-1 role (0538 R2/0710 R7): routing reason; no executor pin — role routing feeds the distinctness gate.
|
|
458
534
|
role: reviewer
|
|
535
|
+
freshSession: true
|
|
536
|
+
priority: ${vars.taskPriority}
|
|
537
|
+
compareExecutorWith: implement
|
|
459
538
|
timeoutMs: ${vars.stepTimeoutMs}
|
|
460
539
|
answerFile: .spur/run/${vars.wbs}-verify-answer.txt
|
|
461
540
|
- kind: shell
|
|
462
541
|
options:
|
|
463
542
|
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.
|
|
543
|
+
# R3 (0703): write the required proof block into the verdict artifact — the digest, the
|
|
544
|
+
# capture point, and the named per-stage results, each stage carrying the SAME digest
|
|
545
|
+
# value (prose asserting proof validity is insufficient). Also keeps the flat
|
|
546
|
+
# `proof-input-digest` check row for consumers that read `checks[]`. Soft action + hard
|
|
547
|
+
# guard: a missing/malformed stamp fails the `verify → record` guard below, not this step.
|
|
482
548
|
- kind: shell
|
|
483
549
|
options:
|
|
484
|
-
command:
|
|
550
|
+
command: >-
|
|
551
|
+
V=".spur/run/$wbs-verdict.json";
|
|
552
|
+
if [ -f "$V" ] && [ -n "$proofDigest" ]; then
|
|
553
|
+
jq --arg d "$proofDigest" --arg g "$(cat .spur/run/$wbs-test-gate.status 2>/dev/null || echo UNKNOWN)"
|
|
554
|
+
'. + {proof: {digest: $d, capturePoint: "quality-gate-entry", stages: {
|
|
555
|
+
qualityGate: {status: $g, digest: $d},
|
|
556
|
+
review: {status: "completed", digest: $d},
|
|
557
|
+
verification: {status: .verdict, digest: $d}}}}
|
|
558
|
+
| .checks += [{name: "proof-input-digest", status: "pass", evidence: $d}]'
|
|
559
|
+
"$V" > "$V.tmp" && mv "$V.tmp" "$V";
|
|
560
|
+
fi;
|
|
561
|
+
exit 0
|
|
485
562
|
|
|
486
563
|
- id: record
|
|
487
564
|
description: >
|
|
@@ -492,10 +569,15 @@ states:
|
|
|
492
569
|
retry-suppression) if `feature_id` is present, or appends an orphan link proposal
|
|
493
570
|
to the run report if absent (task 0328 / ADR-0322).
|
|
494
571
|
onEnter:
|
|
495
|
-
# Proof-state compare (task 0612, ADR-071
|
|
496
|
-
#
|
|
497
|
-
#
|
|
498
|
-
#
|
|
572
|
+
# Proof-state compare (task 0612, ADR-071; bracket closed against the pre-chain
|
|
573
|
+
# capture per task 0703) — FIRST action in the state, before any record write.
|
|
574
|
+
# Re-captures the digest and asserts it equals the value the evidence chain started
|
|
575
|
+
# from. A mismatch means a proof input changed after evidence was established; the
|
|
576
|
+
# default `fail` policy halts the sequence and routes the run to `failed` rather
|
|
577
|
+
# than crossing into `record`. Task-spec evidence writes (Testing/Review/Solution,
|
|
578
|
+
# R6) happen only in the actions AFTER this comparison, and the fingerprint scopes
|
|
579
|
+
# task content to the proof-input sections, so they cannot invalidate the certified
|
|
580
|
+
# input set.
|
|
499
581
|
- kind: proof.fingerprint
|
|
500
582
|
options:
|
|
501
583
|
var: proofDigestNow
|
|
@@ -573,10 +655,17 @@ states:
|
|
|
573
655
|
- kind: note
|
|
574
656
|
options:
|
|
575
657
|
message: "Pipeline complete for task ${vars.wbs} (done gate cleared)."
|
|
576
|
-
# Checkpoint write: record session state for resume (
|
|
658
|
+
# Checkpoint write: record session state for resume (0711 R1–R3) —
|
|
659
|
+
# canonical frontmatter contract; mirrors the Session Checkpoint
|
|
660
|
+
# Convention in plugins/sp/skills/spur-dev/references/cross-cutting.md.
|
|
661
|
+
# Advisory only: the task file and the persisted run row stay authoritative.
|
|
577
662
|
- kind: shell
|
|
578
663
|
options:
|
|
579
|
-
|
|
664
|
+
# Single logical line: the composition-baseline argument-split lint flags any
|
|
665
|
+
# command whose continuation lines look like argument lists (heredocs with
|
|
666
|
+
# `- item` entries trip it), so the checkpoint body is one printf with \n escapes.
|
|
667
|
+
command: >-
|
|
668
|
+
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
669
|
|
|
581
670
|
- id: failed
|
|
582
671
|
description: >
|
|
@@ -587,17 +676,17 @@ states:
|
|
|
587
676
|
description: Terminal — pipeline cancelled by operator at the approval gate (R1).
|
|
588
677
|
|
|
589
678
|
transitions:
|
|
590
|
-
# ── precheck:
|
|
679
|
+
# ── precheck: size PASS + task check → implement; else → failed ──
|
|
591
680
|
- from: precheck
|
|
592
681
|
to: implement
|
|
593
|
-
description:
|
|
682
|
+
description: Deterministic size and task checks are green — begin implementation.
|
|
594
683
|
guard:
|
|
595
684
|
kind: shell
|
|
596
685
|
options:
|
|
597
|
-
command: 'test "$(cat .spur/run/$wbs-precheck-
|
|
686
|
+
command: 'test "$(cat .spur/run/$wbs-precheck-size.status 2>/dev/null)" = PASS && $spurBin task check $wbs'
|
|
598
687
|
- from: precheck
|
|
599
688
|
to: failed
|
|
600
|
-
description:
|
|
689
|
+
description: Size and/or task check failed — stop before implement.
|
|
601
690
|
guard:
|
|
602
691
|
kind: always
|
|
603
692
|
|
|
@@ -707,39 +796,62 @@ transitions:
|
|
|
707
796
|
command: 'test "$__hitlAnswer" = cancel'
|
|
708
797
|
|
|
709
798
|
# ── 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
|
-
#
|
|
799
|
+
# The verify step emits .spur/run/<wbs>-verdict.json with a required proof block (task 0703 R3/R5).
|
|
800
|
+
# Only `verdict: PASS` PLUS a proof block whose digest — top level and every named stage — equals
|
|
801
|
+
# the captured `proofDigest` clears the gate to `record`; any non-PASS, a missing file, malformed
|
|
802
|
+
# JSON, or missing/mismatched proof evidence does not. Declaration order: PASS+proof guard FIRST,
|
|
803
|
+
# then the bounded remediation route (R4), then the always catch-all so a PASS verdict with a
|
|
804
|
+
# missing/malformed proof block still terminates at `failed` instead of hanging the state.
|
|
713
805
|
- from: verify
|
|
714
806
|
to: record
|
|
715
|
-
description: Verification verdict is PASS — record results and proceed to done.
|
|
807
|
+
description: Verification verdict is PASS and its proof block names the captured digest on every stage — record results and proceed to done.
|
|
716
808
|
guard:
|
|
717
809
|
kind: shell
|
|
718
810
|
options:
|
|
719
|
-
command:
|
|
811
|
+
command: >-
|
|
812
|
+
V=".spur/run/$wbs-verdict.json";
|
|
813
|
+
test "$(jq -r .verdict "$V" 2>/dev/null)" = PASS &&
|
|
814
|
+
test "$(jq -r '.proof.digest // ""' "$V" 2>/dev/null)" = "$proofDigest" &&
|
|
815
|
+
test "$(jq -r '.proof.stages.qualityGate.digest // ""' "$V" 2>/dev/null)" = "$proofDigest" &&
|
|
816
|
+
test "$(jq -r '.proof.stages.review.digest // ""' "$V" 2>/dev/null)" = "$proofDigest" &&
|
|
817
|
+
test "$(jq -r '.proof.stages.verification.digest // ""' "$V" 2>/dev/null)" = "$proofDigest"
|
|
720
818
|
- from: verify
|
|
721
|
-
to:
|
|
722
|
-
description:
|
|
819
|
+
to: test-fix
|
|
820
|
+
description: >-
|
|
821
|
+
Verification returned a repairable non-PASS and the shared fix budget is not exhausted —
|
|
822
|
+
bounded remediation hop (task 0703 R4); the chain re-enters quality → review → verify on a
|
|
823
|
+
freshly captured digest. Never reached on PASS: remediation cannot follow certification.
|
|
723
824
|
guard:
|
|
724
825
|
kind: shell
|
|
725
826
|
options:
|
|
726
|
-
command:
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
827
|
+
command: >-
|
|
828
|
+
V="$(jq -r .verdict .spur/run/$wbs-verdict.json 2>/dev/null)";
|
|
829
|
+
test -n "$V" && test "$V" != PASS &&
|
|
830
|
+
test "$(cat .spur/run/$wbs-test-fix-attempt 2>/dev/null || echo 0)" -lt "$qualityGateMaxFixAttempts"
|
|
831
|
+
- from: verify
|
|
832
|
+
to: failed
|
|
833
|
+
description: >-
|
|
834
|
+
Non-PASS with the fix budget exhausted, or a PASS/missing/malformed verdict whose proof
|
|
835
|
+
block is absent or mismatched (task 0703 R5) — block before done; defense catch-all so the
|
|
836
|
+
state always has a viable outgoing edge.
|
|
837
|
+
guard:
|
|
838
|
+
kind: always
|
|
839
|
+
# ── done gate: record → done/failed gated on `spur task check` (ADR-026 amendment 2026-06-23)
|
|
840
|
+
# PLUS the proof-block re-assertion (task 0703 R5): the verdict artifact must still be PASS and
|
|
841
|
+
# still name the captured digest — a forged or mutated completion artifact fails closed here.
|
|
731
842
|
# Declaration order: pass guard first.
|
|
732
843
|
- from: record
|
|
733
844
|
to: done
|
|
734
|
-
description: Task check passed — certify done.
|
|
845
|
+
description: Task check passed and the verdict proof block still names the captured digest — certify done.
|
|
735
846
|
guard:
|
|
736
847
|
kind: shell
|
|
737
848
|
options:
|
|
738
|
-
command:
|
|
849
|
+
command: >-
|
|
850
|
+
$spurBin task check $wbs &&
|
|
851
|
+
test "$(jq -r .verdict .spur/run/$wbs-verdict.json 2>/dev/null)" = PASS &&
|
|
852
|
+
test "$(jq -r '.proof.digest // ""' .spur/run/$wbs-verdict.json 2>/dev/null)" = "$proofDigest"
|
|
739
853
|
- from: record
|
|
740
854
|
to: failed
|
|
741
|
-
description: Task check failed — block before done
|
|
855
|
+
description: Task check failed or proof evidence missing/malformed/mismatched — block before done.
|
|
742
856
|
guard:
|
|
743
|
-
kind:
|
|
744
|
-
options:
|
|
745
|
-
command: "! $spurBin task check $wbs"
|
|
857
|
+
kind: always
|
|
@@ -49,7 +49,7 @@ vars:
|
|
|
49
49
|
profile: "standard"
|
|
50
50
|
merge: "false"
|
|
51
51
|
spurBin: "spur"
|
|
52
|
-
agent: "
|
|
52
|
+
agent: "auto"
|
|
53
53
|
stepTimeoutMs: "1800000"
|
|
54
54
|
# Corpus-aware quality gate for the feature-transition hop (R1, task 0625).
|
|
55
55
|
# The per-task gate (`spur-check`) deliberately excludes corpus-check — the only
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/spur",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.69",
|
|
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",
|