@gobing-ai/spur 0.3.92 → 0.3.94
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 +0 -7
- package/config/plugin-scripts.json +10 -0
- package/config/rules/boundary/test-subpath-boundary.yaml +48 -0
- package/config/rules/strict/runtime-boundaries.yaml +2 -1
- package/config/rules/structure/protected-files.yaml +4 -0
- package/config/templates/AGENTS.md +4 -0
- package/config/templates/docs/02_ROADMAP.md +2 -0
- package/config/templates/docs/03_ARCHITECTURE.md +3 -1
- package/config/templates/docs/04_DESIGN.md +2 -0
- package/config/templates/docs/99_PROJECT_CONSTITUTION.md +10 -2
- package/config/workflow-candidates.json +72 -1
- package/config/workflows/feature-verification.yaml +1 -0
- package/config/workflows/history-anatomy.yaml +2 -0
- package/config/workflows/idea-pipeline.yaml +67 -18
- package/config/workflows/pr-review.yaml +8 -0
- package/config/workflows/task-pipeline.yaml +171 -39
- package/config/workflows/wayfinder-resolution.yaml +5 -0
- package/config/workflows/wrapup-pipeline.yaml +55 -14
- package/package.json +9 -9
- package/plugins/sp/README.md +8 -3
- package/plugins/sp/commands/dev-review-session.md +4 -4
- package/plugins/sp/commands/dev-review.md +16 -5
- package/plugins/sp/commands/dev-run.md +2 -2
- package/plugins/sp/commands/dev-runall.md +2 -2
- package/plugins/sp/hooks/pi/guard-extension.ts +17 -36
- package/plugins/sp/lib/idea-handoff.generated.mjs +8 -4
- package/plugins/sp/lib/inline-run.generated.d.mts +3 -0
- package/plugins/sp/lib/inline-run.generated.mjs +48 -19
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/scripts/inline-pipeline-parity-check.ts +1 -1
- package/plugins/sp/scripts/inline-run-setup.mjs +117 -7
- package/plugins/sp/scripts/inline-run-setup.ts +211 -7
- package/plugins/sp/scripts/quality-gate.mjs +255 -6
- package/plugins/sp/scripts/quality-gate.ts +425 -9
- package/plugins/sp/scripts/residual-scan.mjs +13 -5
- package/plugins/sp/scripts/residual-scan.ts +34 -7
- package/plugins/sp/scripts/task-diffstat.mjs +156 -0
- package/plugins/sp/scripts/task-diffstat.ts +229 -0
- package/plugins/sp/scripts/wrapup-drift-probe.mjs +181 -0
- package/plugins/sp/scripts/wrapup-drift-probe.ts +258 -0
- package/plugins/sp/scripts/wrapup-steps.mjs +60 -1
- package/plugins/sp/scripts/wrapup-steps.ts +89 -4
- package/plugins/sp/skills/brainstorm/SKILL.md +2 -0
- package/plugins/sp/skills/brainstorm/references/workflows.md +17 -2
- package/plugins/sp/skills/code-verification/SKILL.md +2 -2
- package/plugins/sp/skills/code-verification/references/secu-review.md +3 -2
- package/plugins/sp/skills/session-review/SKILL.md +11 -9
- package/plugins/sp/skills/spur-check/SKILL.md +112 -0
- package/plugins/sp/skills/spur-dev/SKILL.md +2 -1
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +14 -2
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +8 -2
- package/plugins/sp/skills/spur-dev/references/document-authoring.md +85 -0
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +46 -18
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +24 -3
- package/plugins/sp/skills/spur-dev/references/gate-checklists.md +3 -2
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +34 -2
- package/plugins/sp/skills/spur-dev/references/planning-workflow.md +5 -5
- package/plugins/sp/skills/spur-dev/templates/design.md +31 -0
- package/plugins/sp/skills/spur-dev/templates/plan.md +32 -0
- package/plugins/sp/skills/spur-doctor/SKILL.md +60 -14
- package/schemas/state-machine-workflow.schema.json +4 -0
- package/spur.js +19577 -19822
- package/web/_astro/BoardApp.C02hAHPO.js +1 -0
- package/web/_astro/{BoardApp.CerSBgis.js → BoardApp.FTEs3-N8.js} +107 -105
- package/web/_astro/{TaskDetail.DCqiC-OZ.js → TaskDetail.C-GdsS-t.js} +1 -1
- package/web/_astro/arc.uuAf51IT.js +1 -0
- package/web/_astro/{architectureDiagram-3BPJPVTR.DM_vp_hO.js → architectureDiagram-3BPJPVTR.CGe629A1.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.DXVIiv0p.js → blockDiagram-GPEHLZMM.D1mGCq3p.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.BbF_zCxW.js → c4Diagram-AAUBKEIU.CMsolcde.js} +1 -1
- package/web/_astro/channel.fsgl7o5j.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.CAgQHpPC.js → chunk-2J33WTMH.CrGA3fik.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.BN-5tpw4.js → chunk-4BX2VUAB.DsLVVla0.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.CnPkEEr0.js → chunk-55IACEB6.Dxc59Tfi.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.BQzQeMVm.js → chunk-727SXJPM.CaEVE2Wy.js} +4 -4
- package/web/_astro/{chunk-AQP2D5EJ.B6xNyDnL.js → chunk-AQP2D5EJ.BiJ4HXeI.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.C7f9Ih78.js → chunk-FMBD7UC4.Mxf1fru5.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.CNV1dFXT.js → chunk-ND2GUHAM.pyOWQixH.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.Cudn2TkJ.js → chunk-QZHKN3VN.BmEsg4vr.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.D1NwP50q.js → classDiagram-4FO5ZUOK.BHhhMFTO.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.D1NwP50q.js → classDiagram-v2-Q7XG4LA2.BHhhMFTO.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.B1wSL-Xb.js → cose-bilkent-S5V4N54A.2fH4YOlp.js} +1 -1
- package/web/_astro/{cynefin-OW5HDTMX.BmK52w8G.js → cynefin-OW5HDTMX.C2j1_lKL.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.Bfy5CTDT.js → dagre-BM42HDAG.hZ2NCTdT.js} +2 -2
- package/web/_astro/diagram-2AECGRRQ.Bfw5_EzK.js +43 -0
- package/web/_astro/diagram-5GNKFQAL.Bt1V_Tmk.js +10 -0
- package/web/_astro/{diagram-KO2AKTUF.CW_vMJ4z.js → diagram-KO2AKTUF.DEk-YFwp.js} +3 -3
- package/web/_astro/{diagram-LMA3HP47.B_8ZGF67.js → diagram-LMA3HP47.CDjndtQm.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.BppnHsdS.js → diagram-OG6HWLK6.cFnUHScG.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.BEuHXcjJ.js → erDiagram-TEJ5UH35.DlhYp7NV.js} +5 -5
- package/web/_astro/{flowDiagram-I6XJVG4X.CH-UlnGr.js → flowDiagram-I6XJVG4X.DNTpsxfx.js} +4 -4
- package/web/_astro/{ganttDiagram-6RSMTGT7.BO81S85v.js → ganttDiagram-6RSMTGT7.DC_p36PI.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.XnPxPPZN.js → gitGraphDiagram-PVQCEYII.DkEqNI0P.js} +1 -1
- package/web/_astro/{infoDiagram-5YYISTIA.JyjYRu_T.js → infoDiagram-5YYISTIA.CrjioCTG.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.BBRBF-Fo.js → ishikawaDiagram-YF4QCWOH.BcK0CN8n.js} +5 -5
- package/web/_astro/{journeyDiagram-JHISSGLW.C_iymSyp.js → journeyDiagram-JHISSGLW.p0CbBDX1.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.DdfW-Oqt.js → kanban-definition-UN3LZRKU.puHIFt6J.js} +7 -7
- package/web/_astro/{linear.C2_IkbZT.js → linear.Bb-3a1d7.js} +1 -1
- package/web/_astro/mermaid.core.CJDgXOJs.js +301 -0
- package/web/_astro/{mindmap-definition-RKZ34NQL.DAZIxQSK.js → mindmap-definition-RKZ34NQL.BoAZEI9t.js} +2 -2
- package/web/_astro/{pieDiagram-4H26LBE5.CN8sIhKM.js → pieDiagram-4H26LBE5.CJNSdqY7.js} +3 -3
- package/web/_astro/{quadrantDiagram-W4KKPZXB.3dGcX5GP.js → quadrantDiagram-W4KKPZXB.DtTy7_0Z.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.BV2y4dd6.js → requirementDiagram-4Y6WPE33.BNYV98Xg.js} +3 -3
- package/web/_astro/{sankeyDiagram-5OEKKPKP.Cqo15Tvo.js → sankeyDiagram-5OEKKPKP.DRq9DGHp.js} +4 -4
- package/web/_astro/{sequenceDiagram-3UESZ5HK.CROCPMJB.js → sequenceDiagram-3UESZ5HK.B7KdBFCm.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.RfXZrkFE.js → stateDiagram-AJRCARHV.CD62ZJ2H.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.CPXmbBs9.js → stateDiagram-v2-BHNVJYJU.CeVk1TAj.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.DdgKTiO8.js → timeline-definition-PNZ67QCA.C_ZPA5tT.js} +3 -3
- package/web/_astro/{vennDiagram-CIIHVFJN.CPNVSHF1.js → vennDiagram-CIIHVFJN.CrThO_FQ.js} +5 -5
- package/web/_astro/{wardleyDiagram-YWT4CUSO.CQhA0Jyr.js → wardleyDiagram-YWT4CUSO.DSZCA5nl.js} +3 -3
- package/web/_astro/{xychartDiagram-2RQKCTM6.n61BWyy4.js → xychartDiagram-2RQKCTM6.KI7baTuk.js} +1 -1
- package/web/index.html +1 -1
- package/config/workflows/decision-routing-example.yaml +0 -134
- package/web/_astro/BoardApp.eoTz0pZs.js +0 -1
- package/web/_astro/arc.CPwg6Rw0.js +0 -1
- package/web/_astro/channel.MYZLKNwy.js +0 -1
- package/web/_astro/diagram-2AECGRRQ.DhNnvUvX.js +0 -43
- package/web/_astro/diagram-5GNKFQAL.lTX5KwnS.js +0 -10
- package/web/_astro/mermaid.core.GAOYeSR0.js +0 -303
|
@@ -286,6 +286,13 @@ states:
|
|
|
286
286
|
# a silent no-op routes the run to `failed` here instead of drifting
|
|
287
287
|
# into test/review and being caught a full pass later.
|
|
288
288
|
requireDiff: true
|
|
289
|
+
# Verification-only re-run admission (task 0976): when requireDiff
|
|
290
|
+
# sees zero non-corpus changes because the implementation already
|
|
291
|
+
# landed through another path, `spur task check <wbs>` PASS admits
|
|
292
|
+
# the empty implement as a certification pass; a check failure
|
|
293
|
+
# keeps the 0424 R3 empty-implement violation. Static option —
|
|
294
|
+
# deliberately no run-var knob (ADR-115).
|
|
295
|
+
requireDiffAllowCleanCheck: true
|
|
289
296
|
# 0933 R26: escalation contract — the agent.run option names the QUESTION
|
|
290
297
|
# file (the pause signal, deleted pre-dispatch for freshness); a paused
|
|
291
298
|
# attempt (agent wrote its question there and exited 0) succeeds with
|
|
@@ -486,8 +493,8 @@ states:
|
|
|
486
493
|
- id: test-recheck
|
|
487
494
|
description: >
|
|
488
495
|
Soft recheck after fixall with bounded SQLite-lock retry. Writes PASS|FAIL (always exit 0). Transitions
|
|
489
|
-
branch to
|
|
490
|
-
or the pipeline `failed` state (
|
|
496
|
+
branch to `triage` (PASS — the 0943 lane router), `test-fail-triage` (FAIL — the 0943
|
|
497
|
+
failure-class router), or the pipeline `failed` state (corrupt status) — never a
|
|
491
498
|
raw lifecycle abort that skips the terminal `failed` state.
|
|
492
499
|
onEnter:
|
|
493
500
|
# R4 (0703, ADR-071): bounded remediation mutated the tree by design, so the fresh evidence
|
|
@@ -510,6 +517,92 @@ states:
|
|
|
510
517
|
command: >-
|
|
511
518
|
mkdir -p .spur/run; if [ -f plugins/sp/scripts/quality-gate.ts ]; then bun plugins/sp/scripts/quality-gate.ts recheck; elif Q="$(superskill script path sp quality-gate.mjs 2>/dev/null)" && [ -f "$Q" ]; then node "$Q" recheck; else echo "quality gate failed closed — quality-gate script not found — run 'superskill install sp'" >&2; printf 'FAIL\n' > ".spur/run/$wbs-test-gate.status"; fi; exit 0
|
|
512
519
|
|
|
520
|
+
- id: triage
|
|
521
|
+
description: >-
|
|
522
|
+
Deterministic lane router between a green gate and the review/verify fork (0943 R1).
|
|
523
|
+
Writes the diffstat evidence file, honors a caller-set `mode` (never overridden), pins
|
|
524
|
+
the safety lane on sensitive paths or >400 changed lines without a model call (R2c),
|
|
525
|
+
otherwise consults `decide task-triage` (low → fast lane; anything else stays empty →
|
|
526
|
+
standard review path), and appends the triage route reason to
|
|
527
|
+
.spur/memory/task-pipeline-routes.log (R5). The `decide` action itself runs
|
|
528
|
+
unconditionally (the engine has no onEnter conditionals); its result is consulted only
|
|
529
|
+
when neither a caller mode nor the deterministic guard resolved the lane. The resolved
|
|
530
|
+
lane lands in the `mode` var for the triage → verify/review guards.
|
|
531
|
+
onEnter:
|
|
532
|
+
# (a) diffstat producer: task-diffstat.ts owns git reading and sensitive-path
|
|
533
|
+
# classification; shell only resolves it and fails closed (writes sensitive:true,
|
|
534
|
+
# which the pre-guard below maps to the safety lane).
|
|
535
|
+
- kind: shell
|
|
536
|
+
options:
|
|
537
|
+
command: >-
|
|
538
|
+
mkdir -p .spur/run; if [ -f plugins/sp/scripts/task-diffstat.ts ]; then bun plugins/sp/scripts/task-diffstat.ts --spur-bin "$spurBin"; elif D="$(superskill script path sp task-diffstat.mjs 2>/dev/null)" && [ -f "$D" ]; then node "$D"; else echo "task-diffstat failed closed — task-diffstat script not found — run 'superskill install sp'" >&2; printf '{"files":0,"insertions":0,"deletions":0,"paths":[],"sensitive":true}\n' > ".spur/run/$wbs-diffstat.json"; fi; exit 0
|
|
539
|
+
# (b)+(c) lane pre-guard BEFORE decide: a caller-set mode is projected verbatim (R2b);
|
|
540
|
+
# a sensitive path or >400 changed lines pins safety (R2c) and the decide result below
|
|
541
|
+
# is never consulted. A missing/malformed diffstat row (producer crashed or never ran,
|
|
542
|
+
# disk error) pins safety HERE: an empty mode file would let the low decide row project
|
|
543
|
+
# the fast lane downstream, so the "never to fast" fail-safe is enforced at the guard,
|
|
544
|
+
# not by the projection (the full-suite gate run exposed this fail-open path).
|
|
545
|
+
- kind: shell
|
|
546
|
+
options:
|
|
547
|
+
command: >-
|
|
548
|
+
mkdir -p .spur/run; if [ -n "$mode" ]; then printf '%s\n' "$mode" > ".spur/run/$wbs-mode.txt"; exit 0; fi; DF=".spur/run/$wbs-diffstat.json"; if ! jq -e 'type == "object"' "$DF" >/dev/null 2>&1; then printf 'safety\n' > ".spur/run/$wbs-mode.txt"; exit 0; fi; jq -r 'if .sensitive == true or ((.insertions // 0) + (.deletions // 0)) > 400 then "safety" else empty end' "$DF" 2>/dev/null > ".spur/run/$wbs-mode.txt"; exit 0
|
|
549
|
+
# (d) lane decision — degrades to the standard default whenever workflow.decideDecisionMaker
|
|
550
|
+
# is off (R4), so with the flag off this state is pure shell: no model call is made.
|
|
551
|
+
- kind: decide
|
|
552
|
+
options:
|
|
553
|
+
id: task-triage
|
|
554
|
+
method: choice
|
|
555
|
+
question: >-
|
|
556
|
+
The quality gate is green. Which verification lane does this diff deserve —
|
|
557
|
+
low (small, contained diff — fast lane), standard, or high caution?
|
|
558
|
+
choices: [low, standard, high]
|
|
559
|
+
default: standard
|
|
560
|
+
evidence:
|
|
561
|
+
- .spur/run/${vars.wbs}-diffstat.json
|
|
562
|
+
- ${vars.taskSpecPath}
|
|
563
|
+
resultFile: .spur/run/${vars.wbs}-triage.decision
|
|
564
|
+
# (d) project the decision: low → fast lane; anything else (standard/high, degraded
|
|
565
|
+
# default, missing row) leaves the mode empty → standard review path. A non-empty mode
|
|
566
|
+
# file (caller-set or deterministic-high) is never overridden.
|
|
567
|
+
- kind: shell
|
|
568
|
+
options:
|
|
569
|
+
command: >-
|
|
570
|
+
MF=".spur/run/$wbs-mode.txt"; [ -s "$MF" ] && exit 0; jq -r 'if .value == "low" then "fast" else empty end' ".spur/run/$wbs-triage.decision" 2>/dev/null > "$MF"; exit 0
|
|
571
|
+
# R5: append the triage route reason in the shared routes-log format.
|
|
572
|
+
- kind: shell
|
|
573
|
+
options:
|
|
574
|
+
command: >-
|
|
575
|
+
m="$(cat ".spur/run/$wbs-mode.txt")"; RUN_ID="$__runId"; [ -n "$RUN_ID" ] || RUN_ID="pipeline-$wbs"; mkdir -p .spur/memory; printf '%s %s %s\n' "$RUN_ID" "$wbs" "$(jq -rn --arg m "$m" --arg c "$mode" 'if $c != "" then ($c + ":caller-set") else {"fast":"fast:triage low lane","safety":"safety:triage deterministic-high","":"safety:triage standard lane"}[$m] // "safety:triage unrecognized mode" end')" >> .spur/memory/task-pipeline-routes.log
|
|
576
|
+
# (d) the resolved lane becomes the `mode` var for the triage → verify/review guards.
|
|
577
|
+
- kind: file.read.into-var
|
|
578
|
+
options:
|
|
579
|
+
path: .spur/run/${vars.wbs}-mode.txt
|
|
580
|
+
var: mode
|
|
581
|
+
|
|
582
|
+
- id: test-fail-triage
|
|
583
|
+
description: >-
|
|
584
|
+
Deterministic failure-class router on a red gate (0943 R3). The engine has no onEnter
|
|
585
|
+
conditionals, so the FAIL branch from `test`/`test-recheck` lands here as its own
|
|
586
|
+
deterministic state (the sanctioned alternative), while the green branch goes to
|
|
587
|
+
`triage`. `decide failure-class` reads the bounded gate findings and routes: fix →
|
|
588
|
+
test-fix (the bounded repair hop; its default, recorded as `source: default` when no
|
|
589
|
+
backend decides — 0976 R2), stop → failed with terminalReason failed-check. A
|
|
590
|
+
missing/corrupt decision fails closed to failed-check. (0976 R2 collapsed the former
|
|
591
|
+
`retryable` lane: the declared default made it unreachable on the inline path.)
|
|
592
|
+
onEnter:
|
|
593
|
+
- kind: decide
|
|
594
|
+
options:
|
|
595
|
+
id: failure-class
|
|
596
|
+
method: choice
|
|
597
|
+
question: >-
|
|
598
|
+
The quality gate failed. Is the failure fixable by the repair agent, or should
|
|
599
|
+
the run stop here?
|
|
600
|
+
choices: [fix, stop]
|
|
601
|
+
default: fix
|
|
602
|
+
evidence:
|
|
603
|
+
- .spur/run/${vars.wbs}-test-gate.findings
|
|
604
|
+
resultFile: .spur/run/${vars.wbs}-failure-class.decision
|
|
605
|
+
|
|
513
606
|
- id: review
|
|
514
607
|
description: Three-dimensional code review via /sp:dev-review (functional requirements traceability + SECUA framework (Security, Efficiency, Correctness, Usability, Architecture) + architecture depth), findings written to `## Review`.
|
|
515
608
|
onEnter:
|
|
@@ -779,6 +872,7 @@ transitions:
|
|
|
779
872
|
test "$size_status" = PASS && test "$evidence_status" = PASS && $spurBin task check $wbs
|
|
780
873
|
- from: precheck
|
|
781
874
|
to: failed
|
|
875
|
+
terminalReason: failed-check
|
|
782
876
|
description: Size and/or task check failed — stop before implement.
|
|
783
877
|
guard:
|
|
784
878
|
kind: always
|
|
@@ -791,6 +885,7 @@ transitions:
|
|
|
791
885
|
# fresh question file so a COMPLETED implement after max asks still routes to test.
|
|
792
886
|
- from: implement
|
|
793
887
|
to: failed
|
|
888
|
+
terminalReason: retry-exhausted
|
|
794
889
|
description: Escalation bound exhausted — the agent paused again after maxEscalations operator answers.
|
|
795
890
|
# 0933 R30 (guard-lines compression): thin predicate; the report note is written
|
|
796
891
|
# by the failed state's onEnter when it observes a bound-exhausted pause.
|
|
@@ -826,38 +921,36 @@ transitions:
|
|
|
826
921
|
command: 'test -n "$__hitlInput"'
|
|
827
922
|
- from: escalate
|
|
828
923
|
to: failed
|
|
924
|
+
terminalReason: cancelled
|
|
829
925
|
description: Empty operator answer — give-up routes to failed (question + transcript preserved as evidence).
|
|
830
926
|
guard:
|
|
831
927
|
kind: shell
|
|
832
928
|
options:
|
|
833
929
|
command: 'test -z "$__hitlInput"'
|
|
834
|
-
# Soft probe branching (declaration order: PASS
|
|
930
|
+
# Soft probe branching (declaration order: PASS → triage, FAIL → test-fail-triage, defense).
|
|
931
|
+
# 0943 R1/R3: the four former gate-PASS edges (test/test-recheck → verify/review, split on
|
|
932
|
+
# `$mode`) are replaced by the deterministic `triage` lane producer; a red gate lands in
|
|
933
|
+
# `test-fail-triage` where `decide failure-class` routes the failure instead of a static fixall.
|
|
835
934
|
- from: test
|
|
836
|
-
to:
|
|
837
|
-
description: Quality gate
|
|
838
|
-
guard:
|
|
839
|
-
kind: shell
|
|
840
|
-
options:
|
|
841
|
-
command: >-
|
|
842
|
-
gate_status="$(cat .spur/run/$wbs-test-gate.status 2>/dev/null)";
|
|
843
|
-
test "$gate_status" = PASS && test "$mode" = fast
|
|
844
|
-
- from: test
|
|
845
|
-
to: review
|
|
846
|
-
description: Quality gate already green and safety mode — proceed to review.
|
|
935
|
+
to: triage
|
|
936
|
+
description: Quality gate green — route the lane deterministically (triage, 0943 R1).
|
|
847
937
|
guard:
|
|
848
938
|
kind: shell
|
|
849
939
|
options:
|
|
850
940
|
command: >-
|
|
851
941
|
gate_status="$(cat .spur/run/$wbs-test-gate.status 2>/dev/null)";
|
|
852
|
-
test "$gate_status" = PASS
|
|
942
|
+
test "$gate_status" = PASS
|
|
853
943
|
- from: test
|
|
854
|
-
to: test-
|
|
855
|
-
description: Quality gate red —
|
|
944
|
+
to: test-fail-triage
|
|
945
|
+
description: Quality gate red — classify the failure before the repair hop (0943 R3).
|
|
856
946
|
guard:
|
|
857
947
|
kind: shell
|
|
858
948
|
options:
|
|
859
949
|
command: 'test "$(cat .spur/run/$wbs-test-gate.status 2>/dev/null)" = FAIL'
|
|
860
|
-
#
|
|
950
|
+
# 0943 review P3#2: the former `test → test-fix` FAIL edge is removed — it was dead (the
|
|
951
|
+
# identical guard on test → test-fail-triage fires first) and a silent spec-bypass trap:
|
|
952
|
+
# restoring it would skip failure-class on every red gate. The always-defense below keeps
|
|
953
|
+
# pre-0943 corrupt-status behavior (fixall then recheck).
|
|
861
954
|
- from: test
|
|
862
955
|
to: test-fix
|
|
863
956
|
description: Probe status missing/corrupt — attempt fixall then recheck.
|
|
@@ -868,51 +961,86 @@ transitions:
|
|
|
868
961
|
description: Fixall finished — soft recheck the same quality gate.
|
|
869
962
|
guard:
|
|
870
963
|
kind: always
|
|
871
|
-
# Recheck branching (PASS
|
|
964
|
+
# Recheck branching (PASS → triage; red → test-fail-triage; defense). The two former
|
|
965
|
+
# static FAIL edges (under-max → test-fix, exhausted → failed retry-exhausted) moved into
|
|
966
|
+
# test-fail-triage's decision routing (0943 R3).
|
|
872
967
|
- from: test-recheck
|
|
873
|
-
to:
|
|
874
|
-
description: Quality gate green after fixall
|
|
968
|
+
to: triage
|
|
969
|
+
description: Quality gate green after fixall — route the lane deterministically (triage, 0943 R1).
|
|
875
970
|
guard:
|
|
876
971
|
kind: shell
|
|
877
972
|
options:
|
|
878
973
|
command: >-
|
|
879
974
|
gate_status="$(cat .spur/run/$wbs-test-gate.status 2>/dev/null)";
|
|
880
|
-
test "$gate_status" = PASS
|
|
975
|
+
test "$gate_status" = PASS
|
|
881
976
|
- from: test-recheck
|
|
882
|
-
to:
|
|
883
|
-
description:
|
|
977
|
+
to: test-fail-triage
|
|
978
|
+
description: Still red after fixall — classify the failure (0943 R3).
|
|
884
979
|
guard:
|
|
885
980
|
kind: shell
|
|
886
981
|
options:
|
|
887
982
|
command: >-
|
|
888
983
|
gate_status="$(cat .spur/run/$wbs-test-gate.status 2>/dev/null)";
|
|
889
|
-
test "$gate_status" =
|
|
984
|
+
test "$gate_status" = FAIL
|
|
985
|
+
# Defense: corrupt recheck status — failed, not review.
|
|
890
986
|
- from: test-recheck
|
|
891
|
-
to:
|
|
892
|
-
|
|
893
|
-
|
|
987
|
+
to: failed
|
|
988
|
+
terminalReason: failed-check
|
|
989
|
+
description: Recheck status missing/corrupt — stop at failed.
|
|
990
|
+
guard:
|
|
991
|
+
kind: always
|
|
992
|
+
# ── triage routing (0943 R1/R2): the lane producer replaced the four gate-PASS edges.
|
|
993
|
+
# mode=fast → verify; anything else (standard/high, deterministic-high, degraded default,
|
|
994
|
+
# caller-set non-fast) → review. Together the two guards are exhaustive, so triage never hangs.
|
|
995
|
+
- from: triage
|
|
996
|
+
to: verify
|
|
997
|
+
description: Triage resolved the fast lane (caller-set fast or task-triage low) — skip review.
|
|
998
|
+
guard:
|
|
999
|
+
kind: shell
|
|
1000
|
+
options:
|
|
1001
|
+
command: 'test "$mode" = fast'
|
|
1002
|
+
- from: triage
|
|
1003
|
+
to: review
|
|
1004
|
+
description: Triage resolved a review lane (standard/high, deterministic-high, or caller-set) — review.
|
|
1005
|
+
guard:
|
|
1006
|
+
kind: shell
|
|
1007
|
+
options:
|
|
1008
|
+
command: 'test "$mode" != fast'
|
|
1009
|
+
# ── failure-class routing (0943 R3): stop first (never mislabeled by the cap), then the
|
|
1010
|
+
# attempt cap, then the fix lane, then the fail-closed defense. Declaration order matters.
|
|
1011
|
+
- from: test-fail-triage
|
|
1012
|
+
to: failed
|
|
1013
|
+
terminalReason: failed-check
|
|
1014
|
+
description: Failure class stop — the run terminates at failed, never bypassed.
|
|
894
1015
|
guard:
|
|
895
1016
|
kind: shell
|
|
896
1017
|
options:
|
|
897
1018
|
command: >-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
test "$gate_status" = FAIL && test "$fix_attempts" -lt "$qualityGateMaxFixAttempts"
|
|
901
|
-
- from: test-recheck
|
|
1019
|
+
jq -e '.value == "stop"' ".spur/run/$wbs-failure-class.decision" >/dev/null 2>&1
|
|
1020
|
+
- from: test-fail-triage
|
|
902
1021
|
to: failed
|
|
903
|
-
|
|
904
|
-
|
|
1022
|
+
terminalReason: retry-exhausted
|
|
1023
|
+
description: Attempt cap reached — qualityGateMaxFixAttempts bounds the fix lane.
|
|
1024
|
+
# (warn) 5 commands: named fix attempts (legibility, 0874).
|
|
905
1025
|
guard:
|
|
906
1026
|
kind: shell
|
|
907
1027
|
options:
|
|
908
1028
|
command: >-
|
|
909
|
-
gate_status="$(cat .spur/run/$wbs-test-gate.status 2>/dev/null)";
|
|
910
1029
|
fix_attempts="$(cat .spur/run/$wbs-test-fix-attempt 2>/dev/null || echo 0)";
|
|
911
|
-
test "$
|
|
912
|
-
|
|
913
|
-
|
|
1030
|
+
test "$fix_attempts" -ge "$qualityGateMaxFixAttempts"
|
|
1031
|
+
- from: test-fail-triage
|
|
1032
|
+
to: test-fix
|
|
1033
|
+
description: Failure class fix and under the cap — the bounded repair hop, as before.
|
|
1034
|
+
guard:
|
|
1035
|
+
kind: shell
|
|
1036
|
+
options:
|
|
1037
|
+
command: >-
|
|
1038
|
+
jq -e '.value == "fix"' ".spur/run/$wbs-failure-class.decision" >/dev/null 2>&1
|
|
1039
|
+
# Defense: missing/corrupt failure-class decision — fail closed instead of silently repairing.
|
|
1040
|
+
- from: test-fail-triage
|
|
914
1041
|
to: failed
|
|
915
|
-
|
|
1042
|
+
terminalReason: failed-check
|
|
1043
|
+
description: Failure-class decision missing/corrupt — stop at failed.
|
|
916
1044
|
guard:
|
|
917
1045
|
kind: always
|
|
918
1046
|
# ── review → approve, OR skip the HITL gate entirely when profile=auto (R4) ──
|
|
@@ -947,6 +1075,7 @@ transitions:
|
|
|
947
1075
|
command: 'test "$__hitlAnswer" = yes'
|
|
948
1076
|
- from: approve
|
|
949
1077
|
to: failed
|
|
1078
|
+
terminalReason: cancelled
|
|
950
1079
|
description: Operator rejected at the approval gate — report and stop.
|
|
951
1080
|
guard:
|
|
952
1081
|
kind: shell
|
|
@@ -954,6 +1083,7 @@ transitions:
|
|
|
954
1083
|
command: 'test "$__hitlAnswer" = no'
|
|
955
1084
|
- from: approve
|
|
956
1085
|
to: cancelled
|
|
1086
|
+
terminalReason: cancelled
|
|
957
1087
|
description: Operator cancelled at the approval gate.
|
|
958
1088
|
guard:
|
|
959
1089
|
kind: shell
|
|
@@ -1002,6 +1132,7 @@ transitions:
|
|
|
1002
1132
|
test "$(cat .spur/run/$wbs-test-fix-attempt 2>/dev/null || echo 0)" -lt "$qualityGateMaxFixAttempts"
|
|
1003
1133
|
- from: verify
|
|
1004
1134
|
to: failed
|
|
1135
|
+
terminalReason: retry-exhausted
|
|
1005
1136
|
description: >-
|
|
1006
1137
|
Non-PASS with the fix budget exhausted, or a PASS/missing/malformed verdict whose proof
|
|
1007
1138
|
block is absent or mismatched (task 0703 R5) — block before done; defense catch-all so the
|
|
@@ -1031,6 +1162,7 @@ transitions:
|
|
|
1031
1162
|
test "$verdict" = PASS && test "$proof_digest" = "$proofDigest"
|
|
1032
1163
|
- from: record
|
|
1033
1164
|
to: failed
|
|
1165
|
+
terminalReason: failed-check
|
|
1034
1166
|
description: Task check failed or proof evidence missing/malformed/mismatched — block before done.
|
|
1035
1167
|
guard:
|
|
1036
1168
|
kind: always
|
|
@@ -209,6 +209,7 @@ transitions:
|
|
|
209
209
|
command: 'test "$(cat .spur/run/$__runId-wayfinder-precheck.status 2>/dev/null)" = PASS'
|
|
210
210
|
- from: precheck
|
|
211
211
|
to: failed
|
|
212
|
+
terminalReason: failed-check
|
|
212
213
|
description: "Precheck FAIL — stop before delegation."
|
|
213
214
|
guard:
|
|
214
215
|
kind: always
|
|
@@ -221,6 +222,7 @@ transitions:
|
|
|
221
222
|
command: 'test -s .spur/run/$__runId-wayfinder-answer.md'
|
|
222
223
|
- from: investigate
|
|
223
224
|
to: failed
|
|
225
|
+
terminalReason: failed-agent
|
|
224
226
|
description: "Empty answer capture — investigate produced nothing to verify; stop rather than certify hollow evidence."
|
|
225
227
|
guard:
|
|
226
228
|
kind: shell
|
|
@@ -254,6 +256,7 @@ transitions:
|
|
|
254
256
|
command: 'test "$__hitlAnswer" = yes'
|
|
255
257
|
- from: approve
|
|
256
258
|
to: cancelled
|
|
259
|
+
terminalReason: cancelled
|
|
257
260
|
description: "Operator cancelled the research resolution."
|
|
258
261
|
guard:
|
|
259
262
|
kind: shell
|
|
@@ -261,6 +264,7 @@ transitions:
|
|
|
261
264
|
command: 'test "$__hitlAnswer" = cancel'
|
|
262
265
|
- from: approve
|
|
263
266
|
to: failed
|
|
267
|
+
terminalReason: cancelled
|
|
264
268
|
description: "Operator rejected the research resolution."
|
|
265
269
|
guard:
|
|
266
270
|
kind: shell
|
|
@@ -275,6 +279,7 @@ transitions:
|
|
|
275
279
|
command: 'test "$(cat .spur/run/$__runId-wayfinder-final.status 2>/dev/null)" = PASS && test "$(cat .spur/run/$__runId-wayfinder-status.txt 2>/dev/null)" = done'
|
|
276
280
|
- from: record
|
|
277
281
|
to: failed
|
|
282
|
+
terminalReason: failed-check
|
|
278
283
|
description: "Recording failed, was denied, or the task never reached done — stop without claiming completion."
|
|
279
284
|
guard:
|
|
280
285
|
kind: always
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"$schema": "@gobing-ai/spur/schemas/state-machine-workflow.schema.json"
|
|
76
76
|
kind: state-machine
|
|
77
77
|
name: wrapup-pipeline
|
|
78
|
-
version: "
|
|
78
|
+
version: "5"
|
|
79
79
|
description: "Post-execution wrap-up: doc-sync (doc drift + learning capture), metrics, feature-transition, branch-cleanup"
|
|
80
80
|
iterationBound: 10
|
|
81
81
|
initialState: start
|
|
@@ -128,7 +128,10 @@ states:
|
|
|
128
128
|
missing or corrupted capture refuses progression. A validated empty list
|
|
129
129
|
-> skipped; length > 0 && mode == fast -> fast-path (metrics-record,
|
|
130
130
|
bypassing doc-sync); missing/unknown/conflict -> doc-sync (safety-path).
|
|
131
|
-
Writes bounded machine-readable reason to reasonFile.
|
|
131
|
+
Writes bounded machine-readable reason to reasonFile. When the caller leaves
|
|
132
|
+
mode empty, a deterministic drift probe (0944) projects mode=fast only when
|
|
133
|
+
no changed path matches a doc-owned surface and every task's Solution
|
|
134
|
+
change map parsed — any doubt stays on the safety path.
|
|
132
135
|
onEnter:
|
|
133
136
|
- kind: note
|
|
134
137
|
options:
|
|
@@ -148,21 +151,53 @@ states:
|
|
|
148
151
|
echo "wrapup-steps failed closed — script not found — run 'superskill install sp'" >&2;
|
|
149
152
|
printf 'FAIL\n' > ".spur/run/$__runId-wrapup-resolve.status";
|
|
150
153
|
fi
|
|
151
|
-
# (
|
|
152
|
-
#
|
|
153
|
-
#
|
|
154
|
-
#
|
|
155
|
-
#
|
|
156
|
-
#
|
|
157
|
-
# the
|
|
154
|
+
# (0944 R1-R3) deterministic drift probe — runs ONLY when the caller left mode
|
|
155
|
+
# empty (a caller-set mode is projected verbatim and the probe never runs). It
|
|
156
|
+
# writes <runId>-drift-probe.json {clean,reasons,paths} and projects the wrapup
|
|
157
|
+
# mode by writing <runId>-mode.txt: caller mode verbatim, `fast` when the probe
|
|
158
|
+
# is clean, empty when dirty (the probe script fails safe on any lookup or parse
|
|
159
|
+
# problem; a missing script writes a dirty probe + empty mode here). The next
|
|
160
|
+
# action reads the mode file into vars.mode via file.read.into-var.
|
|
158
161
|
- kind: shell
|
|
159
162
|
options:
|
|
160
163
|
command: >-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
164
|
+
if [ -n "$mode" ]; then
|
|
165
|
+
printf '%s\n' "$mode" > ".spur/run/$__runId-mode.txt";
|
|
166
|
+
elif [ -f plugins/sp/scripts/wrapup-drift-probe.ts ]; then
|
|
167
|
+
bun plugins/sp/scripts/wrapup-drift-probe.ts;
|
|
168
|
+
elif W="$(superskill script path sp wrapup-drift-probe.mjs 2>/dev/null)" && [ -f "$W" ]; then
|
|
169
|
+
node "$W";
|
|
170
|
+
else
|
|
171
|
+
printf '{"clean":false,"reasons":["probe script not found"],"paths":[]}' > ".spur/run/$__runId-drift-probe.json";
|
|
172
|
+
printf '\n' > ".spur/run/$__runId-mode.txt";
|
|
173
|
+
fi
|
|
174
|
+
- kind: file.read.into-var
|
|
175
|
+
options:
|
|
176
|
+
path: .spur/run/${vars.__runId}-mode.txt
|
|
177
|
+
var: mode
|
|
178
|
+
# (e) route-reason writer: one table lookup over the projected mode var over
|
|
179
|
+
# the validated capture and the drift probe verdict; workflow-local routing
|
|
180
|
+
# glue (0824, moved behind the wrapup-steps locator in 0944 to stay inside the
|
|
181
|
+
# ADR-115 shell caps). Runs AFTER the probe/projection so the reason reflects
|
|
182
|
+
# the projected mode. Reads ONLY .spur/run/<runId>-wrapup-tasks.json and the
|
|
183
|
+
# probe verdict — never raw vars.tasks (0783 R2/R5). A FAIL resolve exits
|
|
184
|
+
# without writing: the failed reason written by validation stands, and the
|
|
185
|
+
# skip reason can never mask it. A clean probe yields `fast:drift-probe-clean`
|
|
186
|
+
# (0944); mode `safety` claims `safety:operator-forced doc-sync`; a missing or
|
|
187
|
+
# corrupted capture fails the lookup (no skipped or clean claim can be
|
|
188
|
+
# invented); the failed defense edge owns the run.
|
|
189
|
+
- kind: shell
|
|
190
|
+
options:
|
|
191
|
+
command: >-
|
|
192
|
+
mkdir -p .spur/run .spur/memory &&
|
|
193
|
+
if [ -f plugins/sp/scripts/wrapup-steps.ts ]; then
|
|
194
|
+
bun plugins/sp/scripts/wrapup-steps.ts route-reason;
|
|
195
|
+
elif W="$(superskill script path sp wrapup-steps.mjs 2>/dev/null)" && [ -f "$W" ]; then
|
|
196
|
+
node "$W" route-reason;
|
|
197
|
+
else
|
|
198
|
+
echo "wrapup-steps failed closed — script not found — run 'superskill install sp'" >&2;
|
|
199
|
+
printf 'FAIL\n' > ".spur/run/$__runId-wrapup-resolve.status";
|
|
200
|
+
fi
|
|
166
201
|
|
|
167
202
|
- id: doc-sync
|
|
168
203
|
description: >
|
|
@@ -367,6 +402,7 @@ transitions:
|
|
|
367
402
|
# ── task-resolve: validation fail + proportional route table (0758 R1-R4, 0770) ──
|
|
368
403
|
- from: task-resolve
|
|
369
404
|
to: failed
|
|
405
|
+
terminalReason: failed-check
|
|
370
406
|
description: >
|
|
371
407
|
Validation FAIL (0770): malformed wrap input, a non-string/empty entry, an
|
|
372
408
|
unresolved or non-completed task, or an empty __runId. Declared before the
|
|
@@ -402,6 +438,7 @@ transitions:
|
|
|
402
438
|
command: 'test "$(jq length .spur/run/$__runId-wrapup-tasks.json 2>/dev/null || echo -1)" -gt 0 && test "$mode" != fast'
|
|
403
439
|
- from: task-resolve
|
|
404
440
|
to: failed
|
|
441
|
+
terminalReason: failed-check
|
|
405
442
|
description: >
|
|
406
443
|
Defense (0770) — no PASS/FAIL resolve status (shell crashed or never ran):
|
|
407
444
|
route to `failed` rather than claiming a skip.
|
|
@@ -429,6 +466,7 @@ transitions:
|
|
|
429
466
|
kind: action-ok
|
|
430
467
|
- from: doc-sync
|
|
431
468
|
to: failed
|
|
469
|
+
terminalReason: failed-check
|
|
432
470
|
description: >
|
|
433
471
|
Executor failure (non-zero exit, signal, or dispatch error) — keep the
|
|
434
472
|
existing fail semantics; a contract violation never falls through here
|
|
@@ -458,6 +496,7 @@ transitions:
|
|
|
458
496
|
# the metrics status PASS so a missing status can never claim success.
|
|
459
497
|
- from: metrics-record
|
|
460
498
|
to: failed
|
|
499
|
+
terminalReason: failed-check
|
|
461
500
|
description: >
|
|
462
501
|
Metrics capture failed for at least one task — a missing metrics row is
|
|
463
502
|
recorded as failure, never silently omitted as success (0770).
|
|
@@ -490,6 +529,7 @@ transitions:
|
|
|
490
529
|
# ── feature-transition: fail edge, then branch-cleanup (if merge) or done ──
|
|
491
530
|
- from: feature-transition
|
|
492
531
|
to: failed
|
|
532
|
+
terminalReason: failed-check
|
|
493
533
|
description: >
|
|
494
534
|
Required synchronization failed (0770): non-zero sync exit, an invalid
|
|
495
535
|
sync result, or a failed feature gate. The failed status carries the
|
|
@@ -507,6 +547,7 @@ transitions:
|
|
|
507
547
|
command: 'test "$(cat .spur/run/$__runId-wrapup-sync.status 2>/dev/null)" = PASS'
|
|
508
548
|
- from: feature-verify
|
|
509
549
|
to: failed
|
|
550
|
+
terminalReason: failed-check
|
|
510
551
|
description: >
|
|
511
552
|
Post-wrapup feature check failed (0915 F1): the bound receipt no longer
|
|
512
553
|
validates against the current feature contract. Already-written
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/spur",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.94",
|
|
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.9",
|
|
57
|
+
"@gobing-ai/ts-ai-runner": "^0.5.9",
|
|
58
|
+
"@gobing-ai/ts-dual-workflow-engine": "^0.5.9",
|
|
59
|
+
"@gobing-ai/ts-infra": "^0.5.9",
|
|
60
|
+
"@gobing-ai/ts-llm-jsonl-importer": "^0.5.9",
|
|
61
|
+
"@gobing-ai/ts-rule-engine": "^0.5.9",
|
|
62
|
+
"@gobing-ai/ts-runtime": "^0.5.9",
|
|
63
|
+
"@gobing-ai/ts-utils": "^0.5.9",
|
|
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
|
@@ -102,7 +102,7 @@ list this README is checked against.
|
|
|
102
102
|
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
103
103
|
| `dev-next` | Status-aware router — inspect a task (or next frontier under a feature), dispatch the best existing `/sp:dev-*` command, chain on clean success |
|
|
104
104
|
| `dev-run` | Run a task — full pipeline (precheck→implement→test→review→approve→verify→record→done) or single-step (implement) |
|
|
105
|
-
| `dev-review` | Multi-dimensional review for a task or path
|
|
105
|
+
| `dev-review` | Multi-dimensional review for a task or path (traceability, SECUA, architecture); `--triage` fixes small findings, files the rest as tasks |
|
|
106
106
|
| `dev-pr-review` | GitHub Codex PR review — prepare/reuse a PR, request `@codex review`, collect findings, validate/fix/re-review (fix mode); workflow-backed spine |
|
|
107
107
|
| `dev-verify` | Verify a task against its requirements and Acceptance Criteria — traceability check producing a PASS/PARTIAL/FAIL verdict with evidence |
|
|
108
108
|
| `dev-unit` | Generate or extend tests until the unit target is met |
|
|
@@ -186,7 +186,7 @@ pipeline step.
|
|
|
186
186
|
|
|
187
187
|
```
|
|
188
188
|
plugins/sp/
|
|
189
|
-
├── skills/ # Domain knowledge + workflow docs (
|
|
189
|
+
├── skills/ # Domain knowledge + workflow docs (39 skills)
|
|
190
190
|
│ ├── brainstorm/ # Structured ideation workflow
|
|
191
191
|
│ │ ├── agents/openai.yaml
|
|
192
192
|
│ │ ├── examples/ideation-example.md
|
|
@@ -342,6 +342,7 @@ surface or run one workflow. All skills target the same five core platforms: `cl
|
|
|
342
342
|
| `session-review` | 1.1 | Inline review of the active coding-agent session — compact outcomes, evidence-backed resolved/open issue classification, proposal-only improvements, and next actions; no workflow, import, delegation, or mutation |
|
|
343
343
|
| `spur-composer` | 1.0 | Cross-noun composition — workflow catalog selection, the ephemeral→project→shared ladder, ADR-115 budgets, trace-driven rule tuning; applies accepted `spur-doctor` proposals through `spur` verbs; never judges its own output and never runs a recurring loop |
|
|
344
344
|
| `spur-doctor` | 1.0 | Cross-noun evaluation — read-only CLI evidence per noun (task/feature/rule/workflow/agent spec), reflection over `history-anatomy` findings through a closed action-class map, and a proposal table; writes nothing; diagnoses artifacts, not runtime environments (`spur agent doctor`'s job) |
|
|
345
|
+
| `spur-check` | 1.0 | Two-tier check primitive (ADR-124) — light changed-scope checks during development, the full `bun run spur-check` chain at the quality boundary, and the fingerprint-bound `<wbs>-check-receipt.json` with the `status` reuse rule; composes with `/sp:dev-fixall --gate-log` |
|
|
345
346
|
| `redesign-web-ui` | 1.0 | Existing-UI visual upgrade — audit generic AI fingerprints, apply in-stack polish against `DESIGN.md` / live tokens, verify behavior and viewports; does not migrate frameworks |
|
|
346
347
|
| `taste-refactoring-api` | 1.0 | API design and refactoring for REST/HTTP, RPC/gRPC, GraphQL, event contracts, and CLI surfaces; compatibility, security, and migration review |
|
|
347
348
|
| `taste-refactoring-ui` | 1.0 | UI design and refactoring with visual hierarchy, typography, spacing, color, and interaction review |
|
|
@@ -512,6 +513,7 @@ hold `SKILL.md` and prompt-side companions only.
|
|
|
512
513
|
| `scripts/feature-sync-bounded.ts` | Bounded retry-suppression wrapper for `spur feature sync` during batch/wrap-up runs — suppresses identical L4-blocked repeats |
|
|
513
514
|
| `scripts/stage-registry-adapter.ts` | dev-next golden-path adapter over the canonical stage registry — TABLE A/B/C resolution bridge for the status-aware facade |
|
|
514
515
|
| `scripts/task-size-precheck.ts` | Pipeline size precheck guard (R2) — evaluates R-item/Plan-count limits to PASS/FAIL |
|
|
516
|
+
| `scripts/task-diffstat.ts` | 0943 triage-lane diffstat producer — numstat + untracked scan vs the run base; writes `<wbs>-diffstat.json` with the sensitive-path flag; fails safe (sensitive) |
|
|
515
517
|
| `scripts/validate-flag-contracts.ts` | Mechanical consistency gate — compares flag claims across command files, flag-glossary, cross-cutting, dev-operations, and ADR; reports disagreements |
|
|
516
518
|
| `*.test.ts` | Unit suites — in `hooks/` for guards, in `tests/<skill>/` per ADR-031 pairing |
|
|
517
519
|
|
|
@@ -629,7 +631,10 @@ pipeline owns one lifecycle phase:
|
|
|
629
631
|
| `idea-pipeline.yaml` | Idea/planning → feature + tasks | `/sp:dev-idea`, `/sp:dev-plan` |
|
|
630
632
|
| `wrapup-pipeline.yaml` | Post-execution wrap-up | `/sp:dev-wrap`, `/sp:dev-wrapall` |
|
|
631
633
|
| `wayfinder-resolution.yaml` | Wayfinder ticket resolution loop | `spur workflow run` (free-form) |
|
|
632
|
-
|
|
634
|
+
|
|
635
|
+
> 0946 (D64): the `decision-routing-example.yaml` authoring sample was retired from the catalogue
|
|
636
|
+
> (zero runs, example-only — `docs/design/workflow-catalogue-refactor.md` §10); the pattern lives on
|
|
637
|
+
> as a test fixture (`packages/app/tests/services/fixtures/decision-routing-example.yaml`).
|
|
633
638
|
|
|
634
639
|
### Lifecycle operations
|
|
635
640
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: "Review the active coding-agent session immediately: summarize outcomes, distinguish resolved and open issues with evidence, and propose bounded improvements. With --triage: apply pure-doc / one-to-two-line fixes inline, then file remaining findings as one
|
|
2
|
+
description: "Review the active coding-agent session immediately: summarize outcomes, distinguish resolved and open issues with evidence, and propose bounded improvements. With --triage: apply pure-doc / one-to-two-line fixes inline, then file remaining findings as one or more implement-ready tasks. Triggers: review this session, session wrap-up, immediate retrospective, what happened, what was resolved, triage findings"
|
|
3
3
|
role: reviewer
|
|
4
4
|
argument-hint: "[<focus>] [--triage]"
|
|
5
5
|
allowed-tools: ["Bash", "Read", "Grep", "Glob", "Skill"]
|
|
@@ -11,8 +11,8 @@ Wraps the **sp:session-review** skill for a lightweight review of the active hos
|
|
|
11
11
|
default it is report-only: current conversation plus read-only repository evidence, run inline so
|
|
12
12
|
the session context is preserved — no workflow launch, history import, task creation, or
|
|
13
13
|
remediation. With `--triage`, it first triages the findings, then applies direct fixes (pure
|
|
14
|
-
documentation work and one-to-two-line fixes) inline and files everything remaining as
|
|
15
|
-
|
|
14
|
+
documentation work and one-to-two-line fixes) inline and files everything remaining as one or more
|
|
15
|
+
implement-ready tasks for further fixing. The result includes a non-overlapping time breakdown with durations in
|
|
16
16
|
`M:SS` or `H:MM:SS` form and `n/a` for unavailable measurements.
|
|
17
17
|
|
|
18
18
|
## Argument Flags
|
|
@@ -20,7 +20,7 @@ new task for further fixing. The result includes a non-overlapping time breakdow
|
|
|
20
20
|
| Flag | Description | Default |
|
|
21
21
|
| --- | --- | --- |
|
|
22
22
|
| `[<focus>]` | Optional question or operation to emphasize without excluding material session outcomes. | full active session |
|
|
23
|
-
| `--triage` | After the report: bucket findings → apply pure-doc / 1–2-line fixes inline →
|
|
23
|
+
| `--triage` | After the report: bucket findings → apply pure-doc / 1–2-line fixes inline → file the remainder as one or more implement-ready tasks. | off (report-only) |
|
|
24
24
|
|
|
25
25
|
For shared semantics, see the [flag glossary](../skills/spur-dev/references/flag-glossary.md).
|
|
26
26
|
|