@gobing-ai/spur 0.3.78 → 0.3.81

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 (177) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/config.example.yaml +29 -18
  3. package/config/config.global.yaml +10 -11
  4. package/config/pipeline-budgets.json +34 -2
  5. package/config/plugin-scripts.json +25 -0
  6. package/config/rules/boundary/config-loading-ownership.yaml +0 -3
  7. package/config/rules/boundary/dao-boundary.yaml +4 -17
  8. package/config/rules/boundary/planning-folder-hardcode.yaml +0 -1
  9. package/config/rules/boundary/sp-no-vendor-refs.yaml +3 -2
  10. package/config/rules/boundary/sp-runtime-path.yaml +3 -14
  11. package/config/rules/quality/coverage-gate.yaml +3 -14
  12. package/config/rules/quality/tsdoc-exports.yaml +4 -7
  13. package/config/rules/strict/http-boundaries.yaml +5 -8
  14. package/config/rules/strict/runtime-boundaries.yaml +1 -5
  15. package/config/rules/structure/protected-files.yaml +9 -3
  16. package/config/rules/structure/test-focus-skip.yaml +0 -2
  17. package/config/rules/structure/test-location.yaml +0 -5
  18. package/config/rules/surface/check-cli-surface.yaml +3 -2
  19. package/config/rules/typescript/bun-tooling.yaml +5 -7
  20. package/config/rules/typescript/guarded-happy-dom-register.yaml +0 -2
  21. package/config/rules/typescript/happy-dom-teardown.yaml +0 -2
  22. package/config/rules/typescript/no-biome-suppressions.yaml +0 -2
  23. package/config/rules/typescript/no-debugger.yaml +0 -2
  24. package/config/rules/typescript/no-eslint-suppressions.yaml +0 -4
  25. package/config/rules/typescript/no-leaky-module-mocks.yaml +6 -13
  26. package/config/rules/typescript/no-module-scope-import-calls.yaml +0 -2
  27. package/config/rules/typescript/no-syscall-emulation-in-boundary-mock.yaml +0 -3
  28. package/config/rules/typescript/no-unmocked-module-eval-side-effects.yaml +0 -3
  29. package/config/rules/typescript/output-boundaries.yaml +0 -3
  30. package/config/rules/typescript/prefer-accessible-role-for-button-queries.yaml +0 -3
  31. package/config/rules/ui/ui-import-boundary.yaml +1 -5
  32. package/config/templates/AGENTS.md +26 -23
  33. package/config/templates/docs/00_ADR.md +13 -23
  34. package/config/templates/docs/01_PRD.md +5 -2
  35. package/config/templates/docs/02_ROADMAP.md +9 -13
  36. package/config/templates/docs/03_ARCHITECTURE.md +2 -2
  37. package/config/templates/docs/04_DESIGN.md +12 -31
  38. package/config/templates/docs/05_FEATURES.md +6 -18
  39. package/config/templates/docs/99_PROJECT_CONSTITUTION.md +162 -394
  40. package/config/transition-shims.json +7 -7
  41. package/config/workflows/basic.yaml +4 -0
  42. package/config/workflows/docs-pipeline.yaml +13 -14
  43. package/config/workflows/feature-dev.yaml +20 -65
  44. package/config/workflows/history-anatomy.yaml +22 -1
  45. package/config/workflows/idea-pipeline.yaml +53 -97
  46. package/config/workflows/pr-review.yaml +21 -33
  47. package/config/workflows/task-pipeline.yaml +87 -330
  48. package/config/workflows/wayfinder-resolution.yaml +12 -26
  49. package/config/workflows/wrapup-pipeline.yaml +48 -189
  50. package/package.json +9 -9
  51. package/plugins/sp/README.md +22 -8
  52. package/plugins/sp/agents/expert-spur.md +41 -19
  53. package/plugins/sp/agents/super-reviewer.md +43 -8
  54. package/plugins/sp/lib/idea-handoff.generated.d.mts +17 -0
  55. package/plugins/sp/lib/idea-handoff.generated.mjs +1301 -0
  56. package/plugins/sp/plugin.json +1 -1
  57. package/plugins/sp/scripts/feature-dev-precheck.mjs +146 -0
  58. package/plugins/sp/scripts/feature-dev-precheck.ts +238 -0
  59. package/plugins/sp/scripts/idea-handoff.mjs +27 -0
  60. package/plugins/sp/scripts/idea-handoff.ts +44 -0
  61. package/plugins/sp/scripts/quality-gate.mjs +165 -0
  62. package/plugins/sp/scripts/quality-gate.ts +217 -0
  63. package/plugins/sp/scripts/verify-answer-lint.ts +21 -3
  64. package/plugins/sp/scripts/workflow-step-profile.mjs +319 -0
  65. package/plugins/sp/scripts/workflow-step-profile.ts +456 -0
  66. package/plugins/sp/scripts/wrapup-steps.mjs +350 -0
  67. package/plugins/sp/scripts/wrapup-steps.ts +466 -0
  68. package/plugins/sp/skills/conflict-finding/SKILL.md +6 -0
  69. package/plugins/sp/skills/daily-summary/SKILL.md +1 -1
  70. package/plugins/sp/skills/doc-evolve/SKILL.md +26 -40
  71. package/plugins/sp/skills/doc-evolve/references/operations.md +17 -30
  72. package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +1 -1
  73. package/plugins/sp/skills/spec-decomposition/references/decomposition.md +29 -0
  74. package/plugins/sp/skills/spur-cli/references/agent.md +56 -14
  75. package/plugins/sp/skills/spur-cli/references/message.md +30 -3
  76. package/plugins/sp/skills/spur-cli/references/projects.md +45 -1
  77. package/plugins/sp/skills/spur-cli/references/self.md +5 -4
  78. package/plugins/sp/skills/spur-cli/references/serve.md +5 -4
  79. package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +17 -1
  80. package/plugins/sp/skills/spur-cli/references/tasks.md +32 -2
  81. package/plugins/sp/skills/spur-cli/references/team.md +21 -1
  82. package/plugins/sp/skills/spur-cli/references/workflows/operations.md +6 -3
  83. package/plugins/sp/skills/spur-cli/references/workflows/workflow-fit-and-tuning.md +57 -18
  84. package/plugins/sp/skills/spur-composer/SKILL.md +145 -0
  85. package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +14 -0
  86. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +3 -3
  87. package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +12 -0
  88. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +46 -4
  89. package/plugins/sp/skills/spur-dev/references/planning-workflow.md +24 -0
  90. package/plugins/sp/skills/spur-doctor/SKILL.md +138 -0
  91. package/plugins/sp/skills/taste-refactoring-api/README.md +43 -0
  92. package/plugins/sp/skills/taste-refactoring-api/SKILL.md +334 -0
  93. package/plugins/sp/skills/taste-refactoring-api/checklists/daily-api-review.md +71 -0
  94. package/plugins/sp/skills/taste-refactoring-api/examples/refactor-example.md +72 -0
  95. package/plugins/sp/skills/taste-refactoring-api/examples/review-template.md +93 -0
  96. package/plugins/sp/skills/taste-refactoring-api/references/api-refactoring-playbook.md +253 -0
  97. package/plugins/sp/skills/taste-refactoring-api/references/protocol-modes.md +79 -0
  98. package/plugins/sp/skills/taste-refactoring-api/references/research-basis.md +58 -0
  99. package/plugins/sp/skills/taste-refactoring-architect/README.md +26 -0
  100. package/plugins/sp/skills/taste-refactoring-architect/SKILL.md +471 -0
  101. package/plugins/sp/skills/taste-refactoring-architect/checklists/daily-architecture-review.md +48 -0
  102. package/plugins/sp/skills/taste-refactoring-architect/examples/refactor-example.md +55 -0
  103. package/plugins/sp/skills/taste-refactoring-architect/examples/review-template.md +51 -0
  104. package/plugins/sp/skills/taste-refactoring-architect/references/architecture-refactoring-playbook.md +173 -0
  105. package/plugins/sp/skills/taste-refactoring-architect/references/research-basis.md +28 -0
  106. package/plugins/sp/skills/taste-refactoring-tests/README.md +28 -0
  107. package/plugins/sp/skills/taste-refactoring-tests/SKILL.md +482 -0
  108. package/plugins/sp/skills/taste-refactoring-tests/checklists/daily-test-review.md +39 -0
  109. package/plugins/sp/skills/taste-refactoring-tests/examples/refactor-example.md +85 -0
  110. package/plugins/sp/skills/taste-refactoring-tests/examples/review-template.md +59 -0
  111. package/plugins/sp/skills/taste-refactoring-tests/references/research-basis.md +47 -0
  112. package/plugins/sp/skills/taste-refactoring-tests/references/test-refactoring-playbook.md +222 -0
  113. package/plugins/sp/skills/taste-refactoring-ui/README.md +12 -0
  114. package/plugins/sp/skills/taste-refactoring-ui/SKILL.md +290 -0
  115. package/plugins/sp/skills/taste-refactoring-ui/checklists/daily-ui-review.md +72 -0
  116. package/plugins/sp/skills/taste-refactoring-ui/examples/review-template.md +51 -0
  117. package/plugins/sp/skills/taste-refactoring-ui/references/refactoring-ui-playbook.md +170 -0
  118. package/plugins/sp/skills/wayfinder/SKILL.md +2 -2
  119. package/plugins/sp/skills/wayfinder/references/pipeline-resolution.md +30 -0
  120. package/schemas/spur-config.schema.json +49 -0
  121. package/spur.js +46936 -44198
  122. package/web/_astro/{BoardApp.CHQ1lycZ.js → BoardApp.B1U26g3I.js} +97 -95
  123. package/web/_astro/BoardApp.Csgyg-lS.js +1 -0
  124. package/web/_astro/{TaskDetail.GKfQJ60c.js → TaskDetail.DwPqpq7v.js} +1 -1
  125. package/web/_astro/{arc.DWEtA3Tx.js → arc.CweZEjN2.js} +1 -1
  126. package/web/_astro/{architectureDiagram-3BPJPVTR.DB42oWmP.js → architectureDiagram-3BPJPVTR.D89pbDuv.js} +1 -1
  127. package/web/_astro/{blockDiagram-GPEHLZMM.rhv-zNQV.js → blockDiagram-GPEHLZMM.BOuTeEpX.js} +1 -1
  128. package/web/_astro/{c4Diagram-AAUBKEIU.Ci4-4VvY.js → c4Diagram-AAUBKEIU.CASbkWZF.js} +1 -1
  129. package/web/_astro/channel.Cx6sXxhq.js +1 -0
  130. package/web/_astro/{chunk-2J33WTMH.Cc9veUgf.js → chunk-2J33WTMH.BKQYtOvY.js} +1 -1
  131. package/web/_astro/{chunk-4BX2VUAB.Bec9c4eI.js → chunk-4BX2VUAB.9sHLdMtG.js} +1 -1
  132. package/web/_astro/{chunk-55IACEB6.DoV8S1iB.js → chunk-55IACEB6.wOLXWlPs.js} +1 -1
  133. package/web/_astro/{chunk-727SXJPM.DwR-Qlyj.js → chunk-727SXJPM.DovFbwg3.js} +1 -1
  134. package/web/_astro/{chunk-AQP2D5EJ.ND_a81WY.js → chunk-AQP2D5EJ.B1Weod1X.js} +1 -1
  135. package/web/_astro/{chunk-FMBD7UC4.Wv_jwG48.js → chunk-FMBD7UC4.TEMS04st.js} +1 -1
  136. package/web/_astro/{chunk-ND2GUHAM.CXKXCMmp.js → chunk-ND2GUHAM.Cp8VT1wQ.js} +1 -1
  137. package/web/_astro/{chunk-QZHKN3VN.nkaoNYQq.js → chunk-QZHKN3VN.BzATdEcP.js} +1 -1
  138. package/web/_astro/{classDiagram-4FO5ZUOK.cMQcVlQu.js → classDiagram-4FO5ZUOK.C9BOCfAO.js} +1 -1
  139. package/web/_astro/{classDiagram-v2-Q7XG4LA2.cMQcVlQu.js → classDiagram-v2-Q7XG4LA2.C9BOCfAO.js} +1 -1
  140. package/web/_astro/{cose-bilkent-S5V4N54A.OaDJ7Mr2.js → cose-bilkent-S5V4N54A.DUnr4UAw.js} +1 -1
  141. package/web/_astro/{cynefin-OW5HDTMX.Chi8IphF.js → cynefin-OW5HDTMX.rYq5uM3D.js} +1 -1
  142. package/web/_astro/{cytoscape.esm.DzSz-X2X.js → cytoscape.esm.BB4DxJjf.js} +1 -1
  143. package/web/_astro/{dagre-BM42HDAG.CzK2t_Fp.js → dagre-BM42HDAG.CWeNKe3I.js} +1 -1
  144. package/web/_astro/{diagram-2AECGRRQ.DRvxlVS7.js → diagram-2AECGRRQ.DCkfls10.js} +1 -1
  145. package/web/_astro/{diagram-5GNKFQAL.CnYvNdwA.js → diagram-5GNKFQAL.D5U4JCka.js} +1 -1
  146. package/web/_astro/{diagram-KO2AKTUF.CpLpMw5R.js → diagram-KO2AKTUF.BZJgqaqG.js} +1 -1
  147. package/web/_astro/{diagram-LMA3HP47.JTb78qUA.js → diagram-LMA3HP47.DoMeHvPR.js} +1 -1
  148. package/web/_astro/{diagram-OG6HWLK6.Bk-1jDIb.js → diagram-OG6HWLK6.B50qwwWX.js} +1 -1
  149. package/web/_astro/{erDiagram-TEJ5UH35.D8hN9GZq.js → erDiagram-TEJ5UH35.DdGPG6LK.js} +1 -1
  150. package/web/_astro/{flowDiagram-I6XJVG4X.-6zQr6m5.js → flowDiagram-I6XJVG4X.QP2MJ12u.js} +1 -1
  151. package/web/_astro/{ganttDiagram-6RSMTGT7.DboLQ9ca.js → ganttDiagram-6RSMTGT7.BI6LgKSy.js} +1 -1
  152. package/web/_astro/{gitGraphDiagram-PVQCEYII.4tYvJKGR.js → gitGraphDiagram-PVQCEYII.npPZiC2G.js} +1 -1
  153. package/web/_astro/index.DayyIngm.css +1 -0
  154. package/web/_astro/{infoDiagram-5YYISTIA.Bd9rXpsB.js → infoDiagram-5YYISTIA.DCJCBVbp.js} +1 -1
  155. package/web/_astro/{ishikawaDiagram-YF4QCWOH.CvMoaf67.js → ishikawaDiagram-YF4QCWOH.BMLV-3I1.js} +1 -1
  156. package/web/_astro/{journeyDiagram-JHISSGLW.Ccy1CA7y.js → journeyDiagram-JHISSGLW.LE58crde.js} +1 -1
  157. package/web/_astro/{kanban-definition-UN3LZRKU.0MaMqHNS.js → kanban-definition-UN3LZRKU.BPbz8rH9.js} +1 -1
  158. package/web/_astro/{linear.CHXgcIbN.js → linear.DhZaBtYh.js} +1 -1
  159. package/web/_astro/{mermaid.core.Ca-kcelG.js → mermaid.core.BD5-jXum.js} +6 -6
  160. package/web/_astro/{mindmap-definition-RKZ34NQL.BUIDlHa0.js → mindmap-definition-RKZ34NQL.MTJyrQ65.js} +1 -1
  161. package/web/_astro/ordinal.BYWQX77i.js +1 -0
  162. package/web/_astro/{pieDiagram-4H26LBE5.2dX3CU1s.js → pieDiagram-4H26LBE5.BrDhDvIS.js} +1 -1
  163. package/web/_astro/{quadrantDiagram-W4KKPZXB.B3LBlRiv.js → quadrantDiagram-W4KKPZXB.71d73_5N.js} +1 -1
  164. package/web/_astro/{requirementDiagram-4Y6WPE33.X12I2uNx.js → requirementDiagram-4Y6WPE33.Bga6UF-z.js} +1 -1
  165. package/web/_astro/{sankeyDiagram-5OEKKPKP.BXohIHqx.js → sankeyDiagram-5OEKKPKP.BnHs4K82.js} +1 -1
  166. package/web/_astro/{sequenceDiagram-3UESZ5HK.C37ZIUzg.js → sequenceDiagram-3UESZ5HK.DsfY2gnj.js} +1 -1
  167. package/web/_astro/{stateDiagram-AJRCARHV.BRgz317z.js → stateDiagram-AJRCARHV.DvsTSc9a.js} +1 -1
  168. package/web/_astro/{stateDiagram-v2-BHNVJYJU.7VYSXN9-.js → stateDiagram-v2-BHNVJYJU.DxzzmHUR.js} +1 -1
  169. package/web/_astro/{timeline-definition-PNZ67QCA.BVNz_HiN.js → timeline-definition-PNZ67QCA.4ZuQmOTt.js} +1 -1
  170. package/web/_astro/{vennDiagram-CIIHVFJN.CHVDkPX4.js → vennDiagram-CIIHVFJN.Ck5Q86SG.js} +1 -1
  171. package/web/_astro/{wardleyDiagram-YWT4CUSO.EQQ_qT9v.js → wardleyDiagram-YWT4CUSO.BK7k2hXr.js} +1 -1
  172. package/web/_astro/{xychartDiagram-2RQKCTM6.DrAT9WoP.js → xychartDiagram-2RQKCTM6.DfCrgauK.js} +1 -1
  173. package/web/index.html +2 -2
  174. package/web/_astro/BoardApp.DV9kx0wo.js +0 -1
  175. package/web/_astro/channel.BAI6xLeV.js +0 -1
  176. package/web/_astro/index.Dcr_8fiK.css +0 -1
  177. package/web/_astro/ordinal.DBvzRdQf.js +0 -1
