@gobing-ai/spur 0.3.95 → 0.3.96
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/plugin-scripts.json +0 -54
- package/config/rules/boundary/sp-script-placement.yaml +19 -0
- package/config/rules/strict/runtime-boundaries.yaml +5 -0
- package/config/rules/structure/test-location.yaml +2 -0
- package/config/rules/typescript/no-syscall-emulation-in-boundary-mock.yaml +1 -1
- package/config/rules/typescript/output-boundaries.yaml +15 -2
- package/config/script-placement-baseline.json +51 -0
- package/config/workflows/feature-verification.yaml +1 -1
- package/config/workflows/history-anatomy.yaml +23 -11
- package/config/workflows/idea-pipeline.yaml +80 -85
- package/config/workflows/pr-review.yaml +18 -9
- package/config/workflows/task-pipeline.yaml +42 -95
- package/config/workflows/wrapup-pipeline.yaml +89 -37
- package/package.json +1 -1
- package/plugins/sp/README.md +8 -10
- package/plugins/sp/agents/super-reviewer.md +43 -18
- package/plugins/sp/commands/dev-fixgha.md +83 -0
- package/plugins/sp/commands/dev-gitmsg.md +8 -6
- package/plugins/sp/commands/dev-gtd.md +2 -2
- package/plugins/sp/commands/dev-idea.md +22 -12
- package/plugins/sp/commands/dev-plan.md +8 -9
- package/plugins/sp/commands/dev-review.md +22 -13
- package/plugins/sp/commands/dev-verifyall.md +1 -1
- package/plugins/sp/commands/spur-init.md +2 -2
- package/plugins/sp/lib/history-anatomy.generated.d.mts +112 -0
- package/plugins/sp/lib/history-anatomy.generated.mjs +686 -0
- package/plugins/sp/lib/idea-handoff.generated.mjs +5 -4
- package/plugins/sp/lib/inline-run.generated.d.mts +11 -0
- package/plugins/sp/lib/inline-run.generated.mjs +25 -8
- package/plugins/sp/lib/quality-gate.generated.d.mts +104 -0
- package/plugins/sp/lib/quality-gate.generated.mjs +438 -0
- package/plugins/sp/lib/residual-scan.generated.d.mts +62 -0
- package/plugins/sp/lib/residual-scan.generated.mjs +210 -0
- package/plugins/sp/lib/spur-bin.ts +36 -0
- package/plugins/sp/lib/step-profile.generated.d.mts +71 -0
- package/plugins/sp/lib/step-profile.generated.mjs +174 -0
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/references/roles.md +1 -1
- package/plugins/sp/scripts/history-anatomy-cache.mjs +20 -19
- package/plugins/sp/scripts/history-anatomy-cache.ts +23 -928
- package/plugins/sp/scripts/inline-run-setup.mjs +85 -320
- package/plugins/sp/scripts/inline-run-setup.ts +104 -667
- package/plugins/sp/scripts/quality-gate.mjs +34 -19
- package/plugins/sp/scripts/quality-gate.ts +12 -658
- package/plugins/sp/scripts/residual-scan.mjs +135 -156
- package/plugins/sp/scripts/residual-scan.ts +102 -499
- package/plugins/sp/scripts/script-root.mjs +5 -1
- package/plugins/sp/scripts/script-root.ts +5 -1
- package/plugins/sp/scripts/workflow-step-profile.mjs +25 -17
- package/plugins/sp/scripts/workflow-step-profile.ts +21 -315
- package/plugins/sp/scripts/wrapup-drift-probe.mjs +8 -2
- package/plugins/sp/scripts/wrapup-drift-probe.ts +3 -2
- package/plugins/sp/scripts/wrapup-steps.mjs +10 -32
- package/plugins/sp/scripts/wrapup-steps.ts +8 -36
- package/plugins/sp/skills/code-improvement/SKILL.md +5 -4
- package/plugins/sp/skills/code-verification/SKILL.md +34 -9
- package/plugins/sp/skills/code-verification/references/verdict-schema.md +3 -3
- package/plugins/sp/skills/functional-review/SKILL.md +7 -4
- package/plugins/sp/skills/functional-review/references/verdict-schema.md +1 -1
- package/plugins/sp/skills/history-anatomy/references/modes.md +2 -1
- package/plugins/sp/skills/next-feature/references/handoff-routing.md +1 -1
- package/plugins/sp/skills/next-router/references/routing-table.md +1 -1
- package/plugins/sp/skills/spur-cli/SKILL.md +3 -3
- package/plugins/sp/skills/spur-cli/references/agent.md +10 -10
- package/plugins/sp/skills/spur-cli/references/features.md +17 -6
- package/plugins/sp/skills/spur-cli/references/init.md +17 -16
- package/plugins/sp/skills/spur-cli/references/self.md +3 -2
- package/plugins/sp/skills/spur-cli/references/serve.md +10 -10
- package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +21 -6
- package/plugins/sp/skills/spur-cli/references/tasks.md +14 -8
- package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +4 -3
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +11 -9
- package/plugins/sp/skills/spur-dev/references/decision-brief.md +1 -1
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +86 -70
- package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +3 -3
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +77 -34
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +5 -9
- package/plugins/sp/skills/spur-dev/references/feature-link-helper.md +3 -3
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +31 -21
- package/plugins/sp/skills/spur-dev/references/gate-checklists.md +19 -19
- package/plugins/sp/skills/spur-dev/references/idea-evaluation.md +4 -3
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +29 -3
- package/plugins/sp/skills/spur-doctor/SKILL.md +1 -1
- package/plugins/sp/skills/sys-architecture/SKILL.md +3 -2
- package/spur.js +1495 -369
- package/web/_astro/{BoardApp.Cpxntzad.js → BoardApp.BIjMatT1.js} +1 -1
- package/web/_astro/{BoardApp.BxJuwD7I.js → BoardApp.GvjIe9Z6.js} +42 -42
- package/web/_astro/{TaskDetail.C5bW4WGV.js → TaskDetail.BZM3EAFx.js} +1 -1
- package/web/_astro/{arc.CyjRvNMY.js → arc.HkRiZnoI.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.B4lWRzJA.js → architectureDiagram-3BPJPVTR.BDdK-tgZ.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.Be38USQ2.js → blockDiagram-GPEHLZMM.CZ9kOBxx.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.DT9Fj5Qx.js → c4Diagram-AAUBKEIU.DXK9qeRD.js} +1 -1
- package/web/_astro/channel.DlhX2MEt.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.SeSBWLg5.js → chunk-2J33WTMH.BTD2WeX5.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.DoO4VE14.js → chunk-4BX2VUAB.Ci6Qbcvk.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.DrmTFA53.js → chunk-55IACEB6.yl3zsj7p.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.Bi-TUb_V.js → chunk-727SXJPM.ClXZsfyR.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.B-xp8Uhi.js → chunk-AQP2D5EJ.BmKWZBcP.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.DGWrDnUU.js → chunk-FMBD7UC4.By30fcb7.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM._BagvPDy.js → chunk-ND2GUHAM.24NmrD-k.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.VOboYWQ0.js → chunk-QZHKN3VN.BN4sKdcS.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.D_apfHS7.js → classDiagram-4FO5ZUOK.CJpoMPb5.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.D_apfHS7.js → classDiagram-v2-Q7XG4LA2.CJpoMPb5.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.DNLU_L-x.js → cose-bilkent-S5V4N54A.BraxQ2Nt.js} +1 -1
- package/web/_astro/{cynefin-OW5HDTMX.D8borhV-.js → cynefin-OW5HDTMX.gzoU73oL.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.Uc0lvjcV.js → dagre-BM42HDAG.wyDfWySU.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.DDIxtDBo.js → diagram-2AECGRRQ.h2_EbMxV.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.DVoDnD3H.js → diagram-5GNKFQAL.Db6dcs89.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.CRubTJ-0.js → diagram-KO2AKTUF.NVwzxu_U.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.m9SeYcXQ.js → diagram-LMA3HP47.B-eNgDQk.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.C6s2ZjV5.js → diagram-OG6HWLK6.Bsa8ZRbJ.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.nSzr5KTj.js → erDiagram-TEJ5UH35.BospRE5Q.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.DrZcys16.js → flowDiagram-I6XJVG4X.DMzvHwAA.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.Do4M1b-K.js → ganttDiagram-6RSMTGT7.Dmdxgd-M.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.BWc9oJ4l.js → gitGraphDiagram-PVQCEYII.CaqdO0rL.js} +1 -1
- package/web/_astro/index.EoZlzLK-.css +1 -0
- package/web/_astro/{infoDiagram-5YYISTIA.BIdOctFk.js → infoDiagram-5YYISTIA.DDVD9Wn7.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.CV5SuG2t.js → ishikawaDiagram-YF4QCWOH.EKyCUFsL.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.CxE-rEJ-.js → journeyDiagram-JHISSGLW.By2-RkYB.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.BPRdKWs_.js → kanban-definition-UN3LZRKU.ar-WmlyR.js} +1 -1
- package/web/_astro/{linear.zRsuuDTE.js → linear.BnzMBgo_.js} +1 -1
- package/web/_astro/{mermaid.core.jAJTcMKc.js → mermaid.core.DSqeFu2Y.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.BffJxfCr.js → mindmap-definition-RKZ34NQL.1XcF8Wh2.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.CacwWaE3.js → pieDiagram-4H26LBE5.DnItHOdK.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.hXELD06-.js → quadrantDiagram-W4KKPZXB.BQQyrnBt.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.DdEbPcqT.js → requirementDiagram-4Y6WPE33.Dmzxun82.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.DgaDocKv.js → sankeyDiagram-5OEKKPKP.BBIeRKYB.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.B0KScnAu.js → sequenceDiagram-3UESZ5HK.CUNVdBBf.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.CV9M_WNc.js → stateDiagram-AJRCARHV.DlFf2sJm.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.BOAo74Et.js → stateDiagram-v2-BHNVJYJU.DXR7I1H5.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.CqqepUMe.js → timeline-definition-PNZ67QCA.BcO-GyX2.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.DDqe4dOG.js → vennDiagram-CIIHVFJN.ChCECmmW.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.B3R9OPdO.js → wardleyDiagram-YWT4CUSO.CRaT12mD.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.B3SvgXpQ.js → xychartDiagram-2RQKCTM6.B3lsHVpj.js} +1 -1
- package/web/index.html +2 -2
- package/plugins/sp/lib/artifact-digest.generated.d.mts +0 -7
- package/plugins/sp/lib/artifact-digest.generated.mjs +0 -48
- package/plugins/sp/scripts/feature-sync-bounded.mjs +0 -301
- package/plugins/sp/scripts/feature-sync-bounded.ts +0 -481
- package/plugins/sp/scripts/idea-coverage-check.ts +0 -168
- package/plugins/sp/scripts/inline-pipeline-parity-check.ts +0 -298
- package/plugins/sp/scripts/record-feature-sync.mjs +0 -63
- package/plugins/sp/scripts/record-feature-sync.ts +0 -84
- package/plugins/sp/scripts/script-contract-check.ts +0 -506
- package/plugins/sp/scripts/stage-registry-adapter.ts +0 -1533
- package/plugins/sp/scripts/surface-drift-inventory.ts +0 -989
- package/plugins/sp/scripts/task-evidence-precheck.ts +0 -189
- package/plugins/sp/scripts/task-size-precheck.ts +0 -212
- package/plugins/sp/scripts/transition-shim-check.ts +0 -238
- package/plugins/sp/scripts/validate-commands.ts +0 -689
- package/plugins/sp/scripts/validate-flag-contracts.ts +0 -890
- package/plugins/sp/scripts/verify-answer-lint.ts +0 -549
- package/web/_astro/channel.CI6N_tCg.js +0 -1
- package/web/_astro/index.CENnIEqT.css +0 -1
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
#
|
|
10
10
|
# Shape: start -> discovery -> idea-eval -> feature-create -> ac-generate -> feature-check
|
|
11
11
|
# -> system-design (conditional: needs_design signal)
|
|
12
|
-
# -> design-approval (taste HITL gate;
|
|
12
|
+
# -> design-approval (taste HITL gate; bypassed only when design_approved=true + design check PASS)
|
|
13
13
|
# -> decompose -> batch-create -> handoff-finalize -> handoff
|
|
14
|
-
# (idea-eval rejection -> cancelled)
|
|
14
|
+
# (idea-eval rejection, or auto + `drop` recommendation -> cancelled)
|
|
15
15
|
# (feature-check failure routes back to ac-generate; batch-create failure to decompose).
|
|
16
16
|
#
|
|
17
17
|
# Evidence instead of ceremony (task 0769): the feature check is MEASURED exactly once at
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
# design — "auto" (default, signal-driven) or "skip" (--skip-design). No force path.
|
|
28
28
|
# Unified: skip also means omit per-task Design in batch-create (scaffold only;
|
|
29
29
|
# refine fills later). Default: decompose must author batch item `design`.
|
|
30
|
-
# design_approved — "true"
|
|
31
|
-
#
|
|
32
|
-
# idea_approved — "true"
|
|
33
|
-
#
|
|
34
|
-
# CLI --
|
|
30
|
+
# design_approved — "true" lets profile=auto route around the design-approval taste gate when
|
|
31
|
+
# the recorded design check PASSes (default "false")
|
|
32
|
+
# idea_approved — "true" lets profile=auto accept the idea-eval report's recommendation
|
|
33
|
+
# (proceed/reshape → continue, drop → cancelled; missing → pause) (default "false")
|
|
34
|
+
# CLI --auto on dev-idea / dev-plan sets profile=auto AND both pre-clear vars to true.
|
|
35
35
|
# spurBin — PATH-independent spur invocation (overridden by CLI at run start)
|
|
36
36
|
# agent — agent for agent.run steps (default: auto → `agent.default` in config)
|
|
37
37
|
#
|
|
@@ -137,15 +137,24 @@ states:
|
|
|
137
137
|
session: fresh
|
|
138
138
|
expectFile: .spur/run/${vars.__runId}-idea-eval-report.md
|
|
139
139
|
timeoutMs: ${vars.stepTimeoutMs}
|
|
140
|
+
# Derive the eval recommendation ONCE (0769 pattern): the first non-blank line under
|
|
141
|
+
# `## Recommendation` → proceed | reshape | drop | unknown. The --auto guards out of
|
|
142
|
+
# discovery / idea-eval read this file; `unknown` routes to the idea-eval pause.
|
|
143
|
+
- kind: shell
|
|
144
|
+
options:
|
|
145
|
+
command: >-
|
|
146
|
+
awk '/^## Recommendation/{f=1;next} f&&NF{r=tolower($0);exit}
|
|
147
|
+
END{print (match(r,/^[*_ ]*(proceed|reshape|drop)/) ? substr(r,RSTART,RLENGTH) : "unknown")}'
|
|
148
|
+
".spur/run/$__runId-idea-eval-report.md" | tr -d '*_ ' > ".spur/run/$__runId-idea-recommendation.txt"
|
|
140
149
|
|
|
141
150
|
- id: idea-eval
|
|
142
151
|
description: >
|
|
143
152
|
HITL taste gate. Discovery has produced the idea-evaluation report
|
|
144
153
|
(.spur/run/${vars.__runId}-idea-eval-report.md) with urgency/necessity scores, premises,
|
|
145
154
|
pros/cons, and a recommendation. The operator reviews and approves or
|
|
146
|
-
rejects.
|
|
147
|
-
|
|
148
|
-
|
|
155
|
+
rejects. Routed around only when profile=auto AND vars.idea_approved=true
|
|
156
|
+
(CLI --auto) AND the report's recommendation is proceed/reshape; a drop
|
|
157
|
+
recommendation cancels, a missing one still pauses here.
|
|
149
158
|
pause: true
|
|
150
159
|
onEnter:
|
|
151
160
|
- kind: hitl.confirm
|
|
@@ -181,16 +190,15 @@ states:
|
|
|
181
190
|
options:
|
|
182
191
|
path: .spur/run/${vars.__runId}-idea-feature-id.txt
|
|
183
192
|
var: featureId
|
|
193
|
+
# 1007 R2: one shell persists both sections — the Goal and Scope updates share the
|
|
194
|
+
# artifact precondition, so the two update shells merged (original commands in order,
|
|
195
|
+
# same && fail-fast semantics).
|
|
184
196
|
- kind: shell
|
|
185
197
|
options:
|
|
186
198
|
command: >-
|
|
187
199
|
mkdir -p .spur/run &&
|
|
188
200
|
test -s .spur/run/$__runId-idea-goal.md &&
|
|
189
|
-
$spurBin feature update "$featureId" --section Goal --from-file .spur/run/$__runId-idea-goal.md
|
|
190
|
-
- kind: shell
|
|
191
|
-
options:
|
|
192
|
-
command: >-
|
|
193
|
-
mkdir -p .spur/run &&
|
|
201
|
+
$spurBin feature update "$featureId" --section Goal --from-file .spur/run/$__runId-idea-goal.md &&
|
|
194
202
|
test -s .spur/run/$__runId-idea-scope.md &&
|
|
195
203
|
$spurBin feature update "$featureId" --section Scope --from-file .spur/run/$__runId-idea-scope.md
|
|
196
204
|
|
|
@@ -206,9 +214,10 @@ states:
|
|
|
206
214
|
check records FAIL and routes through the capped retry loop via guards that consume the
|
|
207
215
|
recorded result — it never fails the run (the engine's default onError policy is `fail`,
|
|
208
216
|
so an in-action check failure would kill the run before the retry edges are evaluated).
|
|
209
|
-
Requirement coverage is MEASURED
|
|
210
|
-
|
|
211
|
-
|
|
217
|
+
Requirement coverage is MEASURED by the same gate (1004 R2): the `idea-ac-check` args
|
|
218
|
+
carry `--inventory .spur/run/${vars.__runId}-idea-eval-report.md`, so uncovered
|
|
219
|
+
inventory items record FAIL on `idea-ac-check.status` and route through the same capped
|
|
220
|
+
retry loop via the guards below.
|
|
212
221
|
onEnter:
|
|
213
222
|
- kind: shell
|
|
214
223
|
options:
|
|
@@ -246,33 +255,16 @@ states:
|
|
|
246
255
|
options:
|
|
247
256
|
id: idea-ac-check
|
|
248
257
|
executable: "${vars.spurBin}"
|
|
249
|
-
args: ["feature", "check", "${vars.featureId}"]
|
|
258
|
+
args: ["feature", "check", "${vars.featureId}", "--inventory", ".spur/run/${vars.__runId}-idea-eval-report.md"]
|
|
250
259
|
resultFile: .spur/run/${vars.__runId}-idea-ac-check.status
|
|
251
260
|
softFail: true
|
|
252
261
|
timeoutMs: 120000
|
|
253
|
-
# 0887 R4: requirement-inventory ↔ AC coverage, measured once at the same author/revise
|
|
254
|
-
# boundary. Soft shell (exit 0 always): the checker writes the PASS/FAIL status itself and
|
|
255
|
-
# the guards below consume the recorded result — never re-run the checker (0769 pattern).
|
|
256
|
-
# Repo-checkout path first, then the superskill-staged twin (handoff-finalize resolution
|
|
257
|
-
# shape); neither present fails closed to FAIL so readiness degrades visibly instead of
|
|
258
|
-
# silently skipping coverage.
|
|
259
|
-
- kind: shell
|
|
260
|
-
options:
|
|
261
|
-
command: >-
|
|
262
|
-
mkdir -p .spur/run &&
|
|
263
|
-
S=plugins/sp/scripts/idea-coverage-check.ts;
|
|
264
|
-
[ -f config/plugin-scripts.json -a -f "$S" ] || S="$(superskill script path sp idea-coverage-check.ts 2>/dev/null)";
|
|
265
|
-
if [ -n "$S" ] && [ -f "$S" ]; then
|
|
266
|
-
bun "$S" --run-id "$__runId" --report ".spur/run/$__runId-idea-eval-report.md" --ac ".spur/run/$__runId-idea-ac-content.md" || printf 'FAIL run=%s checker exited nonzero (bun missing or checker crash)\n' "$__runId" > ".spur/run/$__runId-idea-coverage.reason";
|
|
267
|
-
else
|
|
268
|
-
printf 'FAIL run=%s checker not found — run superskill install sp --marketplace gobing-ai/spur\n' "$__runId" | tee ".spur/run/$__runId-idea-coverage.reason" >&2;
|
|
269
|
-
printf 'FAIL\n' > ".spur/run/$__runId-idea-coverage.status";
|
|
270
|
-
fi
|
|
271
262
|
# 0945 R2: derive the route facts ONCE at this boundary (0769 pattern) — guards read these
|
|
272
263
|
# named files instead of re-deriving design×needs_design inline. The same command is
|
|
273
264
|
# duplicated in feature-check's onEnter (YAML has no include); byte-equality is
|
|
274
265
|
# test-pinned (idea-pipeline-routing.test.ts). Missing/corrupt needs-design JSON fails
|
|
275
|
-
# safe to `design`; readiness is PASS only when
|
|
266
|
+
# safe to `design`; readiness is PASS only when the recorded check is PASS (1004 R2:
|
|
267
|
+
# coverage folds into idea-ac-check via --inventory).
|
|
276
268
|
# (warn) 7 commands: two three-way `test && printf || printf` derivations over captured
|
|
277
269
|
# signal files (ADR-115); no model hop, no CLI re-run.
|
|
278
270
|
- kind: shell
|
|
@@ -282,7 +274,7 @@ states:
|
|
|
282
274
|
{ test "$design" = skip -o "$design" = auto -a "$(jq -r .needs_design .spur/run/$__runId-idea-needs-design.json 2>/dev/null)" = false &&
|
|
283
275
|
printf 'skip\n' > .spur/run/$__runId-idea-design-route.txt ||
|
|
284
276
|
printf 'design\n' > .spur/run/$__runId-idea-design-route.txt; } &&
|
|
285
|
-
{ test "$(cat .spur/run/$__runId-idea-ac-check.status 2>/dev/null)" = PASS
|
|
277
|
+
{ test "$(cat .spur/run/$__runId-idea-ac-check.status 2>/dev/null)" = PASS &&
|
|
286
278
|
printf 'PASS\n' > .spur/run/$__runId-idea-ac-ready.status ||
|
|
287
279
|
printf 'FAIL\n' > .spur/run/$__runId-idea-ac-ready.status; }
|
|
288
280
|
|
|
@@ -299,29 +291,19 @@ states:
|
|
|
299
291
|
the transition guards route directly from ac-generate to the appropriate next
|
|
300
292
|
state, so this state is only entered in interactive mode. On failure, the retry
|
|
301
293
|
cap routes back to ac-generate (≤3 retries) or escalates to failed.
|
|
302
|
-
Requirement coverage (
|
|
303
|
-
|
|
304
|
-
|
|
294
|
+
Requirement coverage (1004 R2) folds into the recorded `idea-ac-check` result via the
|
|
295
|
+
gate's `--inventory` flag: a FAIL there can mean some inventory items have no covering
|
|
296
|
+
scenario — answer no to route back to ac-generate for revision if needed.
|
|
305
297
|
pause: true
|
|
306
298
|
onEnter:
|
|
307
299
|
- kind: hitl.confirm
|
|
308
300
|
options:
|
|
309
|
-
prompt: "Feature check for ${vars.featureId}. Review the AC and confirm to proceed?
|
|
301
|
+
prompt: "Feature check for ${vars.featureId}. Review the AC and confirm to proceed? Recorded check status: $(cat .spur/run/${vars.__runId}-idea-ac-check.status 2>/dev/null || echo unknown) (.spur/run/${vars.__runId}-idea-ac-check.status — includes inventory-coverage findings, 1004 R2). (Failures route back to ac-generate for revision, capped at 3 retries.)"
|
|
310
302
|
decision:
|
|
311
303
|
mode: never
|
|
312
|
-
#
|
|
313
|
-
#
|
|
314
|
-
#
|
|
315
|
-
- kind: shell
|
|
316
|
-
options:
|
|
317
|
-
command: >-
|
|
318
|
-
mkdir -p .spur/run &&
|
|
319
|
-
{ test "$design" = skip -o "$design" = auto -a "$(jq -r .needs_design .spur/run/$__runId-idea-needs-design.json 2>/dev/null)" = false &&
|
|
320
|
-
printf 'skip\n' > .spur/run/$__runId-idea-design-route.txt ||
|
|
321
|
-
printf 'design\n' > .spur/run/$__runId-idea-design-route.txt; } &&
|
|
322
|
-
{ test "$(cat .spur/run/$__runId-idea-ac-check.status 2>/dev/null)" = PASS -a "$(cat .spur/run/$__runId-idea-coverage.status 2>/dev/null)" = PASS &&
|
|
323
|
-
printf 'PASS\n' > .spur/run/$__runId-idea-ac-ready.status ||
|
|
324
|
-
printf 'FAIL\n' > .spur/run/$__runId-idea-ac-ready.status; }
|
|
304
|
+
# 1007 R2: the former post-confirm route-writer duplicate is deleted — ac-generate's
|
|
305
|
+
# writer is the single writer (0945 R2 pin updated); its inputs (design var, needs-design
|
|
306
|
+
# JSON, recorded ac-check status) cannot change across hitl.confirm.
|
|
325
307
|
|
|
326
308
|
- id: system-design
|
|
327
309
|
description: >
|
|
@@ -376,9 +358,8 @@ states:
|
|
|
376
358
|
- id: design-approval
|
|
377
359
|
description: >
|
|
378
360
|
HITL taste gate. The operator reviews the system design and approves or
|
|
379
|
-
rejects it.
|
|
380
|
-
|
|
381
|
-
vars.design_approved=true (explicit prior approval).
|
|
361
|
+
rejects it. Routed around only when profile=auto AND vars.design_approved=true
|
|
362
|
+
(CLI --auto) AND the recorded design check PASSes; a FAIL still pauses here.
|
|
382
363
|
|
|
383
364
|
R7 (0433): a headless `no` persisted by DefaultHitlResponder would loop
|
|
384
365
|
design-approval -> system-design -> design-approval, burning unbounded
|
|
@@ -559,10 +540,8 @@ states:
|
|
|
559
540
|
- kind: shell
|
|
560
541
|
options:
|
|
561
542
|
command: >-
|
|
562
|
-
if
|
|
563
|
-
|
|
564
|
-
elif H="$(superskill script path sp idea-handoff.mjs 2>/dev/null)" && [ -f "$H" ]; then
|
|
565
|
-
node "$H";
|
|
543
|
+
eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/idea-handoff.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/idea-handoff.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)"; if [ -f "$S" ]; then
|
|
544
|
+
"$RUNNER" "$S";
|
|
566
545
|
else
|
|
567
546
|
echo "idea handoff failed closed — idea-handoff script not found — run 'superskill install sp --marketplace gobing-ai/spur'" >&2;
|
|
568
547
|
exit 1;
|
|
@@ -575,9 +554,8 @@ states:
|
|
|
575
554
|
next command (ready-depth refineall when any task is unready, else auto
|
|
576
555
|
runall). No task execution — the pipeline stops here.
|
|
577
556
|
onEnter:
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
message: "Idea pipeline handoff. Feature: ${vars.featureId}. See .spur/run/${vars.__runId}-idea-handoff.md for the created task list and recommended next command."
|
|
557
|
+
# 1007 R2: the handoff note is deleted — the run.artifact below carries the handoff
|
|
558
|
+
# (same path, the recommended-next-command report).
|
|
581
559
|
- kind: run.artifact
|
|
582
560
|
options:
|
|
583
561
|
path: .spur/run/${vars.__runId}-idea-handoff.md
|
|
@@ -608,17 +586,32 @@ transitions:
|
|
|
608
586
|
guard:
|
|
609
587
|
kind: always
|
|
610
588
|
|
|
611
|
-
# ── discovery: auto-
|
|
612
|
-
# Declaration order: auto
|
|
613
|
-
# Without
|
|
589
|
+
# ── discovery: auto-accept the eval recommendation (profile=auto + idea_approved) OR enter idea-eval ──
|
|
590
|
+
# Declaration order: auto edges FIRST (same pattern as system-design → design-approval).
|
|
591
|
+
# Without them, discovery always enters idea-eval (pause: true), rendering the prompt
|
|
614
592
|
# and persisting an avoidable pause before the in-state auto-skip guard can fire (0366 R4/R5).
|
|
593
|
+
# --auto accepts the recommendation derived at the end of discovery (-idea-recommendation.txt):
|
|
594
|
+
# drop → cancelled, proceed/reshape → feature-create; unknown/missing falls through to the
|
|
595
|
+
# idea-eval pause (fail-safe: never auto-create a feature without an explicit proceed).
|
|
596
|
+
- from: discovery
|
|
597
|
+
to: cancelled
|
|
598
|
+
terminalReason: cancelled
|
|
599
|
+
description: profile=auto AND idea_approved=true AND eval recommends drop — accept it, no feature.
|
|
600
|
+
guard:
|
|
601
|
+
kind: shell
|
|
602
|
+
options:
|
|
603
|
+
command: >-
|
|
604
|
+
test "$profile" = auto && test "$idea_approved" = true &&
|
|
605
|
+
grep -qx drop .spur/run/$__runId-idea-recommendation.txt
|
|
615
606
|
- from: discovery
|
|
616
607
|
to: feature-create
|
|
617
|
-
description: profile=auto AND idea_approved=true — skip idea-eval taste gate
|
|
608
|
+
description: profile=auto AND idea_approved=true AND eval recommends proceed/reshape — skip idea-eval taste gate.
|
|
618
609
|
guard:
|
|
619
610
|
kind: shell
|
|
620
611
|
options:
|
|
621
|
-
command:
|
|
612
|
+
command: >-
|
|
613
|
+
test "$profile" = auto && test "$idea_approved" = true &&
|
|
614
|
+
grep -qxE 'proceed|reshape' .spur/run/$__runId-idea-recommendation.txt
|
|
622
615
|
- from: discovery
|
|
623
616
|
to: idea-eval
|
|
624
617
|
description: Discovery complete — gate on idea evaluation taste decision.
|
|
@@ -629,11 +622,13 @@ transitions:
|
|
|
629
622
|
# Declaration order: auto-skip FIRST (same pattern as system-design → design-approval).
|
|
630
623
|
- from: idea-eval
|
|
631
624
|
to: feature-create
|
|
632
|
-
description: profile=auto AND idea_approved=true — skip idea-eval taste gate.
|
|
625
|
+
description: profile=auto AND idea_approved=true AND eval recommends proceed/reshape — skip idea-eval taste gate.
|
|
633
626
|
guard:
|
|
634
627
|
kind: shell
|
|
635
628
|
options:
|
|
636
|
-
command:
|
|
629
|
+
command: >-
|
|
630
|
+
test "$profile" = auto && test "$idea_approved" = true &&
|
|
631
|
+
grep -qxE 'proceed|reshape' .spur/run/$__runId-idea-recommendation.txt
|
|
637
632
|
- from: idea-eval
|
|
638
633
|
to: feature-create
|
|
639
634
|
description: Idea evaluation approved — create or select a feature.
|
|
@@ -694,32 +689,32 @@ transitions:
|
|
|
694
689
|
test "$profile" = auto &&
|
|
695
690
|
test "$(cat .spur/run/$__runId-idea-ac-ready.status 2>/dev/null)" = PASS &&
|
|
696
691
|
test "$(cat .spur/run/$__runId-idea-design-route.txt 2>/dev/null)" = skip
|
|
697
|
-
# Auto-skip 3: check
|
|
692
|
+
# Auto-skip 3: check failed (incl. inventory coverage), retry < 3 → loop back to ac-generate (self-loop)
|
|
698
693
|
- from: ac-generate
|
|
699
694
|
to: ac-generate
|
|
700
|
-
description: "profile=auto, check
|
|
701
|
-
# (warn)
|
|
702
|
-
# (with its 0 fallback); the
|
|
703
|
-
#
|
|
695
|
+
description: "profile=auto, check failed (incl. inventory coverage), retry cap not reached — re-run ac-generate."
|
|
696
|
+
# (warn) 4 commands: one persistent multi-assignment line captures the check status and the retry
|
|
697
|
+
# count (with its 0 fallback); the profile gate folds into the retry test via `test -a`; the retry
|
|
698
|
+
# loop is the smallest honest formulation of cap<3 routing (0769).
|
|
704
699
|
guard:
|
|
705
700
|
kind: shell
|
|
706
701
|
options:
|
|
707
702
|
command: >-
|
|
708
|
-
ac_status="$(cat .spur/run/$__runId-idea-ac-check.status 2>/dev/null)"
|
|
709
|
-
|
|
710
|
-
# Auto-skip 4: check
|
|
703
|
+
ac_status="$(cat .spur/run/$__runId-idea-ac-check.status 2>/dev/null)" retry="$(cat .spur/run/$__runId-idea-ac-retry-count 2>/dev/null || echo 0)";
|
|
704
|
+
test "$ac_status" != PASS && test "$profile" = auto -a "$retry" -lt 3
|
|
705
|
+
# Auto-skip 4: check failed (incl. inventory coverage), retry cap reached → escalate to failed
|
|
711
706
|
- from: ac-generate
|
|
712
707
|
to: failed
|
|
713
708
|
terminalReason: retry-exhausted
|
|
714
|
-
description: "profile=auto, check
|
|
715
|
-
# (warn)
|
|
709
|
+
description: "profile=auto, check failed (incl. inventory coverage) after 3 retries — escalate to failed."
|
|
710
|
+
# (warn) 4 commands: mirror of the retry guard with cap>=3; keeping escalation and retry as one
|
|
716
711
|
# test-chain pair makes the cap boundary auditable in the diff (0769).
|
|
717
712
|
guard:
|
|
718
713
|
kind: shell
|
|
719
714
|
options:
|
|
720
715
|
command: >-
|
|
721
|
-
ac_status="$(cat .spur/run/$__runId-idea-ac-check.status 2>/dev/null)"
|
|
722
|
-
|
|
716
|
+
ac_status="$(cat .spur/run/$__runId-idea-ac-check.status 2>/dev/null)" retry="$(cat .spur/run/$__runId-idea-ac-retry-count 2>/dev/null || echo 0)";
|
|
717
|
+
test "$ac_status" != PASS && test "$profile" = auto -a "$retry" -ge 3
|
|
723
718
|
# Interactive fallback: enter feature-check HITL gate
|
|
724
719
|
- from: ac-generate
|
|
725
720
|
to: feature-check
|
|
@@ -50,6 +50,7 @@ vars:
|
|
|
50
50
|
noWait: "false"
|
|
51
51
|
waitTimeoutSec: "600"
|
|
52
52
|
waitIntervalSec: "30"
|
|
53
|
+
spurBin: "spur"
|
|
53
54
|
preReviewCmd: ""
|
|
54
55
|
__runId: ""
|
|
55
56
|
# Runtime-set by file.read.into-var (0771): the request record's requestedAt|head,
|
|
@@ -65,15 +66,23 @@ states:
|
|
|
65
66
|
before any push can publish it).
|
|
66
67
|
Writes PASS|FAIL to .spur/run/${vars.__runId}-pr-preflight.status; always exit 0.
|
|
67
68
|
onEnter:
|
|
69
|
+
# 1007 R8: run-start script-resolution identity (same command as feature-verification
|
|
70
|
+
# verify's first action) — records which tree this run resolved (source-repo vs
|
|
71
|
+
# installed) into .spur/run/$__runId-script-root.json; later plugin-script actions
|
|
72
|
+
# resolve through it (1007 R4 snippet). Never aborts.
|
|
73
|
+
- kind: shell
|
|
74
|
+
options:
|
|
75
|
+
command: >-
|
|
76
|
+
S=plugins/sp/scripts/script-root.ts; [ -f config/plugin-scripts.json -a -f "$S" ] || S="$(superskill script path sp script-root.mjs 2>/dev/null)"; RUNNER=bun; case "$S" in *.mjs) RUNNER=node ;; esac; [ -f "$S" ] && "$RUNNER" "$S" --run-id "$__runId" --spur-bin "$spurBin" || echo "script-root failed closed — run 'superskill install sp --marketplace gobing-ai/spur'" >&2; exit 0
|
|
68
77
|
- kind: shell
|
|
69
78
|
options:
|
|
70
79
|
# (e) 0825: 10 lines — detached-HEAD/dirty/gh-auth/base-refusal probes must record
|
|
71
80
|
# before any push can publish; split would let a half-probed run continue.
|
|
72
81
|
command: >-
|
|
73
|
-
|
|
82
|
+
|
|
74
83
|
STATUS_FILE=".spur/run/$__runId-pr-preflight.status" &&
|
|
75
84
|
set +e &&
|
|
76
|
-
|
|
85
|
+
eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/pr-reviewing.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/pr-reviewing.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)"; "$RUNNER" "$S" preflight --base "$baseBranch" --json > ".spur/run/$__runId-pr-context.json";
|
|
77
86
|
rc=$?; set -e &&
|
|
78
87
|
if [ "$rc" -eq 0 ]; then printf 'PASS\n' > "$STATUS_FILE"; else printf 'FAIL\n' > "$STATUS_FILE"; fi &&
|
|
79
88
|
exit 0
|
|
@@ -88,10 +97,10 @@ states:
|
|
|
88
97
|
# (e) 0825: 9 lines — hygiene verdict + json capture land together; the status-file
|
|
89
98
|
# fallback keeps a silent driver from passing the gate.
|
|
90
99
|
command: >-
|
|
91
|
-
|
|
100
|
+
|
|
92
101
|
STATUS_FILE=".spur/run/$__runId-pr-hygiene.status" &&
|
|
93
102
|
set +e &&
|
|
94
|
-
|
|
103
|
+
eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/pr-reviewing.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/pr-reviewing.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)"; "$RUNNER" "$S" hygiene --base "$baseBranch" --json
|
|
95
104
|
--status-file "$STATUS_FILE" > ".spur/run/$__runId-pr-hygiene.json";
|
|
96
105
|
rc=$?; set -e &&
|
|
97
106
|
if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
|
|
@@ -122,7 +131,7 @@ states:
|
|
|
122
131
|
mkdir -p .spur/run &&
|
|
123
132
|
STATUS_FILE=".spur/run/$__runId-pr-push.status" &&
|
|
124
133
|
set +e &&
|
|
125
|
-
|
|
134
|
+
eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/pr-reviewing.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/pr-reviewing.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)"; "$RUNNER" "$S" push --json --status-file "$STATUS_FILE"
|
|
126
135
|
> ".spur/run/$__runId-pr-push.json";
|
|
127
136
|
rc=$?; set -e &&
|
|
128
137
|
if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
|
|
@@ -139,7 +148,7 @@ states:
|
|
|
139
148
|
mkdir -p .spur/run &&
|
|
140
149
|
STATUS_FILE=".spur/run/$__runId-pr-ensure.status" &&
|
|
141
150
|
set +e &&
|
|
142
|
-
|
|
151
|
+
eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/pr-reviewing.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/pr-reviewing.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)"; "$RUNNER" "$S" ensure-pr --base "$baseBranch" --json
|
|
143
152
|
--status-file "$STATUS_FILE" > ".spur/run/$__runId-pr.json";
|
|
144
153
|
rc=$?; set -e &&
|
|
145
154
|
if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
|
|
@@ -155,7 +164,7 @@ states:
|
|
|
155
164
|
# (e) 0825: 10 lines — the write-then-read split is the file-var transport feeding
|
|
156
165
|
# wait/collect and must stay one action (same record, same run scope).
|
|
157
166
|
command: >-
|
|
158
|
-
|
|
167
|
+
F="$([ "$mode" = rerun ] && echo --force)"; eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/pr-reviewing.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/pr-reviewing.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)"; "$RUNNER" "$S" request --focus "$focus" $F --json --status-file ".spur/run/$__runId-pr-request.status" > ".spur/run/$__runId-pr-request.json"; [ -f ".spur/run/$__runId-pr-request.status" ] || echo FAIL > ".spur/run/$__runId-pr-request.status"; jq -e . ".spur/run/$__runId-pr-request.json" >/dev/null 2>&1 && jq -r '.requestedAt // ""' ".spur/run/$__runId-pr-request.json" > ".spur/run/$__runId-pr-since.txt" && jq -r '.head // ""' ".spur/run/$__runId-pr-request.json" > ".spur/run/$__runId-pr-head.txt"; exit 0
|
|
159
168
|
|
|
160
169
|
- id: wait
|
|
161
170
|
description: >
|
|
@@ -180,7 +189,7 @@ states:
|
|
|
180
189
|
mkdir -p .spur/run &&
|
|
181
190
|
STATUS_FILE=".spur/run/$__runId-pr-wait.status" &&
|
|
182
191
|
set +e &&
|
|
183
|
-
|
|
192
|
+
eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/pr-reviewing.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/pr-reviewing.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)"; "$RUNNER" "$S" wait --since "$prSince" --head "$prHead" --timeout "$waitTimeoutSec" --interval "$waitIntervalSec"
|
|
184
193
|
--json --status-file "$STATUS_FILE" > ".spur/run/$__runId-pr-wait.json";
|
|
185
194
|
rc=$?; set -e &&
|
|
186
195
|
if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
|
|
@@ -204,7 +213,7 @@ states:
|
|
|
204
213
|
# (e) 0825: 9 lines — collect + status must run against the same since/head pair
|
|
205
214
|
# before the composite status is decided (same 0771 record contract).
|
|
206
215
|
command: >-
|
|
207
|
-
mkdir -p .spur/run;
|
|
216
|
+
mkdir -p .spur/run; eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/pr-reviewing.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/pr-reviewing.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)"; "$RUNNER" "$S" collect --since "$prSince" --head "$prHead" --json --status-file ".spur/run/$__runId-pr-collect.status" > ".spur/run/$__runId-pr-findings.json"; c=$?; "$RUNNER" "$S" status --since "$prSince" --head "$prHead" --json > ".spur/run/$__runId-pr-status.json" && [ "$c" -eq 0 ] && [ -f ".spur/run/$__runId-pr-collect.status" ] || printf 'FAIL\n' > ".spur/run/$__runId-pr-collect.status"; cat ".spur/run/$__runId-pr-findings.json" 2>/dev/null; exit 0
|
|
208
217
|
|
|
209
218
|
- id: done
|
|
210
219
|
description: Terminal — review collected; findings artifact at .spur/run/${vars.__runId}-pr-findings.json
|