@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
@@ -396,7 +396,7 @@ states:
396
396
  # (probe-then-full), `deferred` under the opt-in batch policy.
397
397
  #
398
398
  # The three former routing states are decision CALLS here and in `review` (D65 1239 R1):
399
- # the lane decision (0943 R1/R2, catalog `task-triage`) picks the review depth, and the
399
+ # the lane decision (0943 R1/R2, catalog `task-semantic-risk`, 1262 R5) picks the review depth, and the
400
400
  # gate's own failure class (catalog `failure-class`) drives the red-gate transitions.
401
401
  # Both run unconditionally — the engine has no onEnter conditionals — and both degrade to
402
402
  # their catalog fallback with no model call while `workflows.decideDecisionMaker` is off.
@@ -407,7 +407,7 @@ states:
407
407
  title: Run quality gate
408
408
  description: >
409
409
  Typed quality gate: resolve the task path/priority, produce the diffstat lane
410
- evidence, consult `task-triage` for the review depth (deterministic safety floor
410
+ evidence, consult `task-semantic-risk` for the review depth (deterministic safety floor
411
411
  first), run `${vars.qualityGateCmd}` through `spur task gate <wbs> <mode>` under the
412
412
  host-wide lock (tree-hash receipt reuse on the same tree), then classify a red gate
413
413
  through `failure-class`. Writes the typed outcome to
@@ -446,27 +446,30 @@ states:
446
446
  options:
447
447
  command: >-
448
448
  mkdir -p .spur/run; if [ -n "$mode" ]; then printf '%s\n' "$mode" > ".spur/run/$wbs-mode.txt"; exit 0; fi; DF=".spur/run/$wbs-diffstat.json"; if ! jq -e 'type == "object"' "$DF" >/dev/null 2>&1; then printf 'safety\n' > ".spur/run/$wbs-mode.txt"; exit 0; fi; jq -r 'if .sensitive == true or ((.insertions // 0) + (.deletions // 0)) > 400 then "safety" else empty end' "$DF" 2>/dev/null > ".spur/run/$wbs-mode.txt"; exit 0
449
- # (d) lane decision — degrades to the standard default whenever
450
- # workflows.decideDecisionMaker is off, so with the flag off the pipeline makes no
451
- # model call (1114/1116: the bundled catalog owns question, choices and fallback).
449
+ # (d) lane decision (1262 R5) — one narrow question: does this change set alter
450
+ # behaviour beyond its diffstat? `false` projects the fast lane; `true` or the catalog
451
+ # fallback projects standard. Degrades to that fallback with no model call whenever
452
+ # workflows.decideDecisionMaker is off (the bundled catalog owns question, criteria and
453
+ # fallback), and `skipWhenEvidenceEmpty` keeps a missing diffstat from costing a call.
452
454
  - kind: decide
453
455
  options:
454
- id: task-triage
455
- decision: task-triage
456
+ id: task-semantic-risk
457
+ decision: task-semantic-risk
456
458
  params:
457
459
  wbs: ${vars.wbs}
458
460
  evidence:
459
461
  - .spur/run/${vars.wbs}-diffstat.json
460
462
  - ${vars.taskSpecPath}
461
- resultFile: .spur/run/${vars.wbs}-triage.decision
462
- # (d) project the decision and append the triage route reason (1007 R3: the
463
- # non-empty mode file is never overridden; the append keeps the failure signal of the
464
- # original pair). low → fast lane; anything else (standard/high, degraded default,
465
- # missing row) stays empty → the standard review path.
463
+ skipWhenEvidenceEmpty: true
464
+ resultFile: .spur/run/${vars.wbs}-semantic-risk.decision
465
+ # (d) project the decision and append the route reason (1007 R3: the non-empty mode
466
+ # file is never overridden; the append keeps the failure signal of the original pair).
467
+ # `no` (a noul row stores the label, not a boolean) → fast lane; anything else (`yes`,
468
+ # degraded default, missing row) stays empty → the standard review path.
466
469
  - kind: shell
467
470
  options:
468
471
  command: >-
469
- MF=".spur/run/$wbs-mode.txt"; [ -s "$MF" ] || jq -r 'if .value == "low" then "fast" else empty end' ".spur/run/$wbs-triage.decision" 2>/dev/null > "$MF"; m="$(cat "$MF")"; RUN_ID="$__runId"; [ -n "$RUN_ID" ] || RUN_ID="pipeline-$wbs"; mkdir -p .spur/memory; printf '%s %s %s\n' "$RUN_ID" "$wbs" "$(jq -rn --arg m "$m" --arg c "$mode" 'if $c != "" then ($c + ":caller-set") else {"fast":"fast:triage low lane","safety":"safety:triage deterministic-high","":"safety:triage standard lane"}[$m] // "safety:triage unrecognized mode" end')" >> .spur/memory/task-pipeline-routes.log
472
+ MF=".spur/run/$wbs-mode.txt"; [ -s "$MF" ] || jq -r 'if (.value == false or .value == "no") then "fast" else empty end' ".spur/run/$wbs-semantic-risk.decision" 2>/dev/null > "$MF"; m="$(cat "$MF")"; RUN_ID="$__runId"; [ -n "$RUN_ID" ] || RUN_ID="pipeline-$wbs"; mkdir -p .spur/memory; printf '%s %s %s\n' "$RUN_ID" "$wbs" "$(jq -rn --arg m "$m" --arg c "$mode" 'if $c != "" then ($c + ":caller-set") else {"fast":"fast:semantic-risk mechanical change","safety":"safety:deterministic-high","":"safety:standard lane"}[$m] // "safety:unrecognized mode" end')" >> .spur/memory/task-pipeline-routes.log
470
473
  # (d) review depth from the resolved lane (D65 1239 R2): the fast lane reviews the
471
474
  # requirement/AC traceability only — that table is the certification input, so the
472
475
  # cheap lane never drops the evidence, it drops the SECUA/architecture passes.
@@ -515,6 +518,14 @@ states:
515
518
  args: ["task", "gate", "${vars.wbs}", "${vars.gateMode}", "--no-logo"]
516
519
  resultFile: .spur/run/${vars.__runId}-gate.status
517
520
  softFail: true
521
+ # (d) record what the PREVIOUS gate visit's failure-class answer turned out to be
522
+ # (1263 R3a): a recheck visit means the last class was `fix` and the repair hop ran, so
523
+ # this visit's gate status says whether it was right. First write wins, the step never
524
+ # changes routing, and a missing invocationId (degraded row) or a first visit is a no-op.
525
+ - kind: shell
526
+ options:
527
+ command: >-
528
+ [ "$gateMode" = recheck ] || exit 0; ID="$(jq -r '.invocationId // empty' ".spur/run/$wbs-failure-class.decision" 2>/dev/null)"; [ -n "$ID" ] || exit 0; $spurBin decision outcome "$ID" --gate-status "$__runId" --source gate-recheck --no-logo >/dev/null 2>&1; exit 0
518
529
  # (d) failure class of the gate this visit produced (0943 R3): stop → failed
519
530
  # before the cap can mislabel it, fix → the bounded remediation hop. A missing or
520
531
  # corrupt row fails closed to failed-check. Runs unconditionally (no onEnter
@@ -528,6 +539,9 @@ states:
528
539
  wbs: ${vars.wbs}
529
540
  evidence:
530
541
  - .spur/run/${vars.wbs}-test-gate.findings
542
+ # 1262 R4: a green gate writes a 0-byte findings file — there is nothing to read,
543
+ # so the row degrades to the catalog `fix` fallback with no maker call and no events.
544
+ skipWhenEvidenceEmpty: true
531
545
  resultFile: .spur/run/${vars.wbs}-failure-class.decision
532
546
 
533
547
  # ── remediate hop (bounded repair; former `test-fix`) ─────────────────────
@@ -557,15 +571,17 @@ states:
557
571
  options:
558
572
  command: >-
559
573
  printf '%s\n' "$(( $(cat ".spur/run/$wbs-test-fix-attempt" 2>/dev/null || echo 0) + 1 ))" > ".spur/run/$wbs-test-fix-attempt"; [ -f ".spur/run/$wbs-residuals.json" ] && echo '--- residual artifact (F96 fix targets; deferrals go to residual-deferrals.json, P3/markers only) ---' >> ".spur/run/$wbs-test-gate.log" && cat ".spur/run/$wbs-residuals.json" >> ".spur/run/$wbs-test-gate.log"; exit 0
560
- # Review-lane input: the review failure class routes a non-PASS review into this same
561
- # bounded repair hop, but it stages no gate evidence — the fixer would receive a GREEN
562
- # gate log and an empty findings list. Project the reviewer's answer into the same log
563
- # the other lane uses, and only on the review lane (the decision file exists only
564
- # after a review FAIL). Own action, not an append to the one above (ADR-115 cap).
574
+ # Review-lane input: a non-PASS review status routes into this same bounded repair hop
575
+ # (1262 R6), but it stages no gate evidence — the fixer would receive a GREEN gate log
576
+ # and an empty findings list. Project the reviewer's answer into the same log the other
577
+ # lane uses, and only on the review lane: remediate after a GREEN gate this run means
578
+ # review sent it. The review status file is no lane marker — it outlives its review, so
579
+ # a red recheck after a review repair would re-feed that stale answer.
580
+ # Own action, not an append to the one above (ADR-115 cap).
565
581
  - kind: shell
566
582
  options:
567
583
  command: >-
568
- [ -f ".spur/run/$wbs-review-failure-class.decision" ] && [ -f ".spur/run/$__runId-review-answer.txt" ] && echo '--- review verdict (remediation input, review lane) ---' >> ".spur/run/$wbs-test-gate.log" && cat ".spur/run/$__runId-review-answer.txt" >> ".spur/run/$wbs-test-gate.log"; exit 0
584
+ [ "$(cat ".spur/run/$__runId-gate.status" 2>/dev/null)" = PASS ] && [ -f ".spur/run/$__runId-review-answer.txt" ] && echo '--- review verdict (remediation input, review lane) ---' >> ".spur/run/$wbs-test-gate.log" && cat ".spur/run/$__runId-review-answer.txt" >> ".spur/run/$wbs-test-gate.log"; exit 0
569
585
  # R3 (0482): project the extracted gate anchors into a var so the dispatch input
570
586
  # can NAME the failing file:line, not merely point at a log. A vars template cannot
571
587
  # run a shell, so the read is an action, not an inline `$(cat ...)` substitution.
@@ -630,21 +646,29 @@ states:
630
646
  # spec than the implement stage recorded in __agentRouting_implement.
631
647
  # 0943 R1/R2: `--focus` carries the resolved lane depth — `functional` for the
632
648
  # fast lane (traceability, which is the certification input), `all` otherwise.
633
- # D65 1240: this answer IS the certification input — `spur task verdict --from-answer`
649
+ # D65 1240 + 1254: this answer IS the certification input — `spur task verdict --from-answer`
634
650
  # derives the run's verdict from its requirement rows, so the answer contract is part
635
651
  # of the prompt. A report body ending with a `| WBS | Verdict | P1 | … |` summary and
636
652
  # no per-requirement rows derives UNKNOWN and can never certify, which looped every
637
653
  # run through review -> remediate.
654
+ # 1254: the review emits TWO artifacts with different consumers — the `## Review`
655
+ # section (finding dispositions, deriveReviewConfidence) and this captured answer
656
+ # (requirement/AC evidence, deriveVerifyConfidence). The prompt has to teach both
657
+ # lanes and the fact that a single `Confidence:` line may only carry the second one.
658
+ # 1254: the prompt stays inside the 1000-char composition cap — the full
659
+ # contract (tables, vocabularies, the two confidence lanes, AC identity vs
660
+ # feature credit) is owned by `plugins/sp/agents/super-reviewer.md` Output Format,
661
+ # which this pointer names.
638
662
  input: >-
639
- /sp:dev-review --tasks ${vars.wbs} --auto --focus ${vars.reviewFocus}
640
- Answer contract (machine-read): end with exactly one plain `Verdict: PASS|FAIL`
641
- line, preceded by a `| Req | Status | Evidence |` table with one row per
642
- requirement (R1, R2, ...) and a `| AC | Status | Evidence Type | Evidence |` table
643
- with one row per acceptance criterion, and one `Confidence: HIGH|MEDIUM|LOW` line
644
- whose level YOUR finding dispositions derive (ADR-141: no open P1-P3 and no
645
- carried residual is HIGH; a carried residual is MEDIUM; an open P1-P3 or a
646
- non-PASS verdict is LOW) — the gate recomputes it and rejects a disagreement.
647
- Every row cites a repo-relative `path:line`; no row may be omitted or merged.
663
+ /sp:dev-review --tasks ${vars.wbs} --auto --focus ${vars.reviewFocus} Answer contract (full: super-reviewer Output
664
+ Format). Two artifacts: the `## Review` section (dispositions, deriveReviewConfidence) and your captured answer
665
+ (certification input for `spur task verdict`). The answer has one `Confidence: HIGH|MEDIUM|LOW` line, EVIDENCE-derived
666
+ (deriveVerifyConfidence), never the section's disposition level. End with one `Verdict: PASS|PARTIAL|FAIL` line
667
+ preceded by `| Req | Status | Evidence |` (one row per requirement; MET | PARTIAL | UNMET) and `| AC | Status |
668
+ Evidence Type | Evidence |` (one row per AC; MET | PARTIAL | UNMET | N/A). Evidence types (`+` compound allowed): test
669
+ | command | static-ref | manual-review | llm-judge | n/a. Evidence cells cite `path:line` or a named check. AC rows
670
+ key on the task's identities or a declared `AC-N` alias; a linked scenario covers its task and a task-local criterion
671
+ needs no feature credit. Open P1-P3 blocks completion.
648
672
  # The captured review answer is the run's certification input (and the
649
673
  # `task verdict` input below): expectFile fails the step when no answer landed.
650
674
  answerFile: .spur/run/${vars.__runId}-review-answer.txt
@@ -681,21 +705,14 @@ states:
681
705
  options:
682
706
  command: >-
683
707
  mkdir -p .spur/run; S=FAIL; if [ "$(cat ".spur/run/$__runId-review-verdict.status" 2>/dev/null)" = PASS ] && [ "$(jq -r '.verdict // empty' ".spur/run/$wbs-verdict.json" 2>/dev/null)" = PASS ] && $spurBin task residual "$wbs" review-gate --no-logo >&2; then S=PASS; fi; printf '%s\n' "$S" > ".spur/run/$wbs-review.status"; exit 0
684
- # (d) review failure class (session finding after 1088): stop → failed before the cap
685
- # can mislabel it, fix → the SAME bounded repair hop the red gate uses, so the
686
- # iteration bound stays finite across both lanes. Degrades to the catalog `fix`
687
- # fallback with no model call while the decision switch is off; a missing/corrupt row
688
- # fails closed to failed-check.
689
- - kind: decide
708
+ # (d) record the review severity as the lane decision's outcome (1263 R3b): the
709
+ # question `task-semantic-risk` answered is "is this risky?", and the Review table's
710
+ # worst finding is the answer as observed. Resolved rows count (a fixed P2 was still
711
+ # risky). First write wins, so a later review visit changes nothing.
712
+ - kind: shell
690
713
  options:
691
- id: review-failure-class
692
- decision: review-failure-class
693
- params:
694
- wbs: ${vars.wbs}
695
- evidence:
696
- - .spur/run/${vars.__runId}-review-answer.txt
697
- - ${vars.taskSpecPath}
698
- resultFile: .spur/run/${vars.wbs}-review-failure-class.decision
714
+ command: >-
715
+ [ -f ".spur/run/$wbs-semantic-risk.decision" ] || exit 0; ID="$(jq -r '.invocationId // empty' ".spur/run/$wbs-semantic-risk.decision" 2>/dev/null)"; [ -n "$ID" ] || exit 0; $spurBin decision outcome "$ID" --review-severity "$wbs" --source "task-pipeline review" --no-logo >/dev/null 2>&1; exit 0
699
716
  # (d) Operator approval as a DECISION POINT, not a state (D65 1239 R1/R5, ADR-140
700
717
  # item 5): interactively the operator responder answers; under `profile=auto` the
701
718
  # declared binding answers (evidence status var, catalog fallback when the maker
@@ -1010,15 +1027,6 @@ transitions:
1010
1027
  kind: shell
1011
1028
  options:
1012
1029
  command: 'test "$(cat ".spur/run/$wbs-approval.status" 2>/dev/null)" = DENIED'
1013
- - from: review
1014
- to: failed
1015
- terminalReason: failed-check
1016
- description: Review failure class stop — the run terminates at failed, never bypassed.
1017
- guard:
1018
- kind: shell
1019
- options:
1020
- command: >-
1021
- jq -e '.value == "stop"' ".spur/run/$wbs-review-failure-class.decision" >/dev/null 2>&1
1022
1030
  - from: review
1023
1031
  to: failed
1024
1032
  terminalReason: retry-exhausted
@@ -1031,12 +1039,16 @@ transitions:
1031
1039
  test "$fix_attempts" -ge "$qualityGateMaxFixAttempts"
1032
1040
  - from: review
1033
1041
  to: remediate
1034
- description: Review failure class fix and under the cap — the shared bounded repair hop, then gate → review on the remediated tree.
1042
+ description: Review did not certify and the attempt cap still allows a repair — the shared bounded repair hop, then gate → review on the remediated tree.
1035
1043
  guard:
1036
1044
  kind: shell
1037
1045
  options:
1046
+ # 1262 R6: no decision row and no model call. The review status file is the whole
1047
+ # signal — it exists and is not PASS — and the cap guard above already bounds the
1048
+ # loop, so a non-PASS review always has exactly one forward route.
1038
1049
  command: >-
1039
- jq -e '.value == "fix"' ".spur/run/$wbs-review-failure-class.decision" >/dev/null 2>&1
1050
+ test -f ".spur/run/$wbs-review.status" &&
1051
+ test "$(cat ".spur/run/$wbs-review.status" 2>/dev/null)" != PASS
1040
1052
  # Defense: a review that did not certify and no clearer route — fail closed instead of
1041
1053
  # dead-ending the run (a FAIL, PARTIAL, missing or unparseable certification lands here).
1042
1054
  - from: review