@@ -67,6 +67,8 @@ states:
67
67
  onEnter:
68
68
  - kind: shell
69
69
  options:
70
+ # (e) 0825: 10 lines — detached-HEAD/dirty/gh-auth/base-refusal probes must record
71
+ # before any push can publish; split would let a half-probed run continue.
70
72
  command: >-
71
73
  mkdir -p .spur/run &&
72
74
  STATUS_FILE=".spur/run/$__runId-pr-preflight.status" &&
@@ -83,6 +85,8 @@ states:
83
85
  onEnter:
84
86
  - kind: shell
85
87
  options:
88
+ # (e) 0825: 9 lines — hygiene verdict + json capture land together; the status-file
89
+ # fallback keeps a silent driver from passing the gate.
86
90
  command: >-
87
91
  mkdir -p .spur/run &&
88
92
  STATUS_FILE=".spur/run/$__runId-pr-hygiene.status" &&
@@ -100,16 +104,10 @@ states:
100
104
  onEnter:
101
105
  - kind: shell
102
106
  options:
107
+ # (e) 0825: 7 lines — unchanged shape (optional preReviewCmd probe, SKIP/PASS/FAIL)
108
+ # condensed onto folded one-liners to hold the §1.2 budget.
103
109
  command: >-
104
- mkdir -p .spur/run &&
105
- STATUS_FILE=".spur/run/$__runId-pr-precheck.status" &&
106
- if [ -z "$preReviewCmd" ]; then
107
- printf 'SKIP\n' > "$STATUS_FILE";
108
- else
109
- set +e; sh -c "$preReviewCmd"; rc=$?; set -e;
110
- if [ "$rc" -eq 0 ]; then printf 'PASS\n' > "$STATUS_FILE"; else printf 'FAIL\n' > "$STATUS_FILE"; fi;
111
- fi &&
112
- exit 0
110
+ 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"
113
111
 
