@gobing-ai/spur 0.3.90 → 0.3.92
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/pipeline-budgets.json +9 -2
- package/config/plugin-scripts.json +17 -1
- package/config/workflows/decision-routing-example.yaml +134 -0
- package/config/workflows/feature-lifecycle.yaml +14 -5
- package/config/workflows/feature-verification.yaml +35 -27
- package/config/workflows/history-anatomy.yaml +14 -25
- package/config/workflows/idea-pipeline.yaml +17 -5
- package/config/workflows/task-pipeline.yaml +187 -4
- package/config/workflows/wayfinder-resolution.yaml +2 -0
- package/config/workflows/wrapup-pipeline.yaml +49 -5
- package/package.json +9 -9
- package/plugins/sp/README.md +1 -0
- package/plugins/sp/agents/expert-spur.md +2 -2
- package/plugins/sp/agents/super-planner.md +14 -5
- package/plugins/sp/commands/dev-dogfood.md +4 -4
- package/plugins/sp/commands/dev-fixall.md +8 -5
- package/plugins/sp/commands/dev-run.md +6 -0
- package/plugins/sp/commands/dev-runall.md +12 -6
- package/plugins/sp/commands/dev-verify.md +9 -0
- package/plugins/sp/commands/dev-verifyall.md +5 -0
- package/plugins/sp/lib/idea-handoff.generated.mjs +301 -300
- package/plugins/sp/lib/inline-run.generated.d.mts +17 -0
- package/plugins/sp/lib/inline-run.generated.mjs +1460 -0
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/references/environment-lens.md +1 -1
- package/plugins/sp/scripts/dogfood-testing/validate-report.mjs +136 -0
- package/plugins/sp/scripts/dogfood-testing/validate-report.ts +196 -2
- package/plugins/sp/scripts/feature-verification-steps.mjs +174 -0
- package/plugins/sp/scripts/feature-verification-steps.ts +275 -0
- package/plugins/sp/scripts/history-anatomy-cache.mjs +104 -4
- package/plugins/sp/scripts/history-anatomy-cache.ts +137 -13
- package/plugins/sp/scripts/inline-pipeline-parity-check.ts +2 -0
- package/plugins/sp/scripts/inline-run-setup.mjs +349 -0
- package/plugins/sp/scripts/inline-run-setup.ts +192 -75
- package/plugins/sp/scripts/record-feature-sync.mjs +63 -0
- package/plugins/sp/scripts/record-feature-sync.ts +84 -0
- package/plugins/sp/scripts/residual-scan.mjs +476 -0
- package/plugins/sp/scripts/residual-scan.ts +614 -0
- package/plugins/sp/scripts/surface-drift-inventory.ts +71 -6
- package/plugins/sp/scripts/task-evidence-precheck.ts +8 -3
- package/plugins/sp/scripts/task-size-precheck.ts +8 -3
- package/plugins/sp/scripts/validate-flag-contracts.ts +3 -3
- package/plugins/sp/skills/branch-workflow/SKILL.md +1 -0
- package/plugins/sp/skills/branch-workflow/references/worktree-patterns.md +2 -0
- package/plugins/sp/skills/code-implementation/SKILL.md +17 -0
- package/plugins/sp/skills/code-verification/SKILL.md +21 -0
- package/plugins/sp/skills/code-verification/references/verdict-schema.md +1 -0
- package/plugins/sp/skills/dogfood-testing/SKILL.md +5 -3
- package/plugins/sp/skills/dogfood-testing/references/monitor-ledger.md +63 -26
- package/plugins/sp/skills/dogfood-testing/references/report-template.md +33 -10
- package/plugins/sp/skills/history-anatomy/references/modes.md +5 -3
- package/plugins/sp/skills/next-feature/references/ranking-rubric.md +1 -1
- package/plugins/sp/skills/next-router/references/routing-table.md +7 -0
- package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +1 -1
- package/plugins/sp/skills/session-review/SKILL.md +12 -2
- package/plugins/sp/skills/spur-cli/references/agent.md +11 -2
- package/plugins/sp/skills/spur-cli/references/features.md +1 -1
- package/plugins/sp/skills/spur-cli/references/projects.md +3 -1
- package/plugins/sp/skills/spur-cli/references/self.md +5 -1
- package/plugins/sp/skills/spur-cli/references/workflows.md +42 -20
- package/plugins/sp/skills/spur-dev/SKILL.md +11 -4
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +25 -3
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +2 -2
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +285 -57
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +14 -5
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +19 -4
- package/plugins/sp/skills/spur-dev/references/glossary.md +9 -1
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +51 -16
- package/plugins/sp/skills/spur-dev/references/planning-workflow.md +5 -0
- package/plugins/sp/skills/wayfinder/SKILL.md +1 -1
- package/spur.js +23422 -19364
- package/web/_astro/BoardApp.CerSBgis.js +192 -0
- package/web/_astro/BoardApp.eoTz0pZs.js +1 -0
- package/web/_astro/{TaskDetail.DwTmbQp5.js → TaskDetail.DCqiC-OZ.js} +1 -1
- package/web/_astro/arc.CPwg6Rw0.js +1 -0
- package/web/_astro/{architectureDiagram-3BPJPVTR.jvdDahWM.js → architectureDiagram-3BPJPVTR.DM_vp_hO.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.zSg4AmFD.js → blockDiagram-GPEHLZMM.DXVIiv0p.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.BkUIUQWH.js → c4Diagram-AAUBKEIU.BbF_zCxW.js} +1 -1
- package/web/_astro/channel.MYZLKNwy.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.DvfQ_f50.js → chunk-2J33WTMH.CAgQHpPC.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.DuI4gQqX.js → chunk-4BX2VUAB.BN-5tpw4.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.D3BWBOpF.js → chunk-55IACEB6.CnPkEEr0.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.3QSi0a9M.js → chunk-727SXJPM.BQzQeMVm.js} +4 -4
- package/web/_astro/{chunk-AQP2D5EJ.xazCQrAF.js → chunk-AQP2D5EJ.B6xNyDnL.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.B2g6u4rA.js → chunk-FMBD7UC4.C7f9Ih78.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.wWwWs99t.js → chunk-ND2GUHAM.CNV1dFXT.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.BD5g3qa9.js → chunk-QZHKN3VN.Cudn2TkJ.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.C7CzCdsX.js → classDiagram-4FO5ZUOK.D1NwP50q.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.C7CzCdsX.js → classDiagram-v2-Q7XG4LA2.D1NwP50q.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.Xyiau0gw.js → cose-bilkent-S5V4N54A.B1wSL-Xb.js} +1 -1
- package/web/_astro/{cynefin-OW5HDTMX.BeC5MWas.js → cynefin-OW5HDTMX.BmK52w8G.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.yZbMN9vc.js → dagre-BM42HDAG.Bfy5CTDT.js} +2 -2
- package/web/_astro/diagram-2AECGRRQ.DhNnvUvX.js +43 -0
- package/web/_astro/diagram-5GNKFQAL.lTX5KwnS.js +10 -0
- package/web/_astro/{diagram-KO2AKTUF.CR6k3Y3G.js → diagram-KO2AKTUF.CW_vMJ4z.js} +3 -3
- package/web/_astro/{diagram-LMA3HP47.x7mwu8jz.js → diagram-LMA3HP47.B_8ZGF67.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.D8aTTvUr.js → diagram-OG6HWLK6.BppnHsdS.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.BoBqcKXQ.js → erDiagram-TEJ5UH35.BEuHXcjJ.js} +5 -5
- package/web/_astro/{flowDiagram-I6XJVG4X.D3mTQdrU.js → flowDiagram-I6XJVG4X.CH-UlnGr.js} +4 -4
- package/web/_astro/{ganttDiagram-6RSMTGT7.H-cqgIh-.js → ganttDiagram-6RSMTGT7.BO81S85v.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.B6s9zbfC.js → gitGraphDiagram-PVQCEYII.XnPxPPZN.js} +1 -1
- package/web/_astro/index.Hjbr15fG.css +1 -0
- package/web/_astro/{infoDiagram-5YYISTIA.BzgCoV6P.js → infoDiagram-5YYISTIA.JyjYRu_T.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.BZzVhy1-.js → ishikawaDiagram-YF4QCWOH.BBRBF-Fo.js} +5 -5
- package/web/_astro/{journeyDiagram-JHISSGLW.BV3195Py.js → journeyDiagram-JHISSGLW.C_iymSyp.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.BjRd2DWz.js → kanban-definition-UN3LZRKU.DdfW-Oqt.js} +7 -7
- package/web/_astro/{linear.BILTgS5N.js → linear.C2_IkbZT.js} +1 -1
- package/web/_astro/mermaid.core.GAOYeSR0.js +303 -0
- package/web/_astro/{mindmap-definition-RKZ34NQL.BiEjaI4-.js → mindmap-definition-RKZ34NQL.DAZIxQSK.js} +2 -2
- package/web/_astro/{pieDiagram-4H26LBE5.i_8V5pIn.js → pieDiagram-4H26LBE5.CN8sIhKM.js} +3 -3
- package/web/_astro/{quadrantDiagram-W4KKPZXB.BWaW3MHn.js → quadrantDiagram-W4KKPZXB.3dGcX5GP.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.CzddBbtg.js → requirementDiagram-4Y6WPE33.BV2y4dd6.js} +3 -3
- package/web/_astro/{sankeyDiagram-5OEKKPKP.X2ww0e-D.js → sankeyDiagram-5OEKKPKP.Cqo15Tvo.js} +4 -4
- package/web/_astro/{sequenceDiagram-3UESZ5HK.DSA4kTcc.js → sequenceDiagram-3UESZ5HK.CROCPMJB.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.D0DtFSpR.js → stateDiagram-AJRCARHV.RfXZrkFE.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.BfQq0zQv.js → stateDiagram-v2-BHNVJYJU.CPXmbBs9.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.Dmlrgi1m.js → timeline-definition-PNZ67QCA.DdgKTiO8.js} +3 -3
- package/web/_astro/{vennDiagram-CIIHVFJN.D5mpl00Z.js → vennDiagram-CIIHVFJN.CPNVSHF1.js} +5 -5
- package/web/_astro/{wardleyDiagram-YWT4CUSO.Df4BdzO4.js → wardleyDiagram-YWT4CUSO.CQhA0Jyr.js} +3 -3
- package/web/_astro/{xychartDiagram-2RQKCTM6.DiTRreKN.js → xychartDiagram-2RQKCTM6.n61BWyy4.js} +1 -1
- package/web/index.html +2 -2
- package/web/_astro/BoardApp.CDUcHlTJ.js +0 -188
- package/web/_astro/BoardApp.CaCGU_uX.js +0 -1
- package/web/_astro/arc.BzF71EFI.js +0 -1
- package/web/_astro/channel.SSVY0JPQ.js +0 -1
- package/web/_astro/diagram-2AECGRRQ.Cmo2zQM-.js +0 -43
- package/web/_astro/diagram-5GNKFQAL.D033eSVi.js +0 -10
- package/web/_astro/index.CcU5weKX.css +0 -1
- package/web/_astro/mermaid.core.DBy_WKeW.js +0 -301
|
@@ -6,13 +6,18 @@
|
|
|
6
6
|
# through the normal `spur task update <wbs> <status>` verb so the lifecycle guards
|
|
7
7
|
# (0055) apply identically. Run linkage is written to `task_run_links` (kind=pipeline).
|
|
8
8
|
#
|
|
9
|
-
# Shape: precheck → implement → test[→test-fix↔test-recheck] → review → approve(HITL)
|
|
9
|
+
# Shape: precheck → implement[→escalate] → test[→test-fix↔test-recheck] → review → approve(HITL)
|
|
10
10
|
# → verify → record → done
|
|
11
11
|
# (precheck failure short-circuits to `failed`; approve routes to `failed` on
|
|
12
12
|
# operator rejection or `cancelled` on operator cancel — R1, bug-750).
|
|
13
13
|
# `test` is the project quality gate (shell + bounded /sp:dev-fixall), not
|
|
14
14
|
# /sp:dev-unit (coverage gap-fill; router C3/C5).
|
|
15
15
|
#
|
|
16
|
+
# F96 residual sweep (0950): precheck captures the resume-safe base commit; verify
|
|
17
|
+
# scans and folds residuals between the verdict and the proof bind (blocking leftovers
|
|
18
|
+
# downgrade PASS → PARTIAL and take the existing remediation edge); done settles
|
|
19
|
+
# deferrals; failed renders the recovery report. No new state, edge, or model query.
|
|
20
|
+
#
|
|
16
21
|
# Vars (passed as a JSON object via `--vars`):
|
|
17
22
|
# wbs — task WBS (required)
|
|
18
23
|
# profile — "auto" skips HITL approve (R4)
|
|
@@ -21,6 +26,7 @@
|
|
|
21
26
|
# implementTimeoutMs — implement agent.run budget (ms)
|
|
22
27
|
# qualityGateCmd — project gate (default: bun run spur-check)
|
|
23
28
|
# qualityGateMaxFixAttempts — max /sp:dev-fixall hops after a red gate (default: 2)
|
|
29
|
+
# maxEscalations — max operator-question pauses per implement chain (default: 2)
|
|
24
30
|
#
|
|
25
31
|
# Seeded by `spur init`. agent.run inputs are pure slash commands (ADR-043).
|
|
26
32
|
|
|
@@ -90,6 +96,10 @@ vars:
|
|
|
90
96
|
# Answer captured by the approve gate's hitl.confirm (R1): "yes" | "no" | "cancel".
|
|
91
97
|
# Empty by default; only meaningful once the approve state has been entered.
|
|
92
98
|
__hitlAnswer: ""
|
|
99
|
+
# Operator answer captured by the escalate hop's hitl.input (0933). Empty by
|
|
100
|
+
# default; set by `spur workflow continue --answer-text` after the pause and read
|
|
101
|
+
# by the escalate→implement / escalate→failed guards. Non-empty = answered.
|
|
102
|
+
__hitlInput: ""
|
|
93
103
|
# Proof-state bracket (task 0612, ADR-071; restructured by task 0703). `proofDigest` is the
|
|
94
104
|
# canonical capture taken at quality-gate ENTRY — immediately before the evidence-producing
|
|
95
105
|
# final chain (quality → review → verify) — and re-captured at `test-recheck` when bounded
|
|
@@ -134,6 +144,14 @@ vars:
|
|
|
134
144
|
# Max /sp:dev-fixall attempts after a red quality-gate probe/recheck (bounded; no thrash).
|
|
135
145
|
# Attempt counter: .spur/run/<wbs>-test-fix-attempt. Default 2 = two fixall hops before failed.
|
|
136
146
|
qualityGateMaxFixAttempts: "2"
|
|
147
|
+
# Max operator-question pauses (0933) before the implement chain routes to failed.
|
|
148
|
+
# Escalation counter: .spur/run/<wbs>-escalation-count. Default 2 = two answered
|
|
149
|
+
# questions; a third pause routes to failed with a report note.
|
|
150
|
+
maxEscalations: "2"
|
|
151
|
+
# Runtime-written, 0933: the escalate hop's file.read.into-var fills this from
|
|
152
|
+
# .spur/run/<wbs>-question.md; the hitl.input prompt below references it. Declared
|
|
153
|
+
# here (empty) so the static var-reference validator sees the template source.
|
|
154
|
+
escalationQuestion: ""
|
|
137
155
|
# Post-implement auto-format. Overridable like qualityGateCmd so a non-Bun seeded
|
|
138
156
|
# project can point it at its own formatter; invoked best-effort (a missing or
|
|
139
157
|
# failing formatter must never abort a run — the quality gate is the real gate).
|
|
@@ -156,6 +174,12 @@ vars:
|
|
|
156
174
|
# (default) = on; set to "off" to bypass:
|
|
157
175
|
# `--vars '{"implementScopeGuard":"off"}'`.
|
|
158
176
|
implementScopeGuard: ""
|
|
177
|
+
# 0931 R5: parallel batches defer the per-task feature sync so a task branch never
|
|
178
|
+
# touches feature files or docs/features/INDEX.md. When "true", the record step's
|
|
179
|
+
# post-record shell appends a deferral note and skips the sync; the parallel batch
|
|
180
|
+
# orchestrator runs the sync + `spur feature refresh` once per touched feature on the
|
|
181
|
+
# base ref after integration. Sequential/inline keep the default "false" (unchanged).
|
|
182
|
+
deferFeatureSync: "false"
|
|
159
183
|
|
|
160
184
|
states:
|
|
161
185
|
- id: precheck
|
|
@@ -189,6 +213,12 @@ states:
|
|
|
189
213
|
options:
|
|
190
214
|
command: >-
|
|
191
215
|
mkdir -p .spur/run; S=plugins/sp/scripts/task-evidence-precheck.ts; [ -f "$S" ] || S="$(superskill script path sp task-evidence-precheck.ts 2>/dev/null)"; if [ -f "$S" ]; then bun "$S" "$wbs" --spur-bin "$spurBin"; else echo "task-evidence-precheck failed closed — checker not found in plugins/sp/scripts/ nor staged — run 'superskill install sp'." >&2; echo "FAIL" > ".spur/run/$wbs-precheck-evidence.status"; fi; exit 0
|
|
216
|
+
# (e) F96 R1 (0950): capture the run's base commit once — a resumed or re-entered run
|
|
217
|
+
# keeps its original base so residual scans stay anchored to the same diff.
|
|
218
|
+
- kind: shell
|
|
219
|
+
options:
|
|
220
|
+
command: >-
|
|
221
|
+
mkdir -p .spur/run; [ -f ".spur/run/$wbs-base.sha" ] || git rev-parse HEAD > ".spur/run/$wbs-base.sha"; exit 0
|
|
192
222
|
# (e) route-reason lookup and routes log; proportional-routing tests locate it
|
|
193
223
|
# (0759 R1/R5 run-scoped artifact; 0804 R8 run-id safety — one line, no in-scalar `#`).
|
|
194
224
|
- kind: shell
|
|
@@ -222,6 +252,20 @@ states:
|
|
|
222
252
|
that command DRIVES this pipeline, so calling it here recurses.
|
|
223
253
|
--mode implement is the single-step implement entry.
|
|
224
254
|
onEnter:
|
|
255
|
+
# 0933 R27 (guard-lines compression): the transcript append lives HERE, on
|
|
256
|
+
# (re-)entry, not in the escalate→implement guard. On first entry there is no
|
|
257
|
+
# pending question (no-op); on a resume entry the guard already confirmed a
|
|
258
|
+
# non-empty $__hitlInput and a fresh question file, so this shell records the
|
|
259
|
+
# Q/A pair (## Q<n>/## A<n>, R3) and consumes the question file before the
|
|
260
|
+
# agent.run re-dispatches — which also disarms the implement→escalate edge.
|
|
261
|
+
- kind: shell
|
|
262
|
+
options:
|
|
263
|
+
command: >-
|
|
264
|
+
test -n "$__hitlInput" -a -s .spur/run/$wbs-question.md || exit 0;
|
|
265
|
+
qn="$(cat .spur/run/$wbs-escalation-count 2>/dev/null || echo 0)";
|
|
266
|
+
printf '## Q%s\n%s\n\n## A%s\n%s\n' "$qn" "$(cat .spur/run/$wbs-question.md 2>/dev/null)" "$qn" "$__hitlInput" >> .spur/run/$wbs-escalation.md;
|
|
267
|
+
rm -f .spur/run/$wbs-question.md;
|
|
268
|
+
exit 0
|
|
225
269
|
- kind: agent.run
|
|
226
270
|
options:
|
|
227
271
|
agent: ${vars.implementAgent}
|
|
@@ -232,13 +276,23 @@ states:
|
|
|
232
276
|
# resumes the implement session instead of re-reading the task cold.
|
|
233
277
|
session: reuse
|
|
234
278
|
# lives in /sp:dev-run --mode implement → sp:code-implementation, not YAML prose.
|
|
235
|
-
|
|
279
|
+
# 0933 R28: --escalation-file names the Q/A transcript the implement
|
|
280
|
+
# agent appends to when pausing and reads back on re-dispatch; absent
|
|
281
|
+
# on a first attempt means "no prior escalations".
|
|
282
|
+
input: /sp:dev-run --mode implement ${vars.wbs} --auto --escalation-file .spur/run/${vars.wbs}-escalation.md
|
|
236
283
|
timeoutMs: ${vars.implementTimeoutMs}
|
|
237
284
|
# R3 (task 0424): empty-implement no-op guard — the agent.run action
|
|
238
285
|
# fails the step when exit 0 produced zero non-corpus file changes, so
|
|
239
286
|
# a silent no-op routes the run to `failed` here instead of drifting
|
|
240
287
|
# into test/review and being caught a full pass later.
|
|
241
288
|
requireDiff: true
|
|
289
|
+
# 0933 R26: escalation contract — the agent.run option names the QUESTION
|
|
290
|
+
# file (the pause signal, deleted pre-dispatch for freshness); a paused
|
|
291
|
+
# attempt (agent wrote its question there and exited 0) succeeds with
|
|
292
|
+
# data.escalated=true and skips requireDiff for THAT attempt only. The
|
|
293
|
+
# Q/A transcript (.spur/run/<wbs>-escalation.md) is separate: it reaches
|
|
294
|
+
# the agent via --escalation-file in the input below.
|
|
295
|
+
escalationFile: .spur/run/${vars.wbs}-question.md
|
|
242
296
|
# 0706 R6: this stage mutates the working tree unattended under the
|
|
243
297
|
# auto profile, so it declares minimum execution-capability
|
|
244
298
|
# requirements. Dispatch fails closed (before spawn) when the
|
|
@@ -273,6 +327,39 @@ states:
|
|
|
273
327
|
options:
|
|
274
328
|
command: "$formatCmd ; exit 0"
|
|
275
329
|
|
|
330
|
+
# ── escalate hop (operator-question pause, 0933) ──────────────────────────
|
|
331
|
+
# The implement agent paused on an operator question: it wrote
|
|
332
|
+
# .spur/run/<wbs>-question.md and exited 0 (agent.run reported
|
|
333
|
+
# data.escalated=true, skipping requireDiff for that attempt). This hop bounds
|
|
334
|
+
# the asks (counter), surfaces the question verbatim through the HITL responder
|
|
335
|
+
# (the run pauses here), and — after `spur workflow continue --answer-text <a>`
|
|
336
|
+
# delivers __hitlInput — resumes implement with the Q/A transcript
|
|
337
|
+
# (.spur/run/<wbs>-escalation.md) named in the implement input via
|
|
338
|
+
# --escalation-file. The transcript append + question-file consumption happen in
|
|
339
|
+
# the escalate→implement guard so a stale question can never re-trigger the hop
|
|
340
|
+
# after the answered attempt.
|
|
341
|
+
- id: escalate
|
|
342
|
+
description: >-
|
|
343
|
+
Operator-question pause (0933): the implement agent asked a question
|
|
344
|
+
headlessly; surface it to the operator and resume implement with the answer.
|
|
345
|
+
onEnter:
|
|
346
|
+
# Bounded asks: increment the per-task escalation counter before pausing.
|
|
347
|
+
- kind: shell
|
|
348
|
+
options:
|
|
349
|
+
command: >-
|
|
350
|
+
mkdir -p .spur/run; n="$(cat .spur/run/$wbs-escalation-count 2>/dev/null || echo 0)"; echo $((n + 1)) > .spur/run/$wbs-escalation-count; exit 0
|
|
351
|
+
# The agent's question, verbatim, becomes the pause prompt.
|
|
352
|
+
- kind: file.read.into-var
|
|
353
|
+
options:
|
|
354
|
+
file: .spur/run/${vars.wbs}-question.md
|
|
355
|
+
var: escalationQuestion
|
|
356
|
+
# Pause for the operator (responder pause:true stops the run after this
|
|
357
|
+
# onEnter; `spur workflow continue --answer-text <answer>` writes
|
|
358
|
+
# __hitlInput and re-evaluates the escalate guards).
|
|
359
|
+
- kind: hitl.input
|
|
360
|
+
options:
|
|
361
|
+
prompt: "${vars.escalationQuestion}"
|
|
362
|
+
|
|
276
363
|
# ── test hop (quality gate + bounded auto-fix) ─────────────────────────────
|
|
277
364
|
# NOT /sp:dev-unit. That command (sp:code-testing) *extends/generates* tests toward
|
|
278
365
|
# a coverage target; it is not the project quality gate. Coverage gap-fill remains
|
|
@@ -358,6 +445,14 @@ states:
|
|
|
358
445
|
options:
|
|
359
446
|
command: >-
|
|
360
447
|
mkdir -p .spur/run; A=".spur/run/$wbs-test-fix-attempt"; n=$(cat "$A" 2>/dev/null || echo 0); printf '%s\n' "$((n + 1))" > "$A"; [ ! -f ".spur/run/$wbs-verdict.json" ] || { echo '--- verify verdict (remediation input, task 0703 R4) ---'; cat ".spur/run/$wbs-verdict.json"; } >> ".spur/run/$wbs-test-gate.log"; exit 0
|
|
448
|
+
# (d) F96 R3 (0950): hand the residual list to the remediation loop — dev-fixall
|
|
449
|
+
# treats residual items as fix targets and may defer P3/markers to
|
|
450
|
+
# residual-deferrals.json (see dev-fixall.md). Fold already merged the anchors
|
|
451
|
+
# into <wbs>-test-gate.findings; this carries the structured artifact too.
|
|
452
|
+
- kind: shell
|
|
453
|
+
options:
|
|
454
|
+
command: >-
|
|
455
|
+
[ ! -f ".spur/run/$wbs-residuals.json" ] || { echo '--- residual artifact (F96 fix targets; deferrals go to residual-deferrals.json, P3/markers only) ---'; cat ".spur/run/$wbs-residuals.json"; } >> ".spur/run/$wbs-test-gate.log"; exit 0
|
|
361
456
|
# R3 (0482): project the extracted gate anchors into a var so the dispatch input
|
|
362
457
|
# can NAME the failing file:line, not merely point at a log. A vars template cannot
|
|
363
458
|
# run a shell, so the read is an action, not an inline `$(cat ...)` substitution.
|
|
@@ -464,6 +559,8 @@ states:
|
|
|
464
559
|
- kind: hitl.confirm
|
|
465
560
|
options:
|
|
466
561
|
prompt: "Approve task ${vars.wbs} to proceed to verification?"
|
|
562
|
+
decision:
|
|
563
|
+
mode: never
|
|
467
564
|
|
|
468
565
|
- id: verify
|
|
469
566
|
description: >
|
|
@@ -528,6 +625,16 @@ states:
|
|
|
528
625
|
- kind: shell
|
|
529
626
|
options:
|
|
530
627
|
command: "$spurBin task verdict $wbs --from-answer .spur/run/$wbs-verify-answer.txt"
|
|
628
|
+
# (d) F96 R2 (0950): residual-scan.ts owns the sweep; shell only resolves it.
|
|
629
|
+
# ONE hard action (scan+fold): a scanner crash fails verify closed — the
|
|
630
|
+
# verify→failed catch-all routes a missing/malformed verdict. Runs AFTER
|
|
631
|
+
# `task verdict` and BEFORE the jq bind so a blocking residual turns PASS
|
|
632
|
+
# into PARTIAL (fold rewrites the verdict artifact) and takes the existing
|
|
633
|
+
# verify→test-fix edge while attempts remain.
|
|
634
|
+
- kind: shell
|
|
635
|
+
options:
|
|
636
|
+
command: >-
|
|
637
|
+
S=plugins/sp/scripts/residual-scan.ts; [ -f "$S" ] || S="$(superskill script path sp residual-scan.mjs 2>/dev/null)"; if [ ! -f "$S" ]; then echo "residual-scan failed closed — scanner not found in plugins/sp/scripts/ nor staged — run 'superskill install sp'" >&2; exit 1; fi; case "$S" in *.mjs) RUNNER=node ;; *) RUNNER=bun ;; esac; "$RUNNER" "$S" scan "$wbs" --spur-bin "$spurBin" && "$RUNNER" "$S" fold "$wbs" --spur-bin "$spurBin"
|
|
531
638
|
# (e) one jq mutation binds the verdict to the proof digest (0703 R3; runId 0730 §B.2 /
|
|
532
639
|
# 0757 R4; definitionDigest 0759 R5; honest review stamp 0785 R4; soft action + hard guard).
|
|
533
640
|
- kind: shell
|
|
@@ -582,10 +689,16 @@ states:
|
|
|
582
689
|
# (d) feature-sync-bounded.ts owns the sync; shell adds the orphan note and fallbacks
|
|
583
690
|
# (0411 retry-suppression; 0328 / ADR-0322). Best-effort `exit 0` — feature status sync is a
|
|
584
691
|
# follow-up, not a completion gate; `record → done` runs `spur task check`.
|
|
692
|
+
# 0931 R5: with deferFeatureSync "true" (parallel mode) the deferral note lands in the
|
|
693
|
+
# task report and the sync is skipped entirely, so task branches never touch feature
|
|
694
|
+
# corpus files; the batch orchestrator performs the deferred sync on the base ref.
|
|
695
|
+
# The sync itself is owned by record-feature-sync.ts (ADR-115: the guard plus the old
|
|
696
|
+
# inline chain cannot share one shell); resolution follows the standard in-repo-first,
|
|
697
|
+
# superskill-staged fallback used by every pipeline checker.
|
|
585
698
|
- kind: shell
|
|
586
699
|
options:
|
|
587
700
|
command: >-
|
|
588
|
-
|
|
701
|
+
S=plugins/sp/scripts/record-feature-sync.ts; [ -f "$S" ] || S="$(superskill script path sp record-feature-sync.mjs 2>/dev/null)"; [ "$deferFeatureSync" = "true" ] && echo "feature sync deferred to batch integration" >> ".spur/run/$wbs-report.txt" || if [ -f "$S" ]; then bun "$S" --spur-bin "$spurBin"; else echo "feature sync skipped — record-feature-sync not found in plugins/sp/scripts/ nor staged" >> ".spur/run/$wbs-report.txt"; fi; exit 0
|
|
589
702
|
|
|
590
703
|
- id: done
|
|
591
704
|
description: >
|
|
@@ -593,6 +706,13 @@ states:
|
|
|
593
706
|
guard runs `spur task check` before certifying; a genuinely non-compliant
|
|
594
707
|
task routes to `failed` instead of a silent bad `done`.
|
|
595
708
|
onEnter:
|
|
709
|
+
# (d) F96 R4 (0950): residual-scan.ts owns the settle; shell only resolves it.
|
|
710
|
+
# Soft best-effort (exit 0) — runs after certification and must never change
|
|
711
|
+
# the outcome; failure prints the re-run command.
|
|
712
|
+
- kind: shell
|
|
713
|
+
options:
|
|
714
|
+
command: >-
|
|
715
|
+
S=plugins/sp/scripts/residual-scan.ts; [ -f "$S" ] || S="$(superskill script path sp residual-scan.mjs 2>/dev/null)"; if [ -f "$S" ]; then case "$S" in *.mjs) RUNNER=node ;; *) RUNNER=bun ;; esac; "$RUNNER" "$S" settle "$wbs" --spur-bin "$spurBin" || echo "residual-settle failed — re-run: residual-scan settle $wbs" >&2; else echo "residual-scan not staged — settle skipped — re-run: residual-scan settle $wbs" >&2; fi; exit 0
|
|
596
716
|
# (c) command.gate owns the done transition with classified transient retry.
|
|
597
717
|
- kind: command.gate
|
|
598
718
|
options:
|
|
@@ -618,7 +738,28 @@ states:
|
|
|
618
738
|
- id: failed
|
|
619
739
|
description: >
|
|
620
740
|
Terminal — precheck, quality-gate exhaustion, verify non-PASS, record check
|
|
621
|
-
failure, or operator rejection; reported, not advanced.
|
|
741
|
+
failure, or operator rejection; reported, not advanced. Also receives an
|
|
742
|
+
escalation-bound pause or an operator give-up (0933).
|
|
743
|
+
onEnter:
|
|
744
|
+
# 0933 R30 (guard-lines compression): the escalation-bound report note lives
|
|
745
|
+
# here as a conditional — no-op unless the run reached failed with a pending
|
|
746
|
+
# question at (or above) the ask bound (bound pause or final give-up). The
|
|
747
|
+
# unanswered question itself is appended to the task report (report.txt, R2).
|
|
748
|
+
- kind: shell
|
|
749
|
+
options:
|
|
750
|
+
command: >-
|
|
751
|
+
n="$(cat .spur/run/$wbs-escalation-count 2>/dev/null || echo 0)";
|
|
752
|
+
test "$n" -ge "$maxEscalations" -a -s .spur/run/$wbs-question.md || exit 0;
|
|
753
|
+
printf '\n## Escalation bound reached\n\nThe implement step asked an operator question %s times (bound %s) and ended without a resumable answer. Unanswered question:\n\n' "$n" "$maxEscalations" >> .spur/run/$wbs-report.txt;
|
|
754
|
+
cat .spur/run/$wbs-question.md >> .spur/run/$wbs-report.txt;
|
|
755
|
+
exit 0
|
|
756
|
+
# (d) F96 R5 (0950): residual-scan.ts owns the report; shell only resolves it.
|
|
757
|
+
# Soft (exit 0): a run that exhausts its fix budget on residuals leaves the
|
|
758
|
+
# report + recovery line while the task stays `wip`.
|
|
759
|
+
- kind: shell
|
|
760
|
+
options:
|
|
761
|
+
command: >-
|
|
762
|
+
S=plugins/sp/scripts/residual-scan.ts; [ -f "$S" ] || S="$(superskill script path sp residual-scan.mjs 2>/dev/null)"; if [ -f "$S" ]; then case "$S" in *.mjs) RUNNER=node ;; *) RUNNER=bun ;; esac; "$RUNNER" "$S" report "$wbs" --spur-bin "$spurBin" || echo "residual-report failed — re-run: residual-scan report $wbs" >&2; else echo "residual-scan not staged — report skipped — re-run: residual-scan report $wbs" >&2; fi; exit 0
|
|
622
763
|
|
|
623
764
|
- id: cancelled
|
|
624
765
|
description: Terminal — pipeline cancelled by operator at the approval gate (R1).
|
|
@@ -642,12 +783,54 @@ transitions:
|
|
|
642
783
|
guard:
|
|
643
784
|
kind: always
|
|
644
785
|
|
|
786
|
+
# ── implement routing: escalation first (0933 R26/R30), then the linear body ──
|
|
787
|
+
# Declaration order matters: the escalation bound is checked FIRST — a paused
|
|
788
|
+
# attempt that already exhausted its maxEscalations asks routes to failed (with a
|
|
789
|
+
# report note appended in the same guard) instead of asking forever; then the
|
|
790
|
+
# question-presence hop; then the normal always edge. The bound guard requires a
|
|
791
|
+
# fresh question file so a COMPLETED implement after max asks still routes to test.
|
|
792
|
+
- from: implement
|
|
793
|
+
to: failed
|
|
794
|
+
description: Escalation bound exhausted — the agent paused again after maxEscalations operator answers.
|
|
795
|
+
# 0933 R30 (guard-lines compression): thin predicate; the report note is written
|
|
796
|
+
# by the failed state's onEnter when it observes a bound-exhausted pause.
|
|
797
|
+
guard:
|
|
798
|
+
kind: shell
|
|
799
|
+
options:
|
|
800
|
+
command: >-
|
|
801
|
+
n="$(cat .spur/run/$wbs-escalation-count 2>/dev/null || echo 0)";
|
|
802
|
+
test "$n" -ge "$maxEscalations" -a -s .spur/run/$wbs-question.md
|
|
803
|
+
- from: implement
|
|
804
|
+
to: escalate
|
|
805
|
+
description: Implement agent paused on an operator question (non-empty question file) — pause for an answer.
|
|
806
|
+
guard:
|
|
807
|
+
kind: shell
|
|
808
|
+
options:
|
|
809
|
+
command: 'test -s .spur/run/$wbs-question.md'
|
|
645
810
|
# ── linear body ──
|
|
646
811
|
- from: implement
|
|
647
812
|
to: test
|
|
648
813
|
description: Implementation done — quality-gate probe.
|
|
649
814
|
guard:
|
|
650
815
|
kind: always
|
|
816
|
+
# escalate branching (0933 R27): an answered pause resumes implement — the transcript
|
|
817
|
+
# append and question consumption happen in implement's onEnter (guards stay thin
|
|
818
|
+
# under ADR-115 guard-lines caps); an empty answer is an operator give-up → failed
|
|
819
|
+
# (question + transcript preserved as evidence).
|
|
820
|
+
- from: escalate
|
|
821
|
+
to: implement
|
|
822
|
+
description: Operator answered — re-enter implement, which records the Q/A transcript and consumes the question.
|
|
823
|
+
guard:
|
|
824
|
+
kind: shell
|
|
825
|
+
options:
|
|
826
|
+
command: 'test -n "$__hitlInput"'
|
|
827
|
+
- from: escalate
|
|
828
|
+
to: failed
|
|
829
|
+
description: Empty operator answer — give-up routes to failed (question + transcript preserved as evidence).
|
|
830
|
+
guard:
|
|
831
|
+
kind: shell
|
|
832
|
+
options:
|
|
833
|
+
command: 'test -z "$__hitlInput"'
|
|
651
834
|
# Soft probe branching (declaration order: PASS first, then FAIL, then defense).
|
|
652
835
|
- from: test
|
|
653
836
|
to: verify
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
#
|
|
16
16
|
# Shape: start -> task-resolve -> doc-sync -> learnings-append -> metrics-record
|
|
17
17
|
# -> feature-transition (conditional: if vars.feature set)
|
|
18
|
+
# -> feature-verify (post-transition feature check gate, 0915 F1)
|
|
18
19
|
# -> branch-cleanup (conditional: if vars.merge=true)
|
|
19
20
|
# -> done
|
|
20
21
|
# doc-sync routes a contract violation to `repair` (cheap, no
|
|
@@ -295,6 +296,30 @@ states:
|
|
|
295
296
|
printf 'FAIL\n' > ".spur/run/$__runId-wrapup-sync.status";
|
|
296
297
|
fi
|
|
297
298
|
|
|
299
|
+
- id: feature-verify
|
|
300
|
+
description: >
|
|
301
|
+
Post-feature-transition verification hop (D63 task 0915, review finding
|
|
302
|
+
F1): wrapup's doc-sync and the feature transition mutate the corpus AFTER
|
|
303
|
+
the feature-scoped verification pass ran. The proof digest deliberately
|
|
304
|
+
excludes docs/tasks*/docs/features* (shared evidence, concurrent writers),
|
|
305
|
+
so the bound receipt stays valid — but the feature's completion boundary
|
|
306
|
+
must still observe the post-wrapup state. This hop re-runs the feature
|
|
307
|
+
check gate (`featureGateCmd`). When the configured command is the done-
|
|
308
|
+
boundary variant (`feature check --as done`), it validates the bound
|
|
309
|
+
evidence receipt (feature identity, verifier definition digest, terminal
|
|
310
|
+
recording run, artifact registration, checked-input digest) against the
|
|
311
|
+
current feature contract; a plain gate command observes the post-wrapup
|
|
312
|
+
corpus state but does not enforce the receipt (0915 re-review P3). A FAIL
|
|
313
|
+
fails the wrapup loudly instead of letting a stale PASS ride; only a
|
|
314
|
+
verified gate writes PASS (0783 R4).
|
|
315
|
+
onEnter:
|
|
316
|
+
- kind: shell
|
|
317
|
+
options:
|
|
318
|
+
command: >-
|
|
319
|
+
sh -c "$featureGateCmd" &&
|
|
320
|
+
printf 'PASS\n' > ".spur/run/$__runId-wrapup-feature-verify.status" ||
|
|
321
|
+
printf 'FAIL\n' > ".spur/run/$__runId-wrapup-feature-verify.status"
|
|
322
|
+
|
|
298
323
|
- id: branch-cleanup
|
|
299
324
|
description: >
|
|
300
325
|
Irreversible-operation HITL gate, consent-only (0770). If vars.merge=true,
|
|
@@ -308,6 +333,8 @@ states:
|
|
|
308
333
|
- kind: hitl.confirm
|
|
309
334
|
options:
|
|
310
335
|
prompt: "Branch cleanup for the validated task list (.spur/run/${vars.__runId}-wrapup-tasks.json). This is IRREVERSIBLE (merge or delete). Confirm to proceed?"
|
|
336
|
+
decision:
|
|
337
|
+
mode: never
|
|
311
338
|
|
|
312
339
|
- id: done
|
|
313
340
|
description: >
|
|
@@ -472,19 +499,36 @@ transitions:
|
|
|
472
499
|
options:
|
|
473
500
|
command: 'test "$(cat .spur/run/$__runId-wrapup-sync.status 2>/dev/null)" = FAIL'
|
|
474
501
|
- from: feature-transition
|
|
502
|
+
to: feature-verify
|
|
503
|
+
description: Sync PASS — re-run the feature check gate against the post-wrapup state.
|
|
504
|
+
guard:
|
|
505
|
+
kind: shell
|
|
506
|
+
options:
|
|
507
|
+
command: 'test "$(cat .spur/run/$__runId-wrapup-sync.status 2>/dev/null)" = PASS'
|
|
508
|
+
- from: feature-verify
|
|
509
|
+
to: failed
|
|
510
|
+
description: >
|
|
511
|
+
Post-wrapup feature check failed (0915 F1): the bound receipt no longer
|
|
512
|
+
validates against the current feature contract. Already-written
|
|
513
|
+
learnings/metrics stay on disk.
|
|
514
|
+
guard:
|
|
515
|
+
kind: shell
|
|
516
|
+
options:
|
|
517
|
+
command: 'test "$(cat .spur/run/$__runId-wrapup-feature-verify.status 2>/dev/null)" = FAIL'
|
|
518
|
+
- from: feature-verify
|
|
475
519
|
to: branch-cleanup
|
|
476
|
-
description:
|
|
520
|
+
description: Post-wrapup feature check PASS — merge is requested.
|
|
477
521
|
guard:
|
|
478
522
|
kind: shell
|
|
479
523
|
options:
|
|
480
|
-
command: 'test "$(cat .spur/run/$__runId-wrapup-
|
|
481
|
-
- from: feature-
|
|
524
|
+
command: 'test "$(cat .spur/run/$__runId-wrapup-feature-verify.status 2>/dev/null)" = PASS && test "$merge" = true'
|
|
525
|
+
- from: feature-verify
|
|
482
526
|
to: done
|
|
483
|
-
description:
|
|
527
|
+
description: Post-wrapup feature check PASS — no merge requested.
|
|
484
528
|
guard:
|
|
485
529
|
kind: shell
|
|
486
530
|
options:
|
|
487
|
-
command: 'test "$(cat .spur/run/$__runId-wrapup-
|
|
531
|
+
command: 'test "$(cat .spur/run/$__runId-wrapup-feature-verify.status 2>/dev/null)" = PASS && test "$merge" != true'
|
|
488
532
|
|
|
489
533
|
# ── branch-cleanup: HITL exhaustive routing (yes / no / cancel → done) ──
|
|
490
534
|
# No irreversible git op is wired yet; confirmation is recorded, then wrap
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/spur",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.92",
|
|
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.5.
|
|
57
|
-
"@gobing-ai/ts-ai-runner": "^0.5.
|
|
58
|
-
"@gobing-ai/ts-dual-workflow-engine": "^0.5.
|
|
59
|
-
"@gobing-ai/ts-infra": "^0.5.
|
|
60
|
-
"@gobing-ai/ts-llm-jsonl-importer": "^0.5.
|
|
61
|
-
"@gobing-ai/ts-rule-engine": "^0.5.
|
|
62
|
-
"@gobing-ai/ts-runtime": "^0.5.
|
|
63
|
-
"@gobing-ai/ts-utils": "^0.5.
|
|
56
|
+
"@gobing-ai/ts-db": "^0.5.5",
|
|
57
|
+
"@gobing-ai/ts-ai-runner": "^0.5.5",
|
|
58
|
+
"@gobing-ai/ts-dual-workflow-engine": "^0.5.5",
|
|
59
|
+
"@gobing-ai/ts-infra": "^0.5.5",
|
|
60
|
+
"@gobing-ai/ts-llm-jsonl-importer": "^0.5.5",
|
|
61
|
+
"@gobing-ai/ts-rule-engine": "^0.5.5",
|
|
62
|
+
"@gobing-ai/ts-runtime": "^0.5.5",
|
|
63
|
+
"@gobing-ai/ts-utils": "^0.5.5",
|
|
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
|
@@ -629,6 +629,7 @@ pipeline owns one lifecycle phase:
|
|
|
629
629
|
| `idea-pipeline.yaml` | Idea/planning → feature + tasks | `/sp:dev-idea`, `/sp:dev-plan` |
|
|
630
630
|
| `wrapup-pipeline.yaml` | Post-execution wrap-up | `/sp:dev-wrap`, `/sp:dev-wrapall` |
|
|
631
631
|
| `wayfinder-resolution.yaml` | Wayfinder ticket resolution loop | `spur workflow run` (free-form) |
|
|
632
|
+
| `decision-routing-example.yaml` | DecisionMaker routing example (never / evidence / omitted modes, defer → operator pause) | `spur workflow run` (authoring sample) |
|
|
632
633
|
|
|
633
634
|
### Lifecycle operations
|
|
634
635
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: expert-spur
|
|
3
|
-
description:
|
|
4
|
-
Use PROACTIVELY for "create tasks for this feature", "update all task statuses", "audit task traceability",
|
|
3
|
+
description: |-
|
|
4
|
+
Use PROACTIVELY for "create tasks for this feature", "update all task statuses", "audit task traceability", or "expert-spur". Runs multi-step corpus campaigns across tasks, features, rules, workflows, and agent specs: creation, status/section updates, audits, and hardening. Uses sp:spur-composer for workflow composition, rule tuning, and accepted proposals; sp:spur-doctor for artifact evaluation and history reflection. Run single operations via CLI; recurring loops and multi-agent coordination belong to sp:super-planner.
|
|
5
5
|
|
|
6
6
|
<example>
|
|
7
7
|
Context: Batch task status update across a feature.
|
|
@@ -86,7 +86,10 @@ You own the spaces **between** task runs:
|
|
|
86
86
|
- **Parallelize only when requested** by applying `sp:parallel-execution` to a proven-independent
|
|
87
87
|
subset (Step 3 optional path). Serialize when dependency, file-overlap, or budget checks fail.
|
|
88
88
|
Preflight still runs per WBS before fan-out; recovery stays sequential.
|
|
89
|
-
- **Inspect** each terminal state
|
|
89
|
+
- **Inspect** each terminal state via `spur workflow trace "$RUN" --follow --timeout 600000` (a
|
|
90
|
+
timeout prints one checkpoint and exits 1; the run continues, never cancelled or relaunched) plus
|
|
91
|
+
`.spur/run/<wbs>-verdict.json`, accepted only when the trace's `.run.runId` equals the dispatched
|
|
92
|
+
run and the verdict's mtime ≥ the trace's `.run.startedAt` — otherwise `stale-evidence` (Step 3.3).
|
|
90
93
|
- **One-shot recovery (optional)** - on non-PASS / stuck status, consult next-router **once** for that
|
|
91
94
|
WBS (`recoveryHint` / dry-run plan): print the child command, or dispatch once only when the batch
|
|
92
95
|
was started with `--auto` and cardinality is 1. Never self-loop until done.
|
|
@@ -264,7 +267,10 @@ Report using the batch-report template from execution-batch.md §5:
|
|
|
264
267
|
**Next:** <one-line action>
|
|
265
268
|
```
|
|
266
269
|
|
|
267
|
-
Per-task outcome vocabulary: `done` | `failed` | `blocked` | `skipped` | `
|
|
270
|
+
Per-task outcome vocabulary: `done` | `failed` | `blocked` | `skipped` | `paused` (0933: parked on
|
|
271
|
+
an operator question — escalate hop — or an approval gate; non-terminal, never `done`) |
|
|
272
|
+
`not-attempted`, plus the parallel-only `integration-conflict`
|
|
273
|
+
([execution-batch.md § Parallel isolation](../skills/spur-dev/references/execution-batch.md#parallel-isolation---mode-parallel)).
|
|
268
274
|
Batch verdict: `clean` (all attempted tasks `done`) | `halted` (a failure stopped the batch) |
|
|
269
275
|
`aborted` (cycle or selector error before any run).
|
|
270
276
|
|
|
@@ -272,9 +278,12 @@ With `--json`, emit the same shape as a JSON object for machine consumption.
|
|
|
272
278
|
|
|
273
279
|
## Out of scope (deferred)
|
|
274
280
|
|
|
275
|
-
- **Parallel execution** -
|
|
276
|
-
-
|
|
277
|
-
|
|
281
|
+
- **Parallel execution** - `--mode parallel` isolates each task in its own worktree with
|
|
282
|
+
rebase-and-FF integration; see [execution-batch.md § Parallel isolation](../skills/spur-dev/references/execution-batch.md#parallel-isolation---mode-parallel).
|
|
283
|
+
- **Interactive within-step escalation** — implemented (0933): the pipeline's `escalate` hop
|
|
284
|
+
pauses on the implement agent's operator question; the operator answers via
|
|
285
|
+
`spur workflow continue --answer-text` and the run resumes implement with the Q/A transcript
|
|
286
|
+
(bounded by `maxEscalations`). See [execution-batch.md Step 3](../skills/spur-dev/references/execution-batch.md#step-3--the-driver-loop-r3-r4).
|
|
278
287
|
|
|
279
288
|
## Platform Notes
|
|
280
289
|
|
|
@@ -14,11 +14,11 @@ Wraps the **sp:dogfood-testing** skill.
|
|
|
14
14
|
| Flag | Description | Default |
|
|
15
15
|
| --- | --- | --- |
|
|
16
16
|
| `<testee>` | Skill / command / CLI to exercise end-to-end. | required |
|
|
17
|
-
| `--agent` `<inline\|auto\|name>` |
|
|
18
|
-
| `--max-retry` `<n>` | Max auto-fix retries per
|
|
17
|
+
| `--agent` `<inline\|auto\|name>` | **Testee-scoped** agent the testee runs under — forwarded into the testee invocation; the dogfood driver always runs in the current session. | omit (forward nothing) |
|
|
18
|
+
| `--max-retry` `<n>` | Max auto-fix retries per step. `0` = observe-only. Mandatory (as `0` or `N`) for pipeline-driving testees and testees with a mutating `--fix` mode. | 2 |
|
|
19
19
|
| `--save` | Compatibility no-op; saving is now default. Retained until evidenced retirement. | off |
|
|
20
|
-
| `--task` |
|
|
21
|
-
| `--chain-follow` |
|
|
20
|
+
| `--task` | **Creates** a new review-template task for the findings (`spur task create --template review`) — it does not attach to or update the task under test. | off |
|
|
21
|
+
| `--chain-follow` | **Reads existing chained-leg evidence** (verdict artifacts, task-file diffs, review tables) after a chained leg completes, for attribution — it never executes the chained leg itself. Without it the driver stops at the testing boundary. | off |
|
|
22
22
|
| `--full` | Full report verbosity (all sections). | off |
|
|
23
23
|
|
|
24
24
|
For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag-glossary.md).
|
|
@@ -27,9 +27,12 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
|
|
|
27
27
|
|
|
28
28
|
## Implementation
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
`
|
|
34
|
-
|
|
30
|
+
Follow the inline procedure in [dev-operations.md](../skills/spur-dev/references/dev-operations.md#10-fixall) (fixall). Pipeline signal: when `--gate-log` is set (the `test-fix` hop), run no full gate — the `test-recheck` state immediately after is the deciding run (R4, task 0483).
|
|
31
|
+
|
|
32
|
+
When dispatched from the pipeline's test-fix stage (F96, task 0950), the gate log carries a
|
|
33
|
+
`residual artifact` block (`<wbs>-residuals.json`) and the findings file already
|
|
34
|
+
contains the merged residual anchors: treat those items as fix targets, in order,
|
|
35
|
+
alongside gate anchors. The fixer may write `.spur/run/<wbs>-residual-deferrals.json`
|
|
36
|
+
— one `{id, reason}` entry per item — but only for P3 findings or diff markers it
|
|
37
|
+
cannot fix inside the task; the done stage settles deferrals into follow-up tasks.
|
|
35
38
|
|
|
@@ -41,6 +41,12 @@ For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag
|
|
|
41
41
|
**Flags:**
|
|
42
42
|
|
|
43
43
|
- `--auto` | `--agent <inline|auto|name>` — Skip objective HITL confirmations (taste/irreversible gates still pause). `--agent` names who does the model-bearing work. Interactive omit/`inline` keeps the controller and implement-only stages in this session; full mode reads `task-pipeline.yaml` as the SSOT and interprets its actions/guards through the inline driver, whose eligible `agent.run` stages dispatch once to a native subagent and otherwise run in the host (0508 eligibility — task 0687 resolved-inline) It records `stage <id> executed inline in session <session-id>` or `stage <id> executed via subagent <agent-id> (host session <session-id>)` in the run log. `auto` or a name is merged into `vars.agent` and `vars.implementAgent` and keeps the existing subprocess workflow. Headless `spur workflow run` / `spur agent run` is unchanged. See the [execution-surface contract](../skills/spur-dev/references/cross-cutting.md#inline-default-execution-surface).
|
|
44
|
+
- `--escalation-file <path>` (implement step only, 0933) — names the Q/A escalation transcript
|
|
45
|
+
(default `.spur/run/<wbs>-escalation.md`). Absent on a first attempt means "no prior
|
|
46
|
+
escalations". When the implement agent needs an operator decision it appends its question to
|
|
47
|
+
`.spur/run/<wbs>-question.md` and exits 0 — the pipeline's `escalate` hop surfaces the question,
|
|
48
|
+
the operator answers via `spur workflow continue --answer-text`, and the guard appends the Q/A
|
|
49
|
+
pair to this transcript before re-entering implement, where the agent reads it and resumes.
|
|
44
50
|
|
|
45
51
|
`--worktree` `[<name>]` (run the task's pipeline in an isolated git worktree — FF-merge onto the
|
|
46
52
|
base ref on full success, retain intact on any failure/halt/non-FF; bare form creates a fresh tree,
|
|
@@ -20,10 +20,11 @@ Wraps the **sp:spur-dev** skill.
|
|
|
20
20
|
| `--auto` | Skip objective HITL gates. | off |
|
|
21
21
|
| `--agent` `<inline\|auto\|name>` | Who runs each task's pipeline stages. Interactive sequential omit/`inline` uses the host-session driver with unified inline semantics (task 0687 — see below)). `auto`, a name, parallel mode, and headless invocation use subprocesses. | omit |
|
|
22
22
|
| `--json` | Emit structured JSON. | off |
|
|
23
|
-
| `--wrap` | Run the wrap hop
|
|
23
|
+
| `--wrap` | Run the wrap hop **once for the batch** over the `done` subset only (Step 6 of execution-batch.md): `vars.feature` is passed only when every frozen task is `done`/`cancelled`; an empty done subset skips the wrap with a reason. The `--agent` selector is preserved into the `/sp:dev-wrap` handoff when supplied; omission remains omission. | off |
|
|
24
24
|
| `--next` | Chain-to-completion via the next-router. | off |
|
|
25
25
|
| `--continue` | Resume an interrupted batch. | off |
|
|
26
26
|
| `--worktree` `[<name>]` | Run the batch in an isolated git worktree; FF-merge on success, retain on failure. Bare `--worktree` creates a fresh tree; `--worktree <name>` adopts an existing worktree by name/path/branch. | off |
|
|
27
|
+
| `--concurrency` `<n>` | Parallel-mode worker bound: at most `<n>` task pipelines run at once (task 0931); a dependent starts only after its in-set dependencies are integrated onto the base ref. No-op in sequential mode (ignored). | 2 |
|
|
27
28
|
|
|
28
29
|
For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag-glossary.md).
|
|
29
30
|
|
|
@@ -41,7 +42,9 @@ structured findings, before any task pipeline action, task 0510 R2; scoped: `L4.
|
|
|
41
42
|
(the expected pre-run state of any not-yet-run feature) is reported verbatim but does not abort —
|
|
42
43
|
any other strict error aborts), `--mode`
|
|
43
44
|
`<sequential|parallel>` (default `sequential`; `parallel` fans out a proven-independent subset —
|
|
44
|
-
see `execution-batch.md` § Parallel
|
|
45
|
+
see `execution-batch.md` § Parallel isolation), `--concurrency <n>`
|
|
46
|
+
(parallel-mode worker bound — at most <n> task pipelines at once, default 2; a dependent task starts
|
|
47
|
+
only after its in-set dependencies are **integrated** onto the base ref), `--keep-going`
|
|
45
48
|
(batch failure policy — skip a failed task's in-batch dependents, continue independents; default
|
|
46
49
|
halts on first failure), `--auto`
|
|
47
50
|
(sets `profile=auto` on each per-task run, skipping the HITL approve gate), `--agent <inline|auto|name>`
|
|
@@ -56,9 +59,10 @@ FF-merge onto the base ref on full success, retain intact on any failure/halt/no
|
|
|
56
59
|
creates a fresh tree, `<name>` form adopts an existing worktree by name/path/branch; see
|
|
57
60
|
`execution-batch.md` § Worktree isolation).
|
|
58
61
|
|
|
59
|
-
**`--worktree`
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
**`--worktree` and parallel mode.** `--worktree --mode parallel` is **rejected** — parallel mode
|
|
63
|
+
already isolates each task in its own worktree (see `execution-batch.md` § Parallel isolation), and
|
|
64
|
+
reuse mode (`--worktree <name>`) has no per-task meaning. Run parallel batches without
|
|
65
|
+
`--worktree`, or run them sequentially with it.
|
|
62
66
|
|
|
63
67
|
**`--worktree` corpus visibility.** While the batch runs in a worktree, corpus writes (task
|
|
64
68
|
statuses, kanban) land in the worktree copy; your main tree still shows pre-run statuses until the
|
|
@@ -75,7 +79,9 @@ advancing the feature lifecycle). **was: `--next` deliberately omitted; the old
|
|
|
75
79
|
**Three orthogonal axes** (do not confuse): `--keep-going`
|
|
76
80
|
= batch failure policy (does a failure halt the batch or skip dependents?);
|
|
77
81
|
`--continue` = resume from
|
|
78
|
-
checkpoint
|
|
82
|
+
checkpoint against the batch's original frozen identity — persisted plan membership, worktree
|
|
83
|
+
marker, identity-filtered checkpoints as hints (execution-batch.md § Batch continuation, task
|
|
84
|
+
0919); `--next`
|
|
79
85
|
= chain each task to terminal status + batch-once wrap. See `dev-operations.md` § runall for the
|
|
80
86
|
full distinction.
|
|
81
87
|
|