@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.
Files changed (121) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/config.global.yaml +21 -8
  3. package/config/decisions/executor.yaml +53 -0
  4. package/config/decisions/task-pipeline.yaml +44 -28
  5. package/config/pipeline-budgets.json +0 -14
  6. package/config/workflow-candidates.json +18 -0
  7. package/config/workflows/feature-lifecycle.yaml +9 -16
  8. package/config/workflows/idea-pipeline.yaml +158 -740
  9. package/config/workflows/task-pipeline.yaml +66 -54
  10. package/config/workflows/wrapup-pipeline.yaml +91 -623
  11. package/package.json +11 -10
  12. package/plugins/sp/README.md +9 -5
  13. package/plugins/sp/agents/expert-spur.md +3 -0
  14. package/plugins/sp/agents/super-planner.md +5 -1
  15. package/plugins/sp/agents/super-reviewer.md +43 -12
  16. package/plugins/sp/commands/dev-fixall.md +7 -2
  17. package/plugins/sp/commands/dev-idea.md +15 -6
  18. package/plugins/sp/commands/dev-plan.md +1 -1
  19. package/plugins/sp/commands/dev-pr-review.md +6 -6
  20. package/plugins/sp/commands/dev-run.md +3 -0
  21. package/plugins/sp/commands/dev-runall.md +6 -3
  22. package/plugins/sp/commands/dev-verify.md +1 -1
  23. package/plugins/sp/commands/dev-wrap.md +1 -1
  24. package/plugins/sp/commands/dev-wrapall.md +4 -4
  25. package/plugins/sp/plugin.json +1 -1
  26. package/plugins/sp/skills/code-implementation/SKILL.md +8 -8
  27. package/plugins/sp/skills/code-improvement/SKILL.md +3 -3
  28. package/plugins/sp/skills/code-review/references/verification-before-completion.md +5 -4
  29. package/plugins/sp/skills/code-verification/SKILL.md +4 -4
  30. package/plugins/sp/skills/code-verification/references/verdict-schema.md +27 -11
  31. package/plugins/sp/skills/functional-review/SKILL.md +1 -1
  32. package/plugins/sp/skills/functional-review/references/verdict-schema.md +1 -1
  33. package/plugins/sp/skills/next-router/references/routing-table.md +1 -1
  34. package/plugins/sp/skills/pr-reviewing/SKILL.md +36 -18
  35. package/plugins/sp/skills/spec-decomposition/references/decomposition.md +2 -1
  36. package/plugins/sp/skills/spur-check/SKILL.md +1 -1
  37. package/plugins/sp/skills/spur-cli/SKILL.md +23 -2
  38. package/plugins/sp/skills/spur-cli/references/agent.md +12 -0
  39. package/plugins/sp/skills/spur-cli/references/builder.md +2 -2
  40. package/plugins/sp/skills/spur-cli/references/decision/lifecycle.md +166 -0
  41. package/plugins/sp/skills/spur-cli/references/decision.md +146 -16
  42. package/plugins/sp/skills/spur-cli/references/features.md +19 -0
  43. package/plugins/sp/skills/spur-cli/references/rules.md +2 -0
  44. package/plugins/sp/skills/spur-cli/references/tasks.md +14 -1
  45. package/plugins/sp/skills/spur-cli/references/workflows/authoring-workflows.md +1 -1
  46. package/plugins/sp/skills/spur-cli/references/workflows/workflow-fit-and-tuning.md +3 -2
  47. package/plugins/sp/skills/spur-cli/references/workflows.md +9 -0
  48. package/plugins/sp/skills/spur-composer/SKILL.md +20 -1
  49. package/plugins/sp/skills/spur-dev/SKILL.md +16 -16
  50. package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +2 -1
  51. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +2 -2
  52. package/plugins/sp/skills/spur-dev/references/decision-points.md +97 -0
  53. package/plugins/sp/skills/spur-dev/references/dev-operations.md +18 -18
  54. package/plugins/sp/skills/spur-dev/references/execution-batch-report.md +1 -1
  55. package/plugins/sp/skills/spur-dev/references/execution-batch.md +19 -10
  56. package/plugins/sp/skills/spur-dev/references/execution-parallel-isolation.md +4 -4
  57. package/plugins/sp/skills/spur-dev/references/execution-workflow.md +41 -29
  58. package/plugins/sp/skills/spur-dev/references/execution-worktree-landing.md +34 -2
  59. package/plugins/sp/skills/spur-dev/references/execution-worktree-setup.md +4 -4
  60. package/plugins/sp/skills/spur-dev/references/flag-glossary.md +3 -3
  61. package/plugins/sp/skills/spur-dev/references/gate-checklists.md +3 -2
  62. package/plugins/sp/skills/spur-dev/references/glossary.md +12 -3
  63. package/plugins/sp/skills/spur-dev/references/planning-workflow.md +7 -6
  64. package/plugins/sp/skills/spur-doctor/SKILL.md +23 -0
  65. package/plugins/sp/skills/wayfinder/SKILL.md +11 -1
  66. package/spur.js +25617 -24290
  67. package/web/_astro/{BoardApp.Bjdp3XWV.js → BoardApp.CC7Mwswv.js} +65 -65
  68. package/web/_astro/{BoardApp.DCDZxLlQ.js → BoardApp.mWyrWCAR.js} +1 -1
  69. package/web/_astro/{TaskDetail.B3vBxynO.js → TaskDetail.CtAXuiv8.js} +1 -1
  70. package/web/_astro/{arc.DcuHTB_T.js → arc.Duf4u60i.js} +1 -1
  71. package/web/_astro/{architectureDiagram-3BPJPVTR.ClOFWBON.js → architectureDiagram-3BPJPVTR.JoymtqxN.js} +1 -1
  72. package/web/_astro/{blockDiagram-GPEHLZMM.otYyr7Zb.js → blockDiagram-GPEHLZMM.BvmhcioC.js} +1 -1
  73. package/web/_astro/{c4Diagram-AAUBKEIU.BCjpc9LP.js → c4Diagram-AAUBKEIU.CfaWkgoQ.js} +1 -1
  74. package/web/_astro/channel.DtEPXXcH.js +1 -0
  75. package/web/_astro/{chunk-2J33WTMH.D5Wpnpt_.js → chunk-2J33WTMH.B7uR02cD.js} +1 -1
  76. package/web/_astro/{chunk-4BX2VUAB.DkQGtWNz.js → chunk-4BX2VUAB.SwiEauYR.js} +1 -1
  77. package/web/_astro/{chunk-55IACEB6.B7dqjAip.js → chunk-55IACEB6.6ZRCK8PO.js} +1 -1
  78. package/web/_astro/{chunk-727SXJPM.BDQvnKE2.js → chunk-727SXJPM.Cxra_G3N.js} +1 -1
  79. package/web/_astro/{chunk-AQP2D5EJ.D92doBX5.js → chunk-AQP2D5EJ.Cxd7gZeX.js} +1 -1
  80. package/web/_astro/{chunk-FMBD7UC4.C968oI5G.js → chunk-FMBD7UC4.DCLhFkVc.js} +1 -1
  81. package/web/_astro/{chunk-ND2GUHAM.AkkYC1bY.js → chunk-ND2GUHAM.B9AmKcv6.js} +1 -1
  82. package/web/_astro/{chunk-QZHKN3VN.sCc-rKKo.js → chunk-QZHKN3VN.DOjCvl6S.js} +1 -1
  83. package/web/_astro/{classDiagram-4FO5ZUOK.pOQ9u0mY.js → classDiagram-4FO5ZUOK.BMiT_mNf.js} +1 -1
  84. package/web/_astro/{classDiagram-v2-Q7XG4LA2.pOQ9u0mY.js → classDiagram-v2-Q7XG4LA2.BMiT_mNf.js} +1 -1
  85. package/web/_astro/{cose-bilkent-S5V4N54A.CRaeD6FY.js → cose-bilkent-S5V4N54A.mLBCEGjI.js} +1 -1
  86. package/web/_astro/{cynefin-OW5HDTMX.BiCPBu54.js → cynefin-OW5HDTMX.CjDAY0qn.js} +1 -1
  87. package/web/_astro/{dagre-BM42HDAG.C1-q3vkT.js → dagre-BM42HDAG._G_sP8fP.js} +1 -1
  88. package/web/_astro/{diagram-2AECGRRQ.BSVOv30O.js → diagram-2AECGRRQ.39OcfSuz.js} +1 -1
  89. package/web/_astro/{diagram-5GNKFQAL.CHMkjJ-V.js → diagram-5GNKFQAL.D7v_eNC4.js} +1 -1
  90. package/web/_astro/{diagram-KO2AKTUF.CKY9M564.js → diagram-KO2AKTUF.Da1x-lhg.js} +1 -1
  91. package/web/_astro/{diagram-LMA3HP47.B9yNJiTP.js → diagram-LMA3HP47.C8EnzbEb.js} +1 -1
  92. package/web/_astro/{diagram-OG6HWLK6.Dk8AUGsk.js → diagram-OG6HWLK6.DPnBj69F.js} +1 -1
  93. package/web/_astro/{erDiagram-TEJ5UH35.BQHR89TZ.js → erDiagram-TEJ5UH35.CXMu2TIh.js} +1 -1
  94. package/web/_astro/{flowDiagram-I6XJVG4X.oNkWVgoK.js → flowDiagram-I6XJVG4X.ZklePVtQ.js} +1 -1
  95. package/web/_astro/{ganttDiagram-6RSMTGT7.Kz2U2nu9.js → ganttDiagram-6RSMTGT7.BhYOkdqk.js} +1 -1
  96. package/web/_astro/{gitGraphDiagram-PVQCEYII.DHIZ_wPq.js → gitGraphDiagram-PVQCEYII.CADyX8a1.js} +1 -1
  97. package/web/_astro/{infoDiagram-5YYISTIA.D0NJLcv9.js → infoDiagram-5YYISTIA.BsdmwjHt.js} +1 -1
  98. package/web/_astro/{ishikawaDiagram-YF4QCWOH.CFEfTWRG.js → ishikawaDiagram-YF4QCWOH.CzjZ3Crd.js} +1 -1
  99. package/web/_astro/{journeyDiagram-JHISSGLW.Dc7IE7I4.js → journeyDiagram-JHISSGLW.Bxj-ZH_t.js} +1 -1
  100. package/web/_astro/{kanban-definition-UN3LZRKU.D5v0xO9k.js → kanban-definition-UN3LZRKU.Cbg3wVvX.js} +1 -1
  101. package/web/_astro/{linear.wR5KzXnE.js → linear.DJNUrBI9.js} +1 -1
  102. package/web/_astro/{mermaid.core.BDQ2FoPd.js → mermaid.core.DVHQV3SF.js} +4 -4
  103. package/web/_astro/{mindmap-definition-RKZ34NQL.W6_INsia.js → mindmap-definition-RKZ34NQL.DyomosRU.js} +1 -1
  104. package/web/_astro/{pieDiagram-4H26LBE5.61ihbgkK.js → pieDiagram-4H26LBE5.DajtFknN.js} +1 -1
  105. package/web/_astro/{quadrantDiagram-W4KKPZXB.B5lEpFLo.js → quadrantDiagram-W4KKPZXB.Bjq6SjGe.js} +1 -1
  106. package/web/_astro/{requirementDiagram-4Y6WPE33.CmhVBVX0.js → requirementDiagram-4Y6WPE33.ubBVqGLP.js} +1 -1
  107. package/web/_astro/{sankeyDiagram-5OEKKPKP.D7Vvj9Wf.js → sankeyDiagram-5OEKKPKP.I4q46xd-.js} +1 -1
  108. package/web/_astro/{sequenceDiagram-3UESZ5HK.B1vPLixM.js → sequenceDiagram-3UESZ5HK.DsCgZIa8.js} +1 -1
  109. package/web/_astro/{stateDiagram-AJRCARHV.BnACmrGi.js → stateDiagram-AJRCARHV.DcYjYSqT.js} +1 -1
  110. package/web/_astro/{stateDiagram-v2-BHNVJYJU.CW4pnmc3.js → stateDiagram-v2-BHNVJYJU.Dt8yPqiS.js} +1 -1
  111. package/web/_astro/{timeline-definition-PNZ67QCA.CkzMCPnC.js → timeline-definition-PNZ67QCA.0YTkoa5F.js} +1 -1
  112. package/web/_astro/{vennDiagram-CIIHVFJN.CY4aNdAR.js → vennDiagram-CIIHVFJN.BNl0l1hs.js} +1 -1
  113. package/web/_astro/{wardleyDiagram-YWT4CUSO.BtoU9UFk.js → wardleyDiagram-YWT4CUSO.BYSX6cfn.js} +1 -1
  114. package/web/_astro/{xychartDiagram-2RQKCTM6._9ijUUAs.js → xychartDiagram-2RQKCTM6.DzxxpixK.js} +1 -1
  115. package/web/index.html +1 -1
  116. package/worker/laya_worker.py +219 -0
  117. package/config/workflows/feature-verification.yaml +0 -98
  118. package/config/workflows/pr-review.yaml +0 -209
  119. package/config/workflows/wayfinder-resolution.yaml +0 -302
  120. package/plugins/sp/skills/wayfinder/references/pipeline-resolution.md +0 -30
  121. 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};