114
112
  - id: push
115
113
  description: >
@@ -118,6 +116,8 @@ states:
118
116
  onEnter:
119
117
  - kind: shell
120
118
  options:
119
+ # (e) 0825: 9 lines — push result and status fallback are atomic; a split could
120
+ # publish commits without recording the outcome.
121
121
  command: >-
122
122
  mkdir -p .spur/run &&
123
123
  STATUS_FILE=".spur/run/$__runId-pr-push.status" &&
@@ -133,6 +133,8 @@ states:
133
133
  onEnter:
134
134
  - kind: shell
135
135
  options:
136
+ # (e) 0825: 9 lines — PR dedupe lookup captures its record for the downstream
137
+ # review link; ensure + capture must not race.
136
138
  command: >-
137
139
  mkdir -p .spur/run &&
138
140
  STATUS_FILE=".spur/run/$__runId-pr-ensure.status" &&
@@ -150,19 +152,10 @@ states:
150
152
  onEnter:
151
153
  - kind: shell
152
154
  options:
155
+ # (e) 0825: 10 lines — the write-then-read split is the file-var transport feeding
156
+ # wait/collect and must stay one action (same record, same run scope).
153
157
  command: >-
154
- mkdir -p .spur/run &&
155
- STATUS_FILE=".spur/run/$__runId-pr-request.status" &&
156
- FORCE_FLAG="" &&
157
- if [ "$mode" = "rerun" ]; then FORCE_FLAG="--force"; fi &&
158
- set +e &&
159
- bun "$(superskill script path sp pr-reviewing.ts)" request --focus "$focus" $FORCE_FLAG --json
160
- --status-file "$STATUS_FILE" > ".spur/run/$__runId-pr-request.json";
161
- rc=$?; set -e &&
162
- if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
163
- [ -f ".spur/run/$__runId-pr-request.json" ] &&
164
- bun -e 'const fs=require("node:fs");const r=JSON.parse(fs.readFileSync(process.argv[1],"utf8"));fs.writeFileSync(process.argv[2],(r.requestedAt ?? "")+"\n");fs.writeFileSync(process.argv[3],(r.head ?? "")+"\n")' ".spur/run/$__runId-pr-request.json" ".spur/run/$__runId-pr-since.txt" ".spur/run/$__runId-pr-head.txt";
165
- exit 0
158
+ mkdir -p .spur/run; case "$mode" in rerun) F=--force ;; *) F= ;; esac; bun "$(superskill script path sp pr-reviewing.ts)" request --focus "$focus" $F --json --status-file ".spur/run/$__runId-pr-request.status" > ".spur/run/$__runId-pr-request.json"; [ -f ".spur/run/$__runId-pr-request.status" ] || printf 'FAIL\n' > ".spur/run/$__runId-pr-request.status"; jq -e . ".spur/run/$__runId-pr-request.json" > /dev/null 2>&1 && jq -r '.requestedAt // ""' ".spur/run/$__runId-pr-request.json" > ".spur/run/$__runId-pr-since.txt" && jq -r '.head // ""' ".spur/run/$__runId-pr-request.json" > ".spur/run/$__runId-pr-head.txt"; exit 0
166
159
 
