@gobing-ai/spur 0.4.14 → 0.4.16
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.global.yaml +21 -8
- package/config/decisions/executor.yaml +53 -0
- package/config/decisions/task-pipeline.yaml +44 -28
- package/config/pipeline-budgets.json +0 -14
- package/config/workflow-candidates.json +18 -0
- package/config/workflows/feature-lifecycle.yaml +9 -16
- package/config/workflows/idea-pipeline.yaml +158 -740
- package/config/workflows/task-pipeline.yaml +66 -54
- package/config/workflows/wrapup-pipeline.yaml +91 -623
- package/package.json +11 -10
- package/plugins/sp/README.md +9 -5
- package/plugins/sp/agents/expert-spur.md +3 -0
- package/plugins/sp/agents/super-planner.md +5 -1
- package/plugins/sp/agents/super-reviewer.md +43 -12
- package/plugins/sp/commands/dev-fixall.md +7 -2
- package/plugins/sp/commands/dev-idea.md +15 -6
- package/plugins/sp/commands/dev-plan.md +1 -1
- package/plugins/sp/commands/dev-pr-review.md +6 -6
- package/plugins/sp/commands/dev-run.md +3 -0
- package/plugins/sp/commands/dev-runall.md +6 -3
- package/plugins/sp/commands/dev-verify.md +1 -1
- package/plugins/sp/commands/dev-wrap.md +1 -1
- package/plugins/sp/commands/dev-wrapall.md +4 -4
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/skills/code-implementation/SKILL.md +8 -8
- package/plugins/sp/skills/code-improvement/SKILL.md +3 -3
- package/plugins/sp/skills/code-review/references/verification-before-completion.md +5 -4
- package/plugins/sp/skills/code-verification/SKILL.md +4 -4
- package/plugins/sp/skills/code-verification/references/verdict-schema.md +27 -11
- package/plugins/sp/skills/functional-review/SKILL.md +1 -1
- package/plugins/sp/skills/functional-review/references/verdict-schema.md +1 -1
- package/plugins/sp/skills/next-router/references/routing-table.md +1 -1
- package/plugins/sp/skills/pr-reviewing/SKILL.md +36 -18
- package/plugins/sp/skills/spec-decomposition/references/decomposition.md +2 -1
- package/plugins/sp/skills/spur-check/SKILL.md +1 -1
- package/plugins/sp/skills/spur-cli/SKILL.md +23 -2
- package/plugins/sp/skills/spur-cli/references/agent.md +12 -0
- package/plugins/sp/skills/spur-cli/references/builder.md +2 -2
- package/plugins/sp/skills/spur-cli/references/decision/lifecycle.md +166 -0
- package/plugins/sp/skills/spur-cli/references/decision.md +146 -16
- package/plugins/sp/skills/spur-cli/references/features.md +19 -0
- package/plugins/sp/skills/spur-cli/references/rules.md +2 -0
- package/plugins/sp/skills/spur-cli/references/tasks.md +14 -1
- package/plugins/sp/skills/spur-cli/references/workflows/authoring-workflows.md +1 -1
- package/plugins/sp/skills/spur-cli/references/workflows/workflow-fit-and-tuning.md +3 -2
- package/plugins/sp/skills/spur-cli/references/workflows.md +9 -0
- package/plugins/sp/skills/spur-composer/SKILL.md +20 -1
- package/plugins/sp/skills/spur-dev/SKILL.md +16 -16
- package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +2 -1
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +2 -2
- package/plugins/sp/skills/spur-dev/references/decision-points.md +97 -0
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +18 -18
- package/plugins/sp/skills/spur-dev/references/execution-batch-report.md +1 -1
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +19 -10
- package/plugins/sp/skills/spur-dev/references/execution-parallel-isolation.md +4 -4
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +41 -29
- package/plugins/sp/skills/spur-dev/references/execution-worktree-landing.md +34 -2
- package/plugins/sp/skills/spur-dev/references/execution-worktree-setup.md +4 -4
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +3 -3
- package/plugins/sp/skills/spur-dev/references/gate-checklists.md +3 -2
- package/plugins/sp/skills/spur-dev/references/glossary.md +12 -3
- package/plugins/sp/skills/spur-dev/references/planning-workflow.md +7 -6
- package/plugins/sp/skills/spur-doctor/SKILL.md +23 -0
- package/plugins/sp/skills/wayfinder/SKILL.md +11 -1
- package/spur.js +25617 -24290
- package/web/_astro/{BoardApp.Bjdp3XWV.js → BoardApp.CC7Mwswv.js} +65 -65
- package/web/_astro/{BoardApp.DCDZxLlQ.js → BoardApp.mWyrWCAR.js} +1 -1
- package/web/_astro/{TaskDetail.B3vBxynO.js → TaskDetail.CtAXuiv8.js} +1 -1
- package/web/_astro/{arc.DcuHTB_T.js → arc.Duf4u60i.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.ClOFWBON.js → architectureDiagram-3BPJPVTR.JoymtqxN.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.otYyr7Zb.js → blockDiagram-GPEHLZMM.BvmhcioC.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.BCjpc9LP.js → c4Diagram-AAUBKEIU.CfaWkgoQ.js} +1 -1
- package/web/_astro/channel.DtEPXXcH.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.D5Wpnpt_.js → chunk-2J33WTMH.B7uR02cD.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.DkQGtWNz.js → chunk-4BX2VUAB.SwiEauYR.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.B7dqjAip.js → chunk-55IACEB6.6ZRCK8PO.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.BDQvnKE2.js → chunk-727SXJPM.Cxra_G3N.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.D92doBX5.js → chunk-AQP2D5EJ.Cxd7gZeX.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.C968oI5G.js → chunk-FMBD7UC4.DCLhFkVc.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.AkkYC1bY.js → chunk-ND2GUHAM.B9AmKcv6.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.sCc-rKKo.js → chunk-QZHKN3VN.DOjCvl6S.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.pOQ9u0mY.js → classDiagram-4FO5ZUOK.BMiT_mNf.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.pOQ9u0mY.js → classDiagram-v2-Q7XG4LA2.BMiT_mNf.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.CRaeD6FY.js → cose-bilkent-S5V4N54A.mLBCEGjI.js} +1 -1
- package/web/_astro/{cynefin-OW5HDTMX.BiCPBu54.js → cynefin-OW5HDTMX.CjDAY0qn.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.C1-q3vkT.js → dagre-BM42HDAG._G_sP8fP.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.BSVOv30O.js → diagram-2AECGRRQ.39OcfSuz.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.CHMkjJ-V.js → diagram-5GNKFQAL.D7v_eNC4.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.CKY9M564.js → diagram-KO2AKTUF.Da1x-lhg.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.B9yNJiTP.js → diagram-LMA3HP47.C8EnzbEb.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.Dk8AUGsk.js → diagram-OG6HWLK6.DPnBj69F.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.BQHR89TZ.js → erDiagram-TEJ5UH35.CXMu2TIh.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.oNkWVgoK.js → flowDiagram-I6XJVG4X.ZklePVtQ.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.Kz2U2nu9.js → ganttDiagram-6RSMTGT7.BhYOkdqk.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.DHIZ_wPq.js → gitGraphDiagram-PVQCEYII.CADyX8a1.js} +1 -1
- package/web/_astro/{infoDiagram-5YYISTIA.D0NJLcv9.js → infoDiagram-5YYISTIA.BsdmwjHt.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.CFEfTWRG.js → ishikawaDiagram-YF4QCWOH.CzjZ3Crd.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.Dc7IE7I4.js → journeyDiagram-JHISSGLW.Bxj-ZH_t.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.D5v0xO9k.js → kanban-definition-UN3LZRKU.Cbg3wVvX.js} +1 -1
- package/web/_astro/{linear.wR5KzXnE.js → linear.DJNUrBI9.js} +1 -1
- package/web/_astro/{mermaid.core.BDQ2FoPd.js → mermaid.core.DVHQV3SF.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.W6_INsia.js → mindmap-definition-RKZ34NQL.DyomosRU.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.61ihbgkK.js → pieDiagram-4H26LBE5.DajtFknN.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.B5lEpFLo.js → quadrantDiagram-W4KKPZXB.Bjq6SjGe.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.CmhVBVX0.js → requirementDiagram-4Y6WPE33.ubBVqGLP.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.D7Vvj9Wf.js → sankeyDiagram-5OEKKPKP.I4q46xd-.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.B1vPLixM.js → sequenceDiagram-3UESZ5HK.DsCgZIa8.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.BnACmrGi.js → stateDiagram-AJRCARHV.DcYjYSqT.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.CW4pnmc3.js → stateDiagram-v2-BHNVJYJU.Dt8yPqiS.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.CkzMCPnC.js → timeline-definition-PNZ67QCA.0YTkoa5F.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.CY4aNdAR.js → vennDiagram-CIIHVFJN.BNl0l1hs.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.BtoU9UFk.js → wardleyDiagram-YWT4CUSO.BYSX6cfn.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6._9ijUUAs.js → xychartDiagram-2RQKCTM6.DzxxpixK.js} +1 -1
- package/web/index.html +1 -1
- package/worker/laya_worker.py +219 -0
- package/config/workflows/feature-verification.yaml +0 -98
- package/config/workflows/pr-review.yaml +0 -209
- package/config/workflows/wayfinder-resolution.yaml +0 -302
- package/plugins/sp/skills/wayfinder/references/pipeline-resolution.md +0 -30
- package/web/_astro/channel.qgOLXjI_.js +0 -1
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
# PR-review workflow: deterministic spine for /sp:dev-pr-review (skill sp:pr-reviewing).
|
|
2
|
-
# Authored for the @gobing-ai/ts-dual-workflow-engine state-machine schema
|
|
3
|
-
# (initialState / states[].id / onEnter / top-level transitions), same family as
|
|
4
|
-
# basic.yaml / task-pipeline.yaml. Seeded into projects by `spur init` (scaffold manifest).
|
|
5
|
-
#
|
|
6
|
-
# Shape: check → precheck → open → review → done
|
|
7
|
-
# (soft probes everywhere: red gates route to `failed`/`pending` via transitions,
|
|
8
|
-
# never a raw lifecycle abort — same reliability contract as basic.yaml)
|
|
9
|
-
#
|
|
10
|
-
# This YAML is the SSOT for the review spine's state order and guards. Every state shells out to
|
|
11
|
-
# the four flat `spur builder pr-<verb>` verbs (task 1219); the op sequencing
|
|
12
|
-
# (preflight→hygiene, push→ensure, request→wait→collect) lives in `runPrVerb`, not in this file's
|
|
13
|
-
# shell, and no gh/git logic lives in this file. All model-bearing work — finding triage, `fix`
|
|
14
|
-
# mode — stays in the sp:pr-reviewing skill and never enters this machine.
|
|
15
|
-
#
|
|
16
|
-
# Non-negotiable: the external review goes through the GitHub PR + an `@codex review`
|
|
17
|
-
# comment. Never substitute a local Codex review mechanism.
|
|
18
|
-
#
|
|
19
|
-
# Vars (override per run: --vars '{"mode":"submit","focus":"migration safety"}'):
|
|
20
|
-
# mode — full (default) | submit | rerun
|
|
21
|
-
# full: dedupe an up-to-date Codex review, else request + wait + collect
|
|
22
|
-
# submit: request and stop at `pending` (no wait)
|
|
23
|
-
# rerun: request with --force even when HEAD is already reviewed
|
|
24
|
-
# baseBranch — base for a newly created PR (default: existing PR base, else repo default)
|
|
25
|
-
# focus — extra review focus appended to the @codex review request
|
|
26
|
-
# noWait — "true" returns pending right after the request instead of polling
|
|
27
|
-
# waitTimeoutSec — poll budget for Codex output (default 600)
|
|
28
|
-
# waitIntervalSec — poll interval (default 30; do not poll aggressively)
|
|
29
|
-
# preReviewCmd — project fast check run before requesting (empty = skipped).
|
|
30
|
-
# TRUSTED CONFIG ONLY — executed via `sh -c` (task 0436 SECUA residual).
|
|
31
|
-
# Never interpolate untrusted operator/LLM input into it.
|
|
32
|
-
# __runId — injected by WorkflowAppService.run(); scopes .spur/run artifacts.
|
|
33
|
-
|
|
34
|
-
"$schema": "@gobing-ai/spur/schemas/state-machine-workflow.schema.json"
|
|
35
|
-
version: "1"
|
|
36
|
-
name: pr-review
|
|
37
|
-
kind: state-machine
|
|
38
|
-
description: GitHub Codex PR-review spine — check → precheck → open → review
|
|
39
|
-
iterationBound: 16
|
|
40
|
-
initialState: check
|
|
41
|
-
terminalStates:
|
|
42
|
-
- done
|
|
43
|
-
- pending
|
|
44
|
-
- failed
|
|
45
|
-
failureStates:
|
|
46
|
-
- failed
|
|
47
|
-
vars:
|
|
48
|
-
mode: "full"
|
|
49
|
-
baseBranch: ""
|
|
50
|
-
focus: ""
|
|
51
|
-
noWait: "false"
|
|
52
|
-
waitTimeoutSec: "600"
|
|
53
|
-
waitIntervalSec: "30"
|
|
54
|
-
spurBin: "spur"
|
|
55
|
-
preReviewCmd: ""
|
|
56
|
-
__runId: ""
|
|
57
|
-
|
|
58
|
-
states:
|
|
59
|
-
- id: check
|
|
60
|
-
description: >
|
|
61
|
-
Soft probe: preflight (git/gh/repo checks, detached HEAD, dirty tree, base-branch refusal —
|
|
62
|
-
refused before any push can publish it) followed by the hygiene scan of base...HEAD
|
|
63
|
-
(secrets/.env/conflict markers BLOCK; debug residue WARNs). A preflight failure stops before
|
|
64
|
-
hygiene. Writes PASS|WARN|BLOCK|FAIL to .spur/run/${vars.__runId}-pr-check.status; always
|
|
65
|
-
exit 0, so a red gate routes through the transitions below.
|
|
66
|
-
onEnter:
|
|
67
|
-
# script-root retired for this workflow: actions call `$spurBin builder pr-<verb>` directly.
|
|
68
|
-
- kind: shell
|
|
69
|
-
options:
|
|
70
|
-
# (e) 0825: 7 lines — preflight+hygiene and their status fallback must land together
|
|
71
|
-
# (one verb now owns the whole probe; a split would half-probe the submission gate).
|
|
72
|
-
command: >-
|
|
73
|
-
STATUS_FILE=".spur/run/$__runId-pr-check.status";
|
|
74
|
-
mkdir -p .spur/run;
|
|
75
|
-
$spurBin builder pr-check --base "$baseBranch" --json --status-file "$STATUS_FILE"
|
|
76
|
-
> ".spur/run/$__runId-pr-check.json";
|
|
77
|
-
if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi;
|
|
78
|
-
exit 0
|
|
79
|
-
|
|
80
|
-
- id: precheck
|
|
81
|
-
description: >
|
|
82
|
-
Optional project fast check (vars.preReviewCmd) before spending a review request.
|
|
83
|
-
Empty command records SKIP; a red check stops the run before request (fail loud).
|
|
84
|
-
onEnter:
|
|
85
|
-
- kind: shell
|
|
86
|
-
options:
|
|
87
|
-
# (e) 0825: 7 lines — unchanged shape (optional preReviewCmd probe, SKIP/PASS/FAIL)
|
|
88
|
-
# condensed onto folded one-liners to hold the §1.2 budget.
|
|
89
|
-
command: >-
|
|
90
|
-
mkdir -p .spur/run; if [ -z "$preReviewCmd" ]; then R=SKIP; elif sh -c "$preReviewCmd"; then R=PASS; else R=FAIL; fi; printf '%s\n' "$R" > ".spur/run/$__runId-pr-precheck.status"
|
|
91
|
-
|
|
92
|
-
- id: open
|
|
93
|
-
description: >
|
|
94
|
-
Publish the branch (normal push only, never force; sets upstream when missing) and reuse or
|
|
95
|
-
create its PR — a rejected push stops before any PR work. Writes FOUND|CREATED|FAIL to
|
|
96
|
-
.spur/run/${vars.__runId}-pr-open.status and the composed record (push + pr) to
|
|
97
|
-
.spur/run/${vars.__runId}-pr-open.json.
|
|
98
|
-
onEnter:
|
|
99
|
-
- kind: shell
|
|
100
|
-
options:
|
|
101
|
-
# (e) 0825: 7 lines — publish + PR dedupe are one verb now; the status fallback keeps a
|
|
102
|
-
# silent driver from passing the gate.
|
|
103
|
-
command: >-
|
|
104
|
-
STATUS_FILE=".spur/run/$__runId-pr-open.status";
|
|
105
|
-
mkdir -p .spur/run;
|
|
106
|
-
$spurBin builder pr-open --base "$baseBranch" --json --status-file "$STATUS_FILE"
|
|
107
|
-
> ".spur/run/$__runId-pr-open.json";
|
|
108
|
-
if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi;
|
|
109
|
-
exit 0
|
|
110
|
-
|
|
111
|
-
- id: review
|
|
112
|
-
description: >
|
|
113
|
-
Request, wait for and collect the `@codex review` result on the current pushed HEAD
|
|
114
|
-
(per-HEAD dedupe unless mode=rerun; mode=submit or noWait=true stop at PENDING). Writes
|
|
115
|
-
CLEAN|FINDINGS|PENDING|FAIL to .spur/run/${vars.__runId}-pr-review.status — a wait timeout
|
|
116
|
-
is PENDING, never a failure — plus the composed findings record and the composite status.
|
|
117
|
-
onEnter:
|
|
118
|
-
- kind: shell
|
|
119
|
-
options:
|
|
120
|
-
# (e) 0825: 10 lines — request/wait/collect are one verb now, so their result lands
|
|
121
|
-
# atomically; the status fallback covers a crashed driver. `mode=submit` or `noWait=true`
|
|
122
|
-
# pass --no-wait and `mode=rerun` passes --force, each as its own space-separated word
|
|
123
|
-
# (two substitutions, never concatenated). `/bin/sh -c` carries no `-e`, so a failed
|
|
124
|
-
# substitution is ignored.
|
|
125
|
-
command: >-
|
|
126
|
-
O="$([ "$mode" = submit ] || [ "$noWait" = "true" ] && echo --no-wait) $([ "$mode" = rerun ] && echo --force)";
|
|
127
|
-
STATUS_FILE=".spur/run/$__runId-pr-review.status";
|
|
128
|
-
mkdir -p .spur/run;
|
|
129
|
-
$spurBin builder pr-review --focus "$focus" $O --timeout "$waitTimeoutSec" --interval "$waitIntervalSec"
|
|
130
|
-
--json --status-file "$STATUS_FILE" > ".spur/run/$__runId-pr-findings.json";
|
|
131
|
-
if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi;
|
|
132
|
-
exit 0
|
|
133
|
-
- kind: shell
|
|
134
|
-
options:
|
|
135
|
-
# The report reads the same composite PR/CI/Codex artifact as before (read-only, so a
|
|
136
|
-
# failed probe records its own error object instead of failing the collected run).
|
|
137
|
-
command: >-
|
|
138
|
-
$spurBin builder pr-status --json > ".spur/run/$__runId-pr-status.json" || true
|
|
139
|
-
|
|
140
|
-
- id: done
|
|
141
|
-
description: Terminal — review collected; findings artifact at .spur/run/${vars.__runId}-pr-findings.json
|
|
142
|
-
- id: pending
|
|
143
|
-
description: Terminal — review requested (or timed out) but not yet collected; run /sp:dev-pr-review status later
|
|
144
|
-
- id: failed
|
|
145
|
-
description: Terminal — a gate went red; the stage .status/.json artifacts under .spur/run name the blocker
|
|
146
|
-
|
|
147
|
-
transitions:
|
|
148
|
-
- from: check
|
|
149
|
-
to: precheck
|
|
150
|
-
description: Clean or warn-only — warnings ride along to the report
|
|
151
|
-
guard:
|
|
152
|
-
kind: shell
|
|
153
|
-
options:
|
|
154
|
-
command: 'grep -qE "^(PASS|WARN)$" .spur/run/$__runId-pr-check.status 2>/dev/null'
|
|
155
|
-
- from: check
|
|
156
|
-
to: failed
|
|
157
|
-
terminalReason: failed-check
|
|
158
|
-
description: BLOCK (secrets/.env/conflict markers), a preflight failure (detached HEAD, dirty tree, gh auth, no GitHub remote, or the current branch being the base branch), or a probe failure — stop before any publishing
|
|
159
|
-
guard:
|
|
160
|
-
kind: always
|
|
161
|
-
|
|
162
|
-
- from: precheck
|
|
163
|
-
to: open
|
|
164
|
-
description: Project fast check passed or was skipped
|
|
165
|
-
guard:
|
|
166
|
-
kind: shell
|
|
167
|
-
options:
|
|
168
|
-
command: 'grep -qE "^(PASS|SKIP)$" .spur/run/$__runId-pr-precheck.status 2>/dev/null'
|
|
169
|
-
- from: precheck
|
|
170
|
-
to: failed
|
|
171
|
-
terminalReason: failed-check
|
|
172
|
-
description: Project checks red — do not spend a review request on code that fails its own gate
|
|
173
|
-
guard:
|
|
174
|
-
kind: always
|
|
175
|
-
|
|
176
|
-
- from: open
|
|
177
|
-
to: review
|
|
178
|
-
description: Branch published and PR found or created
|
|
179
|
-
guard:
|
|
180
|
-
kind: shell
|
|
181
|
-
options:
|
|
182
|
-
command: 'grep -qE "^(FOUND|CREATED)$" .spur/run/$__runId-pr-open.status 2>/dev/null'
|
|
183
|
-
- from: open
|
|
184
|
-
to: failed
|
|
185
|
-
terminalReason: failed-check
|
|
186
|
-
description: Push rejected (e.g. non-fast-forward — report; never force-push as a workaround) or no reviewable delta or PR creation failed
|
|
187
|
-
guard:
|
|
188
|
-
kind: always
|
|
189
|
-
|
|
190
|
-
- from: review
|
|
191
|
-
to: done
|
|
192
|
-
description: Current-HEAD review collected (CLEAN/FINDINGS)
|
|
193
|
-
guard:
|
|
194
|
-
kind: shell
|
|
195
|
-
options:
|
|
196
|
-
command: 'grep -qE "^(FINDINGS|CLEAN)$" .spur/run/$__runId-pr-review.status 2>/dev/null'
|
|
197
|
-
- from: review
|
|
198
|
-
to: pending
|
|
199
|
-
description: Request in flight, mode=submit/noWait, or a wait timeout — pending, not failed (collect later)
|
|
200
|
-
guard:
|
|
201
|
-
kind: shell
|
|
202
|
-
options:
|
|
203
|
-
command: 'test "$(cat .spur/run/$__runId-pr-review.status 2>/dev/null)" = PENDING'
|
|
204
|
-
- from: review
|
|
205
|
-
to: failed
|
|
206
|
-
terminalReason: failed-check
|
|
207
|
-
description: Review probe itself failed (no PR, gh error, moved HEAD)
|
|
208
|
-
guard:
|
|
209
|
-
kind: always
|
|
@@ -1,302 +0,0 @@
|
|
|
1
|
-
# Wayfinder resolution pipeline — research/specification tasks without the code
|
|
2
|
-
# implementation pipeline (no task-pipeline / /sp:dev-run recursion).
|
|
3
|
-
#
|
|
4
|
-
# Reliability (aligned with task-pipeline / ADR-043):
|
|
5
|
-
# - Soft precheck (task check + show) → failed via transitions (status file, always exit 0);
|
|
6
|
-
# the show capture doubles as the investigate input bundle (0769: the separate collect
|
|
7
|
-
# state re-ran the same CLI reads with no write in between — deleted)
|
|
8
|
-
# - investigate→verify passes only on a non-empty answer capture (fail-closed both ways)
|
|
9
|
-
# - verify is an independent fresh-session observe-only reviewer over the standard verdict
|
|
10
|
-
# contract (`spur task verdict --from-answer` + proof digest bracket + verify-verdict
|
|
11
|
-
# artifact) — 0769 retires the ad-hoc PASS-word file and the >5-line/>60-word padding
|
|
12
|
-
# metrics; evidence citations must still be truthful (grep -n anchors)
|
|
13
|
-
# - HITL approve routing is exhaustive (yes/no/cancel)
|
|
14
|
-
# - record captures `task record` → `task update done --no-lifecycle` into a status file;
|
|
15
|
-
# record → done is fail-closed on the captured result + persisted status readback — an
|
|
16
|
-
# exit 0 never converts a denied record into success (0769)
|
|
17
|
-
# - Free-form agent inputs are intentional: no pure-slash research surface yet
|
|
18
|
-
|
|
19
|
-
"$schema": "@gobing-ai/spur/schemas/state-machine-workflow.schema.json"
|
|
20
|
-
version: "1"
|
|
21
|
-
kind: state-machine
|
|
22
|
-
name: wayfinder-resolution
|
|
23
|
-
description: "Reusable resolution pipeline for research/specification tasks without invoking the code implementation pipeline"
|
|
24
|
-
iterationBound: 20
|
|
25
|
-
initialState: precheck
|
|
26
|
-
terminalStates:
|
|
27
|
-
- done
|
|
28
|
-
- failed
|
|
29
|
-
- cancelled
|
|
30
|
-
failureStates:
|
|
31
|
-
- failed
|
|
32
|
-
- cancelled
|
|
33
|
-
vars:
|
|
34
|
-
wbs: "0000"
|
|
35
|
-
profile: "standard"
|
|
36
|
-
spurBin: "spur"
|
|
37
|
-
agent: "auto"
|
|
38
|
-
stepTimeoutMs: "1800000"
|
|
39
|
-
approval: "required"
|
|
40
|
-
# Accepted/deferred status the approve gate's decision binding writes (1236 R2).
|
|
41
|
-
approvalStatus: ""
|
|
42
|
-
resolutionMode: "research"
|
|
43
|
-
evidencePolicy: "spur-cli-first"
|
|
44
|
-
__hitlAnswer: ""
|
|
45
|
-
# R8 (0366): injected by WorkflowAppService.run(); run-scopes every capture.
|
|
46
|
-
__runId: ""
|
|
47
|
-
# Resolved per-run by the verify state's taskpath shell step; folded into the proof
|
|
48
|
-
# digest via taskFile (docs/tasks* is excluded from the digest's git-tree half).
|
|
49
|
-
taskSpecPath: ""
|
|
50
|
-
# Proof-state bracket (docs-pipeline precedent): canonical capture at verify entry,
|
|
51
|
-
# live re-capture after the verifier; the verify → record guard compares them.
|
|
52
|
-
proofDigest: ""
|
|
53
|
-
proofDigestNow: ""
|
|
54
|
-
|
|
55
|
-
states:
|
|
56
|
-
- id: precheck
|
|
57
|
-
description: >
|
|
58
|
-
Soft precheck: task check + show, status file, always exit 0 so failures
|
|
59
|
-
route to `failed` via transitions (not a raw lifecycle abort). The `task show`
|
|
60
|
-
capture is reused as the investigate input bundle — no separate collect state
|
|
61
|
-
(0769: same reads, no intervening write, no re-run).
|
|
62
|
-
onEnter:
|
|
63
|
-
- kind: shell
|
|
64
|
-
options:
|
|
65
|
-
# (e) 0825: 8 lines — task check + show capture the investigate input bundle in the
|
|
66
|
-
# same soft probe; show must stay verbatim (it IS the bundle downstream reads).
|
|
67
|
-
command: >-
|
|
68
|
-
mkdir -p .spur/run; $spurBin task check $wbs; c=$?; $spurBin task show $wbs --json > .spur/run/$__runId-wayfinder-input.json && [ "$c" -eq 0 ] && printf 'PASS\n' > .spur/run/$__runId-wayfinder-precheck.status || printf 'FAIL\n' > .spur/run/$__runId-wayfinder-precheck.status; exit 0
|
|
69
|
-
- kind: note
|
|
70
|
-
options:
|
|
71
|
-
message: "Wayfinder resolution started for task ${vars.wbs} (mode=${vars.resolutionMode}, evidence=${vars.evidencePolicy}); no code implementation pipeline is permitted."
|
|
72
|
-
|
|
73
|
-
- id: investigate
|
|
74
|
-
description: "Resolve the task's research/specification requirements and author evidence-backed sections through Spur CLI."
|
|
75
|
-
onEnter:
|
|
76
|
-
- kind: agent.run
|
|
77
|
-
options:
|
|
78
|
-
agent: ${vars.agent}
|
|
79
|
-
capture: true
|
|
80
|
-
# Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
|
|
81
|
-
role: planner
|
|
82
|
-
mode: text
|
|
83
|
-
# (e) 0825: bounded reference-reading prompt (260 chars) — the authoring contract
|
|
84
|
-
# lives in the skill reference sp:wayfinder references/pipeline-resolution.md.
|
|
85
|
-
input: >-
|
|
86
|
-
Resolve wayfinder task ${vars.wbs} per the sp:wayfinder skill (references/pipeline-resolution.md). Mode ${vars.resolutionMode}; evidence policy ${vars.evidencePolicy}; bundle .spur/run/${vars.__runId}-wayfinder-input.json. Finish with a short summary and stop.
|
|
87
|
-
answerFile: .spur/run/${vars.__runId}-wayfinder-answer.md
|
|
88
|
-
expectFile: .spur/run/${vars.__runId}-wayfinder-answer.md
|
|
89
|
-
timeoutMs: ${vars.stepTimeoutMs}
|
|
90
|
-
|
|
91
|
-
- id: verify
|
|
92
|
-
description: >
|
|
93
|
-
Independent, observe-only measured verification (0769): a fresh-session reviewer runs
|
|
94
|
-
/sp:dev-verify --fix none, the standard `spur task verdict` contract derives ONE verdict,
|
|
95
|
-
and a proof-input digest bracket fails closed on verifier-time mutation. Retires the
|
|
96
|
-
ad-hoc resolution-verdict PASS-word file. The verifier never repairs and never edits
|
|
97
|
-
task sections.
|
|
98
|
-
onEnter:
|
|
99
|
-
- kind: shell
|
|
100
|
-
options:
|
|
101
|
-
command: "mkdir -p .spur/run && rm -f .spur/run/$__runId-wayfinder-verify-answer.txt .spur/run/$wbs-verdict.json"
|
|
102
|
-
# Fail-closed task-path lookup (0760 R1 pattern): the resolved path folds into the
|
|
103
|
-
# proof digest via taskFile; a silent miss would degrade the proof to tree-only.
|
|
104
|
-
- kind: shell
|
|
105
|
-
options:
|
|
106
|
-
# (e) 0825: 6 lines — fail-closed lookup feeds every downstream artifact name;
|
|
107
|
-
# folding a silent miss into the digest would fake tree coverage.
|
|
108
|
-
command: >-
|
|
109
|
-
set -e;
|
|
110
|
-
task_path="$($spurBin task path $wbs --json | jq -r '.path // .filePath // empty')";
|
|
111
|
-
if [ -z "$task_path" ]; then echo "wayfinder-resolution: task path did not resolve for wbs $wbs" >&2; exit 1; fi;
|
|
112
|
-
printf '%s' "$task_path" > ".spur/run/$__runId-wayfinder-taskpath.txt"
|
|
113
|
-
- kind: file.read.into-var
|
|
114
|
-
options:
|
|
115
|
-
path: .spur/run/${vars.__runId}-wayfinder-taskpath.txt
|
|
116
|
-
var: taskSpecPath
|
|
117
|
-
- kind: proof.fingerprint
|
|
118
|
-
options:
|
|
119
|
-
var: proofDigest
|
|
120
|
-
taskFile: ${vars.taskSpecPath}
|
|
121
|
-
input: /sp:dev-verify ${vars.wbs} --auto --fix none --focus all
|
|
122
|
-
timeoutMs: ${vars.stepTimeoutMs}
|
|
123
|
-
- kind: agent.run
|
|
124
|
-
options:
|
|
125
|
-
agent: ${vars.agent}
|
|
126
|
-
capture: true
|
|
127
|
-
# Declared Layer-1 role (0538 R2): routing reason beside the agent: pin.
|
|
128
|
-
role: reviewer
|
|
129
|
-
mode: text
|
|
130
|
-
# Observe-only + fresh session (ADR-071 / 0710 R2 precedent): the verifier
|
|
131
|
-
# certifies, it never repairs and never inherits the investigate session.
|
|
132
|
-
freshSession: true
|
|
133
|
-
input: /sp:dev-verify ${vars.wbs} --auto --fix none --focus all
|
|
134
|
-
answerFile: .spur/run/${vars.__runId}-wayfinder-verify-answer.txt
|
|
135
|
-
expectFile: .spur/run/${vars.__runId}-wayfinder-verify-answer.txt
|
|
136
|
-
timeoutMs: ${vars.stepTimeoutMs}
|
|
137
|
-
- kind: shell
|
|
138
|
-
options:
|
|
139
|
-
command: "$spurBin task verdict $wbs --from-answer .spur/run/$__runId-wayfinder-verify-answer.txt"
|
|
140
|
-
- kind: shell
|
|
141
|
-
options:
|
|
142
|
-
# (e) 0825: 6 lines — stamp shell freezes the proof digest + capture point into the
|
|
143
|
-
# verdict before it is registered; the closing guard compares against this stamp.
|
|
144
|
-
command: >-
|
|
145
|
-
V=".spur/run/$wbs-verdict.json";
|
|
146
|
-
if [ -f "$V" ] && [ -n "$proofDigest" ]; then
|
|
147
|
-
jq --arg d "$proofDigest" --arg r "$__runId" '. + {proof: {digest: $d, capturePoint: "wayfinder-verify-entry", runId: $r}}' "$V" > "$V.tmp" && mv "$V.tmp" "$V";
|
|
148
|
-
fi;
|
|
149
|
-
exit 0
|
|
150
|
-
- kind: run.artifact
|
|
151
|
-
options:
|
|
152
|
-
path: .spur/run/${vars.wbs}-verdict.json
|
|
153
|
-
artifactKind: verify-verdict
|
|
154
|
-
- kind: proof.fingerprint
|
|
155
|
-
options:
|
|
156
|
-
var: proofDigestNow
|
|
157
|
-
taskFile: ${vars.taskSpecPath}
|
|
158
|
-
input: /sp:dev-verify ${vars.wbs} --auto --fix none --focus all
|
|
159
|
-
timeoutMs: ${vars.stepTimeoutMs}
|
|
160
|
-
|
|
161
|
-
- id: approve
|
|
162
|
-
description: "Human review gate unless the caller explicitly selects auto approval (vars.approval=auto)."
|
|
163
|
-
onEnter:
|
|
164
|
-
- kind: hitl.confirm
|
|
165
|
-
options:
|
|
166
|
-
prompt: "Approve research resolution for task ${vars.wbs}?"
|
|
167
|
-
# Interactive always prompts the operator; profile=auto answers from the
|
|
168
|
-
# verifier's recorded evidence (1236 R1/R2). No `pause: true` — an evidence
|
|
169
|
-
# binding cannot live in a paused state (0911 D2).
|
|
170
|
-
decision:
|
|
171
|
-
mode: evidence
|
|
172
|
-
statusVar: approvalStatus
|
|
173
|
-
evidenceNodes:
|
|
174
|
-
- verify
|
|
175
|
-
# A deferred/absent answer is the denial today's headless responder gave.
|
|
176
|
-
- kind: shell
|
|
177
|
-
options:
|
|
178
|
-
command: >-
|
|
179
|
-
mkdir -p .spur/run; a="$__hitlAnswer"; [ -n "$a" ] || a=no;
|
|
180
|
-
printf '%s\n' "$a" > ".spur/run/$__runId-wayfinder-approve-answer.txt"
|
|
181
|
-
- kind: file.read.into-var
|
|
182
|
-
options:
|
|
183
|
-
path: .spur/run/${vars.__runId}-wayfinder-approve-answer.txt
|
|
184
|
-
var: __hitlAnswer
|
|
185
|
-
|
|
186
|
-
- id: record
|
|
187
|
-
description: >
|
|
188
|
-
Record the resolution AFTER measured verification (0769). The `task record` verb
|
|
189
|
-
backfills Solution from the diff and moves the task to testing; `task update done
|
|
190
|
-
--no-lifecycle` then completes it (this pipeline's own verify already produced the
|
|
191
|
-
standard verdict evidence). Both results are captured to a run-scoped status file and
|
|
192
|
-
the persisted status is read back — a denied record or a task that never reached done
|
|
193
|
-
routes to `failed` via the guards below and is never converted to success by exit 0.
|
|
194
|
-
onEnter:
|
|
195
|
-
- kind: shell
|
|
196
|
-
options:
|
|
197
|
-
command: >-
|
|
198
|
-
if $spurBin task record $wbs --solution-from-diff --transition testing &&
|
|
199
|
-
$spurBin task update $wbs done --no-lifecycle; then
|
|
200
|
-
printf 'PASS\n' > ".spur/run/$__runId-wayfinder-final.status";
|
|
201
|
-
else
|
|
202
|
-
printf 'FAIL\n' > ".spur/run/$__runId-wayfinder-final.status";
|
|
203
|
-
fi;
|
|
204
|
-
$spurBin task show $wbs --json | jq -r '.status // empty' > ".spur/run/$__runId-wayfinder-status.txt"
|
|
205
|
-
|
|
206
|
-
- id: done
|
|
207
|
-
description: "Research task resolved and ready to feed the implementation backlog."
|
|
208
|
-
onEnter:
|
|
209
|
-
- kind: note
|
|
210
|
-
options:
|
|
211
|
-
message: "Wayfinder research task ${vars.wbs} resolved; implementation remains deferred to the synthesized build backlog."
|
|
212
|
-
|
|
213
|
-
- id: failed
|
|
214
|
-
description: "Research resolution failed a gate; no completion transition is attempted."
|
|
215
|
-
|
|
216
|
-
- id: cancelled
|
|
217
|
-
description: "Operator cancelled the research resolution."
|
|
218
|
-
|
|
219
|
-
transitions:
|
|
220
|
-
- from: precheck
|
|
221
|
-
to: investigate
|
|
222
|
-
description: "Precheck PASS — resolve the research task (input bundle captured at precheck)."
|
|
223
|
-
guard:
|
|
224
|
-
kind: shell
|
|
225
|
-
options:
|
|
226
|
-
command: 'test "$(cat .spur/run/$__runId-wayfinder-precheck.status 2>/dev/null)" = PASS'
|
|
227
|
-
- from: precheck
|
|
228
|
-
to: failed
|
|
229
|
-
terminalReason: failed-check
|
|
230
|
-
description: "Precheck FAIL — stop before delegation."
|
|
231
|
-
guard:
|
|
232
|
-
kind: always
|
|
233
|
-
- from: investigate
|
|
234
|
-
to: verify
|
|
235
|
-
description: "Research resolution authored — verify evidence and traceability. Guard enforces a non-empty answer capture (fail-closed both ways)."
|
|
236
|
-
guard:
|
|
237
|
-
kind: shell
|
|
238
|
-
options:
|
|
239
|
-
command: 'test -s .spur/run/$__runId-wayfinder-answer.md'
|
|
240
|
-
- from: investigate
|
|
241
|
-
to: failed
|
|
242
|
-
terminalReason: failed-agent
|
|
243
|
-
description: "Empty answer capture — investigate produced nothing to verify; stop rather than certify hollow evidence."
|
|
244
|
-
guard:
|
|
245
|
-
kind: shell
|
|
246
|
-
options:
|
|
247
|
-
command: '! test -s .spur/run/$__runId-wayfinder-answer.md'
|
|
248
|
-
- from: verify
|
|
249
|
-
to: record
|
|
250
|
-
description: "Auto profile — record only on a measured PASS verdict with the proof bracket intact (fail-closed to the approve gate otherwise)."
|
|
251
|
-
guard:
|
|
252
|
-
kind: shell
|
|
253
|
-
options:
|
|
254
|
-
# (e) 0825: 5-line guard — approval + digest-bracket + verdict PASS must all hold
|
|
255
|
-
# before record; dropping any operand would let a stale proof auto-record.
|
|
256
|
-
command: >-
|
|
257
|
-
test "$approval" = auto &&
|
|
258
|
-
test -n "$proofDigest" &&
|
|
259
|
-
test "$proofDigestNow" = "$proofDigest" &&
|
|
260
|
-
test -f ".spur/run/$wbs-verdict.json" &&
|
|
261
|
-
test "$(jq -r '.verdict // empty' .spur/run/$wbs-verdict.json 2>/dev/null)" = PASS
|
|
262
|
-
- from: verify
|
|
263
|
-
to: approve
|
|
264
|
-
description: "Verification completed — require explicit review approval."
|
|
265
|
-
guard:
|
|
266
|
-
kind: always
|
|
267
|
-
- from: approve
|
|
268
|
-
to: record
|
|
269
|
-
description: "Operator approved the research resolution."
|
|
270
|
-
guard:
|
|
271
|
-
kind: shell
|
|
272
|
-
options:
|
|
273
|
-
command: 'test "$__hitlAnswer" = yes'
|
|
274
|
-
- from: approve
|
|
275
|
-
to: cancelled
|
|
276
|
-
terminalReason: cancelled
|
|
277
|
-
description: "Operator cancelled the research resolution."
|
|
278
|
-
guard:
|
|
279
|
-
kind: shell
|
|
280
|
-
options:
|
|
281
|
-
command: 'test "$__hitlAnswer" = cancel'
|
|
282
|
-
- from: approve
|
|
283
|
-
to: failed
|
|
284
|
-
terminalReason: cancelled
|
|
285
|
-
description: "Operator rejected the research resolution."
|
|
286
|
-
guard:
|
|
287
|
-
kind: shell
|
|
288
|
-
options:
|
|
289
|
-
command: 'test "$__hitlAnswer" = no'
|
|
290
|
-
- from: record
|
|
291
|
-
to: done
|
|
292
|
-
description: "Captured record result PASS and the persisted status readback is actually done."
|
|
293
|
-
guard:
|
|
294
|
-
kind: shell
|
|
295
|
-
options:
|
|
296
|
-
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'
|
|
297
|
-
- from: record
|
|
298
|
-
to: failed
|
|
299
|
-
terminalReason: failed-check
|
|
300
|
-
description: "Recording failed, was denied, or the task never reached done — stop without claiming completion."
|
|
301
|
-
guard:
|
|
302
|
-
kind: always
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
# Wayfinder resolution-pipeline authoring contract
|
|
2
|
-
|
|
3
|
-
Reference for the `wayfinder-resolution` workflow's `investigate` hop. The pipeline passes a
|
|
4
|
-
bounded pointer prompt; this page carries the full authoring contract the hop must follow.
|
|
5
|
-
Context variables (`${vars.wbs}`, `${vars.resolutionMode}`, `${vars.evidencePolicy}`) are
|
|
6
|
-
resolved by the engine before the hop runs.
|
|
7
|
-
|
|
8
|
-
## Research boundary (preserve the research boundary)
|
|
9
|
-
|
|
10
|
-
- Work only from the prepared local bundle `.spur/run/<runId>-wayfinder-input.json`, local
|
|
11
|
-
shell/file reads, and the `spur` CLI. Do not use network search or MCP tools.
|
|
12
|
-
- Do not invoke `task-pipeline.yaml`, `/sp:dev-run`, `/sp:dev-runall`, or any code
|
|
13
|
-
implementation pipeline. This hop authors research/specification sections — it never
|
|
14
|
-
implements.
|
|
15
|
-
|
|
16
|
-
## Procedure
|
|
17
|
-
|
|
18
|
-
1. Read the task file for `<wbs>` and map its existing Requirements and Acceptance Criteria
|
|
19
|
-
onto the existing Design/Plan/References sections.
|
|
20
|
-
2. Author concise Solution, Testing, and Review sections through
|
|
21
|
-
`spur task update --section --from-file` (write each section to a file, then pass it).
|
|
22
|
-
3. Finish with a short summary and stop.
|
|
23
|
-
|
|
24
|
-
## Evidence-anchor contract (mandatory — 0299 R1 line-anchor rule)
|
|
25
|
-
|
|
26
|
-
When the task's evidence lives in a shared evidence file, anchor every Solution/Testing
|
|
27
|
-
`file:line` citation truthfully — resolve the section's real start line with
|
|
28
|
-
`grep -n "^## <wbs> " <evidence-file>` and cite that exact line. NEVER copy a line number
|
|
29
|
-
from another ticket's example; each WBS anchors to its own section. Before finishing, re-read
|
|
30
|
-
each cited line and confirm it names the requirement's subject.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{ah as o,ai as n}from"./mermaid.core.BDQ2FoPd.js";const t=(a,r)=>o.lang.round(n.parse(a)[r]);export{t as c};
|