@gobing-ai/spur 0.4.10 → 0.4.12
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/config.example.yaml +22 -0
- package/config/rules/quality/coverage-gate.yaml +2 -2
- package/config/rules/surface/check-cli-surface.yaml +4 -0
- package/config/workflows/feature-verification.yaml +14 -5
- package/config/workflows/idea-pipeline.yaml +92 -12
- package/config/workflows/pr-review.yaml +72 -224
- package/config/workflows/task-pipeline.yaml +456 -830
- package/config/workflows/wayfinder-resolution.yaml +20 -3
- package/config/workflows/wrapup-pipeline.yaml +22 -9
- package/package.json +1 -1
- package/plugins/sp/README.md +2 -2
- package/plugins/sp/agents/super-planner.md +2 -2
- package/plugins/sp/agents/super-reviewer.md +17 -8
- package/plugins/sp/bunfig.toml +3 -3
- package/plugins/sp/commands/dev-changelog.md +1 -1
- package/plugins/sp/commands/dev-gitmsg.md +2 -2
- package/plugins/sp/commands/dev-handover.md +1 -1
- package/plugins/sp/commands/dev-idea.md +23 -13
- package/plugins/sp/commands/dev-job-dump.md +1 -1
- package/plugins/sp/commands/dev-plan.md +17 -6
- package/plugins/sp/commands/dev-pr-review.md +27 -17
- package/plugins/sp/commands/dev-review.md +1 -1
- package/plugins/sp/commands/dev-run.md +7 -6
- package/plugins/sp/commands/dev-runall.md +1 -1
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/skills/code-implementation/SKILL.md +7 -7
- package/plugins/sp/skills/code-refactoring/SKILL.md +1 -1
- package/plugins/sp/skills/code-verification/SKILL.md +1 -1
- package/plugins/sp/skills/code-verification/references/secu-review.md +8 -4
- package/plugins/sp/skills/code-verification/references/verdict-schema.md +23 -10
- package/plugins/sp/skills/doc-evolve/SKILL.md +1 -1
- package/plugins/sp/skills/next-router/references/routing-table.md +1 -1
- package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +7 -7
- package/plugins/sp/skills/pr-reviewing/SKILL.md +157 -210
- package/plugins/sp/skills/source-driven-development/SKILL.md +14 -6
- package/plugins/sp/skills/spec-decomposition/references/decomposition.md +4 -4
- package/plugins/sp/skills/spur-check/SKILL.md +9 -8
- package/plugins/sp/skills/spur-cli/SKILL.md +3 -3
- package/plugins/sp/skills/spur-cli/references/builder.md +86 -13
- package/plugins/sp/skills/spur-cli/references/self.md +37 -2
- package/plugins/sp/skills/spur-cli/references/tasks/l3-guard-cheatsheet.md +1 -1
- package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +3 -3
- package/plugins/sp/skills/spur-cli/references/tasks.md +1 -1
- package/plugins/sp/skills/spur-cli/references/workflows.md +5 -3
- package/plugins/sp/skills/spur-dev/SKILL.md +3 -3
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +9 -8
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +11 -11
- package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +4 -3
- package/plugins/sp/skills/spur-dev/references/execution-batch-report.md +4 -4
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +13 -11
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +31 -22
- package/plugins/sp/skills/spur-dev/references/execution-worktree-landing.md +5 -5
- package/plugins/sp/skills/spur-dev/references/execution-worktree-setup.md +4 -4
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +3 -2
- package/plugins/sp/skills/spur-dev/references/gate-checklists.md +4 -4
- package/schemas/spur-config.schema.json +19 -1
- package/spur.js +32388 -31906
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +0 -997
- package/plugins/sp/skills/spur-dev/references/structured-trace-emission.md +0 -178
|
@@ -230,6 +230,28 @@ redaction:
|
|
|
230
230
|
# releaseCommitType: chore
|
|
231
231
|
# releaseCommitScope: release
|
|
232
232
|
# ghRunListLimit: 5
|
|
233
|
+
# # Stack preset for the SDLC action vocabulary (ADR-139): the commands Spur's gates run.
|
|
234
|
+
# # bun (default) — every reserved action resolves to the legacy bun scripts below, so a
|
|
235
|
+
# # bun project needs no binding at all.
|
|
236
|
+
# # none — only the stack-neutral `spur rule run` presets are bound; declare the
|
|
237
|
+
# # rest in `actions` (see below) or they stay unbound.
|
|
238
|
+
# preset: bun
|
|
239
|
+
# # action name -> one shell command, or a list of action names (composite, run in order,
|
|
240
|
+
# # fail-fast). A declared entry replaces the preset binding whole. Reserved names: build, dev,
|
|
241
|
+
# # clean, format, autofix, lint, typecheck, test, test-full, test-heavy, rules-pre, rules-post,
|
|
242
|
+
# # check, check-full, check-feature, lint-changed, typecheck-changed, test-changed. Any other
|
|
243
|
+
# # name is a custom action (exec-only). {files}/{paths}/{workspace} are allowed only in the
|
|
244
|
+
# # three *-changed actions; each substituted item is shell-quoted.
|
|
245
|
+
# actions:
|
|
246
|
+
# build: make build
|
|
247
|
+
# lint: ruff check .
|
|
248
|
+
# typecheck: mypy src
|
|
249
|
+
# test: pytest -q
|
|
250
|
+
# test-full: pytest --cov
|
|
251
|
+
# lint-changed: ruff check {files}
|
|
252
|
+
# test-changed: cd {workspace} && pytest {paths}
|
|
253
|
+
# check: [lint, test, rules-post]
|
|
254
|
+
# release: ./scripts/release.sh
|
|
233
255
|
|
|
234
256
|
# ── Planning (design §2.1 / §9) ──
|
|
235
257
|
tasks:
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
$schema: "@gobing-ai/spur/schemas/rule-file.schema.json"
|
|
2
2
|
# Coverage gate — per-file line coverage meets threshold from Bun's lcov output.
|
|
3
3
|
#
|
|
4
|
-
# PROVENANCE (task 1203): since task 1203 the repository post-check
|
|
5
|
-
# (`test-post-check
|
|
4
|
+
# PROVENANCE (task 1203): since task 1203 the repository post-check script
|
|
5
|
+
# (`test-post-check`) validates canonical coverage
|
|
6
6
|
# certification BEFORE this rule evaluates: only a completed successful canonical
|
|
7
7
|
# full-suite run (`bun run test`, `test:coverage`, `test:full`) certifies
|
|
8
8
|
# .coverage/lcov.info (marker: .coverage/coverage-certification.json, written by
|
|
@@ -65,6 +65,10 @@ rules:
|
|
|
65
65
|
# commit-guard declares no --json: its {staged, foreign} / {foreign} lines are rendered by
|
|
66
66
|
# @gobing-ai/spur-app/commit-guard (byte-identical to the retired script, PR-4 golden).
|
|
67
67
|
- "apps/cli/src/commands/workflow/commit-guard.ts"
|
|
68
|
+
# WT-4 worktree-landing transports (D65 1242, flat since the inline group was deleted): they
|
|
69
|
+
# print the app operation's already-serialized payload (runPersistOut/persist-check), and
|
|
70
|
+
# declare no --json of their own.
|
|
71
|
+
- "apps/cli/src/commands/workflow/persist.ts"
|
|
68
72
|
# Pipeline-internal task verbs (script-absorption PR-3) declare no --json: their contract is
|
|
69
73
|
# the .spur/run artifact they write (gate status/receipt, residuals.json, diffstat.json) and
|
|
70
74
|
# the exit code; the gate's own status line is serialized by the app service.
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"$schema": "@gobing-ai/spur/schemas/state-machine-workflow.schema.json"
|
|
40
40
|
kind: state-machine
|
|
41
41
|
name: feature-verification
|
|
42
|
-
version: "
|
|
42
|
+
version: "2"
|
|
43
43
|
description: "Feature-scoped verification pass (ADR-119): runs the repo-wide check set once per feature and records a bound PASS/FAIL evidence receipt. Invoked by feature-lifecycle's verifying entry."
|
|
44
44
|
iterationBound: 2
|
|
45
45
|
initialState: verify
|
|
@@ -51,7 +51,7 @@ failureStates:
|
|
|
51
51
|
vars:
|
|
52
52
|
featureId: "X"
|
|
53
53
|
spurBin: "spur"
|
|
54
|
-
verificationCmd: "
|
|
54
|
+
verificationCmd: "spur self exec check-feature"
|
|
55
55
|
__runId: ""
|
|
56
56
|
|
|
57
57
|
states:
|
|
@@ -62,10 +62,19 @@ states:
|
|
|
62
62
|
digest, run identity) and the coarse status file, always exit 0 so the
|
|
63
63
|
transition guard routes missing/corrupt/FAIL to `failed`.
|
|
64
64
|
onEnter:
|
|
65
|
-
|
|
65
|
+
# D65 1238 R1: the pass runs as a typed gate builtin (1234), not a shell action — the same
|
|
66
|
+
# `spur feature verify` argv, whose configured `spur self exec check-feature` action is the
|
|
67
|
+
# verification command. `softFail` keeps a non-running pass a RECORDED outcome that the guards
|
|
68
|
+
# below route to `failed`, exactly as the always-exit-0 shell did. The pass still writes its
|
|
69
|
+
# own `.spur/run/<runId>-feature-verification.status` and evidence receipt; the gate's typed
|
|
70
|
+
# token lands beside them, so the pass's PASS/FAIL evidence is never overwritten.
|
|
71
|
+
- kind: command.gate
|
|
66
72
|
options:
|
|
67
|
-
|
|
68
|
-
|
|
73
|
+
id: feature-verification
|
|
74
|
+
executable: "${vars.spurBin}"
|
|
75
|
+
args: ["feature", "verify", "${vars.featureId}", "--run-id", "${vars.__runId}", "--no-logo"]
|
|
76
|
+
resultFile: .spur/run/${vars.__runId}-feature-verification.gate.status
|
|
77
|
+
softFail: true
|
|
69
78
|
|
|
70
79
|
- id: done
|
|
71
80
|
description: Terminal — repo-wide checks passed and the receipt is bound.
|
|
@@ -76,6 +76,15 @@ vars:
|
|
|
76
76
|
agent: "auto"
|
|
77
77
|
planningAgent: ""
|
|
78
78
|
stepTimeoutMs: "1800000"
|
|
79
|
+
# Executor for every agent.run stage (D65 R1): "host" pauses the run with a work item
|
|
80
|
+
# (`spur workflow run|continue --json`), "fleet" dispatches through ADR-126, and empty
|
|
81
|
+
# resolves the subprocess surface through the existing tier ladder.
|
|
82
|
+
executor: ""
|
|
83
|
+
# Accepted/deferred status each operator gate's decision binding writes (1236 R2).
|
|
84
|
+
ideaEvalStatus: ""
|
|
85
|
+
featureCheckStatus: ""
|
|
86
|
+
designApprovalStatus: ""
|
|
87
|
+
batchCreateStatus: ""
|
|
79
88
|
|
|
80
89
|
states:
|
|
81
90
|
- id: start
|
|
@@ -138,6 +147,11 @@ states:
|
|
|
138
147
|
# explicitly so the definition is self-documenting.
|
|
139
148
|
session: fresh
|
|
140
149
|
expectFile: .spur/run/${vars.__runId}-idea-eval-report.md
|
|
150
|
+
# The signal is this stage's own output; the plural form declares it to the
|
|
151
|
+
# work item (host/fleet) while the singular expectFile stays the subprocess
|
|
152
|
+
# post-exit guard, so a missing signal still falls back to the catalog decision.
|
|
153
|
+
expectFiles:
|
|
154
|
+
- .spur/run/${vars.__runId}-idea-needs-design.json
|
|
141
155
|
timeoutMs: ${vars.stepTimeoutMs}
|
|
142
156
|
# Derive the eval recommendation ONCE (0769 pattern): the first non-blank line under
|
|
143
157
|
# `## Recommendation` → proceed | reshape | drop | unknown. The --auto guards out of
|
|
@@ -183,14 +197,30 @@ states:
|
|
|
183
197
|
pros/cons, and a recommendation. The operator reviews and approves or
|
|
184
198
|
rejects. Routed around only when profile=auto AND vars.idea_approved=true
|
|
185
199
|
(CLI --auto) AND the report's recommendation is proceed/reshape; a drop
|
|
186
|
-
recommendation cancels, a missing one
|
|
187
|
-
|
|
200
|
+
recommendation cancels, a missing one asks the gate, whose evidence binding then
|
|
201
|
+
answers under profile=auto (1236/1241).
|
|
188
202
|
onEnter:
|
|
189
203
|
- kind: hitl.confirm
|
|
190
204
|
options:
|
|
191
205
|
prompt: "Review the idea evaluation report (.spur/run/${vars.__runId}-idea-eval-report.md). Approve to create a feature, or reject to cancel? (Reject creates no feature.)"
|
|
206
|
+
# Interactive always prompts the operator; profile=auto answers from the discovery
|
|
207
|
+
# stage's recorded evidence, deferring when it cannot decide (1236 R1/R2).
|
|
192
208
|
decision:
|
|
193
|
-
mode:
|
|
209
|
+
mode: evidence
|
|
210
|
+
statusVar: ideaEvalStatus
|
|
211
|
+
evidenceNodes:
|
|
212
|
+
- discovery
|
|
213
|
+
# A deferred/absent answer is the denial today's headless responder gave, so the
|
|
214
|
+
# guards keep routing on yes | no | cancel with no new edge.
|
|
215
|
+
- kind: shell
|
|
216
|
+
options:
|
|
217
|
+
command: >-
|
|
218
|
+
mkdir -p .spur/run; a="$__hitlAnswer"; [ -n "$a" ] || a=no;
|
|
219
|
+
printf '%s\n' "$a" > ".spur/run/$__runId-idea-eval-answer.txt"
|
|
220
|
+
- kind: file.read.into-var
|
|
221
|
+
options:
|
|
222
|
+
path: .spur/run/${vars.__runId}-idea-eval-answer.txt
|
|
223
|
+
var: __hitlAnswer
|
|
194
224
|
|
|
195
225
|
- id: feature-create
|
|
196
226
|
display:
|
|
@@ -218,6 +248,11 @@ states:
|
|
|
218
248
|
# B7 R6 (0894): declared fresh policy (planner default).
|
|
219
249
|
session: fresh
|
|
220
250
|
expectFile: .spur/run/${vars.__runId}-idea-feature-id.txt
|
|
251
|
+
# Intent artifacts this stage writes; the shell below fails closed when either is
|
|
252
|
+
# missing, so declaring them adds the work-item contract, not a new precondition.
|
|
253
|
+
expectFiles:
|
|
254
|
+
- .spur/run/${vars.__runId}-idea-goal.md
|
|
255
|
+
- .spur/run/${vars.__runId}-idea-scope.md
|
|
221
256
|
timeoutMs: ${vars.stepTimeoutMs}
|
|
222
257
|
- kind: file.read.into-var
|
|
223
258
|
options:
|
|
@@ -335,13 +370,29 @@ states:
|
|
|
335
370
|
Requirement coverage (1004 R2) folds into the recorded `idea-ac-check` result via the
|
|
336
371
|
gate's `--inventory` flag: a FAIL there can mean some inventory items have no covering
|
|
337
372
|
scenario — answer no to route back to ac-generate for revision if needed.
|
|
338
|
-
pause: true
|
|
339
373
|
onEnter:
|
|
340
374
|
- kind: hitl.confirm
|
|
341
375
|
options:
|
|
342
376
|
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.)"
|
|
377
|
+
# Interactive always prompts the operator; profile=auto answers from the AC
|
|
378
|
+
# authoring stage's recorded evidence (1236 R1/R2). No `pause: true` — an
|
|
379
|
+
# evidence binding cannot live in a paused state (0911 D2), and the responder
|
|
380
|
+
# is what asks the operator now.
|
|
343
381
|
decision:
|
|
344
|
-
mode:
|
|
382
|
+
mode: evidence
|
|
383
|
+
statusVar: featureCheckStatus
|
|
384
|
+
evidenceNodes:
|
|
385
|
+
- ac-generate
|
|
386
|
+
# A deferred/absent answer is the denial today's headless responder gave.
|
|
387
|
+
- kind: shell
|
|
388
|
+
options:
|
|
389
|
+
command: >-
|
|
390
|
+
mkdir -p .spur/run; a="$__hitlAnswer"; [ -n "$a" ] || a=no;
|
|
391
|
+
printf '%s\n' "$a" > ".spur/run/$__runId-idea-feature-check-answer.txt"
|
|
392
|
+
- kind: file.read.into-var
|
|
393
|
+
options:
|
|
394
|
+
path: .spur/run/${vars.__runId}-idea-feature-check-answer.txt
|
|
395
|
+
var: __hitlAnswer
|
|
345
396
|
# 1007 R2: the former post-confirm route-writer duplicate is deleted — ac-generate's
|
|
346
397
|
# writer is the single writer (0945 R2 pin updated); its inputs (design var, needs-design
|
|
347
398
|
# JSON, recorded ac-check status) cannot change across hitl.confirm.
|
|
@@ -420,7 +471,6 @@ states:
|
|
|
420
471
|
records the concrete issue(s) in the run-scoped design-review artifact
|
|
421
472
|
(.spur/run/${vars.__runId}-idea-design-review.md) under `## Operator feedback` —
|
|
422
473
|
the revision pass reads it to reconcile invalidated AC before re-approval.
|
|
423
|
-
pause: true
|
|
424
474
|
onEnter:
|
|
425
475
|
- kind: shell
|
|
426
476
|
options:
|
|
@@ -428,8 +478,23 @@ states:
|
|
|
428
478
|
- kind: hitl.confirm
|
|
429
479
|
options:
|
|
430
480
|
prompt: "Review the system design for feature ${vars.featureId}. Approve to proceed to decomposition? To reject, first record your feedback in .spur/run/${vars.__runId}-idea-design-review.md under the `## Operator feedback` heading, then answer no."
|
|
481
|
+
# Interactive always prompts the operator; profile=auto answers from the
|
|
482
|
+
# system-design stage's recorded evidence (1236 R1/R2).
|
|
431
483
|
decision:
|
|
432
|
-
mode:
|
|
484
|
+
mode: evidence
|
|
485
|
+
statusVar: designApprovalStatus
|
|
486
|
+
evidenceNodes:
|
|
487
|
+
- system-design
|
|
488
|
+
# A deferred/absent answer is the denial today's headless responder gave.
|
|
489
|
+
- kind: shell
|
|
490
|
+
options:
|
|
491
|
+
command: >-
|
|
492
|
+
mkdir -p .spur/run; a="$__hitlAnswer"; [ -n "$a" ] || a=no;
|
|
493
|
+
printf '%s\n' "$a" > ".spur/run/$__runId-idea-design-approval-answer.txt"
|
|
494
|
+
- kind: file.read.into-var
|
|
495
|
+
options:
|
|
496
|
+
path: .spur/run/${vars.__runId}-idea-design-approval-answer.txt
|
|
497
|
+
var: __hitlAnswer
|
|
433
498
|
|
|
434
499
|
- id: decompose
|
|
435
500
|
display:
|
|
@@ -491,13 +556,27 @@ states:
|
|
|
491
556
|
from decompose to the appropriate next state, so this state is only
|
|
492
557
|
entered in interactive mode. On failure, the retry cap routes back to
|
|
493
558
|
decompose (≤3 retries) or escalates to failed.
|
|
494
|
-
pause: true
|
|
495
559
|
onEnter:
|
|
496
560
|
- kind: hitl.confirm
|
|
497
561
|
options:
|
|
498
562
|
prompt: "Batch-create for feature ${vars.featureId}. Review the task batch and confirm to proceed? (Failures route back to decompose for revision, capped at 3 retries.)"
|
|
563
|
+
# Interactive always prompts the operator; profile=auto answers from the
|
|
564
|
+
# decompose stage's recorded evidence (1236 R1/R2).
|
|
499
565
|
decision:
|
|
500
|
-
mode:
|
|
566
|
+
mode: evidence
|
|
567
|
+
statusVar: batchCreateStatus
|
|
568
|
+
evidenceNodes:
|
|
569
|
+
- decompose
|
|
570
|
+
# A deferred/absent answer is the denial today's headless responder gave.
|
|
571
|
+
- kind: shell
|
|
572
|
+
options:
|
|
573
|
+
command: >-
|
|
574
|
+
mkdir -p .spur/run; a="$__hitlAnswer"; [ -n "$a" ] || a=no;
|
|
575
|
+
printf '%s\n' "$a" > ".spur/run/$__runId-idea-batch-create-answer.txt"
|
|
576
|
+
- kind: file.read.into-var
|
|
577
|
+
options:
|
|
578
|
+
path: .spur/run/${vars.__runId}-idea-batch-create-answer.txt
|
|
579
|
+
var: __hitlAnswer
|
|
501
580
|
|
|
502
581
|
- id: batch-create-run
|
|
503
582
|
display:
|
|
@@ -650,11 +729,12 @@ transitions:
|
|
|
650
729
|
|
|
651
730
|
# ── discovery: auto-accept the eval recommendation (profile=auto + idea_approved) OR enter idea-eval ──
|
|
652
731
|
# Declaration order: auto edges FIRST (same pattern as system-design → design-approval).
|
|
653
|
-
# Without them, discovery always enters idea-eval
|
|
654
|
-
#
|
|
732
|
+
# Without them, discovery always enters the idea-eval gate, rendering the prompt and
|
|
733
|
+
# persisting an avoidable operator question before the gate's own auto answer can fire (0366 R4/R5).
|
|
655
734
|
# --auto accepts the recommendation derived at the end of discovery (-idea-recommendation.txt):
|
|
656
735
|
# drop → cancelled, proceed/reshape → feature-create; unknown/missing falls through to the
|
|
657
|
-
# idea-eval
|
|
736
|
+
# idea-eval gate, whose evidence binding then answers (fail-safe: never auto-create a feature
|
|
737
|
+
# without an explicit proceed).
|
|
658
738
|
- from: discovery
|
|
659
739
|
to: cancelled
|
|
660
740
|
terminalReason: cancelled
|