167
160
  - id: wait
168
161
  description: >
@@ -181,6 +174,8 @@ states:
181
174
  var: prHead
182
175
  - kind: shell
183
176
  options:
177
+ # (e) 0825: 9 lines — bounded wait loop keeps rc bookkeeping so a crashed driver
178
+ # fails closed instead of polling forever.
184
179
  command: >-
185
180
  mkdir -p .spur/run &&
186
181
  STATUS_FILE=".spur/run/$__runId-pr-wait.status" &&
@@ -206,19 +201,10 @@ states:
206
201
  var: prHead
207
202
  - kind: shell
208
203
  options:
204
+ # (e) 0825: 9 lines — collect + status must run against the same since/head pair
205
+ # before the composite status is decided (same 0771 record contract).
209
206
  command: >-
210
- mkdir -p .spur/run &&
211
- STATUS_FILE=".spur/run/$__runId-pr-collect.status" &&
212
- set +e &&
213
- bun "$(superskill script path sp pr-reviewing.ts)" collect --since "$prSince" --head "$prHead" --json
214
- --status-file "$STATUS_FILE" > ".spur/run/$__runId-pr-findings.json";
215
- collect_rc=$?;
216
- bun "$(superskill script path sp pr-reviewing.ts)" status --since "$prSince" --head "$prHead" --json > ".spur/run/$__runId-pr-status.json";
217
- status_rc=$?; set -e &&
218
- if [ "$collect_rc" -ne 0 ] || [ "$status_rc" -ne 0 ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
219
- if [ ! -f "$STATUS_FILE" ]; then printf 'FAIL\n' > "$STATUS_FILE"; fi &&
220
- { cat ".spur/run/$__runId-pr-findings.json" 2>/dev/null || true; } &&
221
- exit 0
207
+ mkdir -p .spur/run; bun "$(superskill script path sp pr-reviewing.ts)" collect --since "$prSince" --head "$prHead" --json --status-file ".spur/run/$__runId-pr-collect.status" > ".spur/run/$__runId-pr-findings.json"; c=$?; bun "$(superskill script path sp pr-reviewing.ts)" status --since "$prSince" --head "$prHead" --json > ".spur/run/$__runId-pr-status.json" && [ "$c" -eq 0 ] && [ -f ".spur/run/$__runId-pr-collect.status" ] || printf 'FAIL\n' > ".spur/run/$__runId-pr-collect.status"; cat ".spur/run/$__runId-pr-findings.json" 2>/dev/null; exit 0
222
208
 
223
209
  - id: done
224
210
  description: Terminal — review collected; findings artifact at .spur/run/${vars.__runId}-pr-findings.json
@@ -308,6 +294,8 @@ transitions:
308
294
  guard:
309
295
  kind: shell
310
296
  options:
297
+ # (e) 0825: 4-predicate guard — ALREADY_REQUESTED/REQUESTED pair state is the
298
+ # fallback route when the review driver stalls (mode/noWait honored).
311
299
  command: 'test "$(cat .spur/run/$__runId-pr-request.status 2>/dev/null)" = ALREADY_REQUESTED || { test "$(cat .spur/run/$__runId-pr-request.status 2>/dev/null)" = REQUESTED && { test "$mode" = "submit" || test "$noWait" = "true"; }; }'
312
300
  - from: request
313
301
  to: wait