@gobing-ai/spur 0.4.4 → 0.4.6

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 (82) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/config.example.yaml +3 -4
  3. package/config/config.global.yaml +3 -4
  4. package/config/rules/docs/sourced-api-claims.yaml +3 -2
  5. package/config/rules/quality/coverage-gate.yaml +6 -4
  6. package/config/rules/recommended-pre-check.yaml +11 -9
  7. package/config/transition-shims.json +0 -14
  8. package/config/workflows/task-pipeline.yaml +31 -71
  9. package/package.json +1 -1
  10. package/plugins/sp/agents/super-reviewer.md +11 -27
  11. package/plugins/sp/commands/dev-review.md +1 -1
  12. package/plugins/sp/lib/inline-run.generated.mjs +3 -3
  13. package/plugins/sp/lib/residual-scan.generated.d.mts +0 -13
  14. package/plugins/sp/lib/residual-scan.generated.mjs +3 -47
  15. package/plugins/sp/plugin.json +1 -1
  16. package/plugins/sp/scripts/commit-guard.mjs +49 -39
  17. package/plugins/sp/scripts/commit-guard.ts +60 -61
  18. package/plugins/sp/scripts/persist-out-check.mjs +28 -24
  19. package/plugins/sp/scripts/persist-out-check.ts +42 -33
  20. package/plugins/sp/scripts/residual-scan.mjs +5 -50
  21. package/plugins/sp/scripts/residual-scan.ts +4 -6
  22. package/plugins/sp/skills/code-verification/SKILL.md +1 -2
  23. package/plugins/sp/skills/code-verification/references/verdict-schema.md +16 -35
  24. package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +4 -2
  25. package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +3 -1
  26. package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +3 -2
  27. package/plugins/sp/skills/spur-dev/references/execution-workflow.md +7 -11
  28. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +7 -6
  29. package/spur.js +422 -431
  30. package/web/_astro/{BoardApp.hF0RAIrg.js → BoardApp.C5jnkkKP.js} +124 -124
  31. package/web/_astro/{BoardApp.Niubpe6z.js → BoardApp.CaNvQBD_.js} +1 -1
  32. package/web/_astro/{TaskDetail.DJpapt38.js → TaskDetail.DGKndhI8.js} +1 -1
  33. package/web/_astro/{arc.BgKcK0i8.js → arc.DHrwdg3G.js} +1 -1
  34. package/web/_astro/{architectureDiagram-3BPJPVTR.ChP-Ig0V.js → architectureDiagram-3BPJPVTR.pvKpK1s5.js} +1 -1
  35. package/web/_astro/{blockDiagram-GPEHLZMM.BVaCBoeN.js → blockDiagram-GPEHLZMM.BQmRcZsS.js} +1 -1
  36. package/web/_astro/{c4Diagram-AAUBKEIU.CHSDpEO5.js → c4Diagram-AAUBKEIU.CCLjHeH1.js} +1 -1
  37. package/web/_astro/channel.C7wG9RxA.js +1 -0
  38. package/web/_astro/{chunk-2J33WTMH.MYRcYVRa.js → chunk-2J33WTMH.DL6Yuoma.js} +1 -1
  39. package/web/_astro/{chunk-4BX2VUAB.S5j22Zqa.js → chunk-4BX2VUAB.CzlyEI7l.js} +1 -1
  40. package/web/_astro/{chunk-55IACEB6.gciRPvmZ.js → chunk-55IACEB6.B60EWxp1.js} +1 -1
  41. package/web/_astro/{chunk-727SXJPM.CdqrSQkX.js → chunk-727SXJPM.c7v_fRLo.js} +1 -1
  42. package/web/_astro/{chunk-AQP2D5EJ.CyokdHT3.js → chunk-AQP2D5EJ.8BxLWdDc.js} +1 -1
  43. package/web/_astro/{chunk-FMBD7UC4.Bg9KJhjW.js → chunk-FMBD7UC4.DmKuxGFT.js} +1 -1
  44. package/web/_astro/{chunk-ND2GUHAM.1gxxI-vD.js → chunk-ND2GUHAM.1Zwd4mqV.js} +1 -1
  45. package/web/_astro/{chunk-QZHKN3VN.DDEYtCKU.js → chunk-QZHKN3VN.BvYLu-A1.js} +1 -1
  46. package/web/_astro/{classDiagram-4FO5ZUOK.Ch3zi37T.js → classDiagram-4FO5ZUOK.CEqRt0WU.js} +1 -1
  47. package/web/_astro/{classDiagram-v2-Q7XG4LA2.Ch3zi37T.js → classDiagram-v2-Q7XG4LA2.CEqRt0WU.js} +1 -1
  48. package/web/_astro/{cose-bilkent-S5V4N54A.D2q5AINI.js → cose-bilkent-S5V4N54A.C7JiUdj2.js} +1 -1
  49. package/web/_astro/{cynefin-OW5HDTMX.BA9kC2YT.js → cynefin-OW5HDTMX.B6mZ-1be.js} +1 -1
  50. package/web/_astro/{dagre-BM42HDAG.CHO08nRp.js → dagre-BM42HDAG.BuryfDy6.js} +1 -1
  51. package/web/_astro/{diagram-2AECGRRQ.BfFQt0LW.js → diagram-2AECGRRQ.dao39YQM.js} +1 -1
  52. package/web/_astro/{diagram-5GNKFQAL.CHMwMTe4.js → diagram-5GNKFQAL.lnGZe4At.js} +1 -1
  53. package/web/_astro/{diagram-KO2AKTUF.BJ-7gK-w.js → diagram-KO2AKTUF.uWfhzEfT.js} +1 -1
  54. package/web/_astro/{diagram-LMA3HP47.C5xqcc0t.js → diagram-LMA3HP47.ppq8-198.js} +1 -1
  55. package/web/_astro/{diagram-OG6HWLK6.C2pQjfrC.js → diagram-OG6HWLK6.CKSCqDt5.js} +1 -1
  56. package/web/_astro/{erDiagram-TEJ5UH35._FoNyxgC.js → erDiagram-TEJ5UH35.sFSf2yBN.js} +1 -1
  57. package/web/_astro/{flowDiagram-I6XJVG4X.B_ENkT2I.js → flowDiagram-I6XJVG4X.BJQjKLbz.js} +1 -1
  58. package/web/_astro/{ganttDiagram-6RSMTGT7.B3q8h77C.js → ganttDiagram-6RSMTGT7.DAHKNj2N.js} +1 -1
  59. package/web/_astro/{gitGraphDiagram-PVQCEYII.QWZFDboZ.js → gitGraphDiagram-PVQCEYII.BlmzcW_O.js} +1 -1
  60. package/web/_astro/index.BCY1JJHd.css +1 -0
  61. package/web/_astro/{infoDiagram-5YYISTIA.Cs6eEc92.js → infoDiagram-5YYISTIA.DGhjaqsi.js} +1 -1
  62. package/web/_astro/{ishikawaDiagram-YF4QCWOH.BU9DJMHA.js → ishikawaDiagram-YF4QCWOH.gKIpgt6F.js} +1 -1
  63. package/web/_astro/{journeyDiagram-JHISSGLW.D35k6Jpe.js → journeyDiagram-JHISSGLW.DG3tmP0R.js} +1 -1
  64. package/web/_astro/{kanban-definition-UN3LZRKU.DBqcAT4m.js → kanban-definition-UN3LZRKU.CgHDSxkR.js} +1 -1
  65. package/web/_astro/{linear.D-LSNK8W.js → linear.BuGEpcuM.js} +1 -1
  66. package/web/_astro/{mermaid.core.CSruWVOa.js → mermaid.core.DBVqkWBp.js} +4 -4
  67. package/web/_astro/{mindmap-definition-RKZ34NQL.BiFaUsfj.js → mindmap-definition-RKZ34NQL.D-kOcji9.js} +1 -1
  68. package/web/_astro/{pieDiagram-4H26LBE5.D1KTKqb9.js → pieDiagram-4H26LBE5.BvGPwtZt.js} +1 -1
  69. package/web/_astro/{quadrantDiagram-W4KKPZXB.DBHflsMG.js → quadrantDiagram-W4KKPZXB.BKb_9FV6.js} +1 -1
  70. package/web/_astro/{requirementDiagram-4Y6WPE33.hwX9CNdk.js → requirementDiagram-4Y6WPE33.Cx0fvD8v.js} +1 -1
  71. package/web/_astro/{sankeyDiagram-5OEKKPKP.DkI8mJiE.js → sankeyDiagram-5OEKKPKP.fatULi0W.js} +1 -1
  72. package/web/_astro/{sequenceDiagram-3UESZ5HK.DMz7jBDx.js → sequenceDiagram-3UESZ5HK.ChHyKqco.js} +1 -1
  73. package/web/_astro/{stateDiagram-AJRCARHV.B6Ef2xJ1.js → stateDiagram-AJRCARHV.BdUpKWyj.js} +1 -1
  74. package/web/_astro/{stateDiagram-v2-BHNVJYJU.CgoaufB9.js → stateDiagram-v2-BHNVJYJU.fmJxqIm5.js} +1 -1
  75. package/web/_astro/{timeline-definition-PNZ67QCA.B3c8h1t-.js → timeline-definition-PNZ67QCA.BayDn5-V.js} +1 -1
  76. package/web/_astro/{vennDiagram-CIIHVFJN.BdHPAxAb.js → vennDiagram-CIIHVFJN.Bm2Aggwa.js} +1 -1
  77. package/web/_astro/{wardleyDiagram-YWT4CUSO.BrJXPPAj.js → wardleyDiagram-YWT4CUSO.DI75O-uG.js} +1 -1
  78. package/web/_astro/{xychartDiagram-2RQKCTM6.CMH5yFsV.js → xychartDiagram-2RQKCTM6.DL90E7Q7.js} +1 -1
  79. package/web/index.html +2 -2
  80. package/config/rules/docs/verdict-confidence.yaml +0 -68
  81. package/web/_astro/channel.DkpvN2tD.js +0 -1
  82. package/web/_astro/index.BFyW13JJ.css +0 -1
@@ -7,7 +7,7 @@
7
7
  "plugins": [
8
8
  {
9
9
  "name": "sp",
10
- "version": "0.4.4",
10
+ "version": "0.4.6",
11
11
  "source": "./plugins/sp"
12
12
  }
13
13
  ]
@@ -66,10 +66,9 @@ bootstrap:
66
66
  agent:
67
67
  # `default` is the role used for `--agent auto` when the caller declares
68
68
  # nothing (task 0542 R2 — the value domain moved from executor names to
69
- # roles). A role id selects its tier's cheapest eligible executor; a
70
- # configured executor name still resolves during the transition with a
71
- # one-time warning (shim agent-default-executor); any other value fails
72
- # naming both accepted sets.
69
+ # roles). A role id selects its tier's cheapest eligible executor; any
70
+ # other value fails. A configured executor name fails with a fix (use a
71
+ # role, and pin the executor with --agent <name>).
73
72
  default: coder
74
73
 
75
74
  # Role → tier map (SSOT: DEFAULT_AGENT_ROLES in packages/config, task 0572 /
@@ -35,10 +35,9 @@ version: "1.2"
35
35
  agent:
36
36
  # `default` is the role used for `--agent auto` when the caller declares
37
37
  # nothing (task 0542 R2 — the value domain moved from executor names to
38
- # roles). A role id selects its tier's cheapest eligible executor; a
39
- # configured executor name still resolves during the transition with a
40
- # one-time warning (shim agent-default-executor); any other value fails
41
- # naming both accepted sets.
38
+ # roles). A role id selects its tier's cheapest eligible executor; any
39
+ # other value fails. A configured executor name fails with a fix (use a
40
+ # role, and pin the executor with --agent <name>).
42
41
  default: coder
43
42
 
44
43
  # Role → tier map. Resolution: role → tier → cheapest USABLE executor whose
@@ -32,8 +32,9 @@ $schema: "@gobing-ai/spur/schemas/rule-file.schema.json"
32
32
  # backstop: the two `cited-*` rules cover the citation half, and
33
33
  # `cited-api-claims-confidence` covers the level half. All are severity `info`,
34
34
  # and the category is deliberately NOT in `recommended-pre-check` — it surfaces
35
- # findings for review without reddening gates. To promote it to a gate, add
36
- # `- docs` to that preset's `extends` once the residual list is triaged.
35
+ # findings for review without reddening gates. The 2026-10-12 audit below settled
36
+ # the promotion question: the residual findings stay a review-surface concern
37
+ # (SECUA checklist), not a gate one — do not add `- docs` to that preset.
37
38
  include:
38
39
  - "docs/**/*.md"
39
40
  - "plugins/sp/skills/**/references/**/*.md"
@@ -12,14 +12,16 @@ $schema: "@gobing-ai/spur/schemas/rule-file.schema.json"
12
12
  # `bun run test:full`. Running this rule directly via `spur rule run` outside the
13
13
  # repository wrapper bypasses that certification wrapper and is outside this
14
14
  # repository's certification contract. This rule and its evaluator are unchanged.
15
+ # Launcher children write isolated LCOV; canonical publication is exclusive and
16
+ # accepts only that run's complete records. Noncanonical launcher runs cannot
17
+ # overwrite the certified tracefile. Bare `bun test` still bypasses the launcher.
15
18
  #
16
19
  # Absorbed from ts-libs/.spur/rules/quality/coverage-gate.yaml, re-scoped to
17
20
  # Spur's monorepo layout:
18
21
  # - lcovPath kept at .coverage/lcov.info (Spur's `bun run test:coverage`
19
- # writes it via --coverage-dir=.coverage, and `bunfig.toml
20
- # [test] coverage = true` means a plain `bun run test` writes the same
21
- # artifact — so a TARGETED `bun test <file>` overwrites it with a partial
22
- # tracefile, and this rule then judges that partial data)
22
+ # publishes it after a completed run; bare TARGETED `bun test <file>` can
23
+ # still overwrite it with partial data, which the repository provenance
24
+ # wrapper refuses before this rule runs)
23
25
  # - include expanded to apps/** + packages/** (Spur tests cover both;
24
26
  # ts-libs only covers packages/**)
25
27
  # - threshold kept at 90 matching bunfig.toml coverageThreshold
@@ -4,16 +4,17 @@ $schema: "@gobing-ai/spur/schemas/preset.schema.json"
4
4
  #
5
5
  # Runs BEFORE tests (test-pre-check). Extends categories: typescript,
6
6
  # structure, boundary, surface, ui, strict (ui since bc267cc8, strict since
7
- # 79186391), and docs (sourced-api-claims, 2026-10-07). TSDoc exports run in
8
- # post-check alongside coverage-gate.
7
+ # 79186391), and docs (sourced-api-claims, 2026-10-07; pulled 2026-10-08 for
8
+ # finding noise — a 2026-10-14 restore was reverted; keep it out for now, see
9
+ # the marker line below). TSDoc exports run in post-check alongside
10
+ # coverage-gate.
9
11
  #
10
- # TEMPORARY (2026-10-08): `docs` removed from extends to unblock the gate —
11
- # restore it (add `- docs` back) once sourcing-claim finding noise is triaged.
12
- # The category now holds two files and both residuals must be triaged first:
13
- # `docs/sourced-api-claims.yaml` (advisory citation/level checks on claim lines) and
14
- # `docs/verdict-confidence.yaml` (a machine `Verdict:` report must state its
15
- # HIGH/MEDIUM/LOW level; 3 historical reports under docs/reports/ predate the
16
- # contract). Recapture the raw-json-baseline fixtures in the same change.
12
+ # `docs/sourced-api-claims.yaml` (citation/level checks) stays OUT of this gate:
13
+ # severity info would not redden it, but the findings belong to the SECUA review
14
+ # surface — run that file ad hoc instead. Recapture the raw-json-baseline
15
+ # fixtures when touching this preset. (F511: the category's other file,
16
+ # `verdict-confidence.yaml`, was deleted with the asserted confidence machinery
17
+ # it backstopped.)
17
18
  name: recommended-pre-check
18
19
  extends:
19
20
  - typescript
@@ -22,3 +23,4 @@ extends:
22
23
  - surface
23
24
  - ui
24
25
  - strict
26
+ # - docs ## DO NOT ENABLE THIS LINE
@@ -7,20 +7,6 @@
7
7
  "file": "packages/app/src/services/agent-service.ts",
8
8
  "keepsWorking": "a bare coding-agent binary name (codex, omp, claude with no matching agent.executors entry) remains a valid --agent value during the role transition, with a one-time warning emitted by warnBareBinaryOnce",
9
9
  "removalCondition": "no bare-binary --agent value remains in docs/, config/workflows/, or plugins/sp/ (scan for --agent <binary-name> usages against agent.executors names)"
10
- },
11
- {
12
- "id": "spec-without-executor-field",
13
- "wbs": "0537",
14
- "file": "apps/cli/src/commands/agent.ts",
15
- "keepsWorking": "a pre-existing agent spec carrying only type (no executor field) still drains: --agent <specId> falls back to the spec's coding-agent type instead of resolving a missing executor",
16
- "removalCondition": "every spec under .spur/agents/ records an executor field (scan .spur/agents/*.yaml for the key; re-materialize the demo team first)"
17
- },
18
- {
19
- "id": "agent-default-executor",
20
- "wbs": "0542",
21
- "file": "packages/app/src/services/agent-service.ts",
22
- "keepsWorking": "a configured executor name in agent.default still resolves during the transition, warned once by warnAgentDefaultExecutorOnce; the value domain moved to roles (recommended default: coder)",
23
- "removalCondition": "no agent.default value names an agent.executors entry (scan .spur/config.yaml and config/config.example.yaml against the agent.executors names)"
24
10
  }
25
11
  ]
26
12
  }
@@ -19,14 +19,6 @@
19
19
  # done guard closed, and re-records Testing before the failed edge); done settles
20
20
  # deferrals; failed renders the recovery report. No new state, edge, or model query.
21
21
  #
22
- # Confidence gate (session finding after 1088, task 1068 follow-up): the verify answer has
23
- # carried a `Confidence: HIGH|MEDIUM|LOW` line since 1068, and nothing read it — a PASS at
24
- # LOW confidence certified exactly like HIGH. The verify stamp now records a `confidence`
25
- # check row, and BOTH completion guards (verify → record, record → done) refuse a LOW (or
26
- # absent) level unless the run was launched with `--vars '{"ackLowConfidence":"true"}'`.
27
- # The acknowledgement is an operator decision, not a model one: it is the only way to
28
- # certify a verdict the verifier itself would not stand behind.
29
- #
30
22
  # Review-failure routing (session finding after 1088): `review` had no outgoing edge for a
31
23
  # FAIL verdict, so a failing review could only be remediated by driving the graph by hand
32
24
  # (re-entering `test` and hand-emitting rows). The review stage now derives
@@ -51,9 +43,8 @@ kind: state-machine
51
43
  name: task-pipeline
52
44
  # 0772 R2: explicit identity tag. Set only after the proof failure-path tests
53
45
  # passed; the engine treats unversioned external definitions as supported.
54
- # v4 (session finding after 1088): the completion gate reads the verifier's confidence level and
55
- # the graph routes a non-PASS review into bounded remediation — both are contract changes, so the
56
- # identity moves with them.
46
+ # v4 (session finding after 1088): the graph routes a non-PASS review into bounded remediation —
47
+ # a contract change, so the identity moves with it (the confidence half of v4 was retired at v7).
57
48
  # v5 (task 1077's inline run, 2026-10-06): the verify verdict action is explicitly `onError:
58
49
  # continue`. `task verdict` exits non-zero on any non-PASS verdict BY DESIGN (1003 R2) — that is
59
50
  # data for the verify guards, not a state failure. Under the engine's default 'fail' policy
@@ -63,14 +54,13 @@ name: task-pipeline
63
54
  # UNREACHABLE: a non-PASS verify could only end the run failed. `test-fix` also gained the
64
55
  # review-lane evidence projection (see its onEnter) so the repair hop is not fed an empty findings
65
56
  # list when the failing hop was `review-fail-triage` rather than the quality gate.
66
- # v6 (task 1134 run, 2026-10-09): the `confidence` check row now encodes the SAME policy as the two
67
- # completion guards instead of a stricter one of its own. It warned for every level below HIGH, so a
68
- # MEDIUM certification was admitted by both guards but recomputed as PARTIAL by the CLI done gate —
69
- # the artifact was self-inconsistent and `done` was refused with no named level to act on. The row
70
- # now warns only for an unacknowledged LOW (or absent) level, which is exactly what the guards
71
- # refuse; `packages/app/tests/workflow/task-pipeline-proof-chain.test.ts` pins the agreement for
72
- # HIGH/MEDIUM/LOW/absent × ack.
73
- version: "6"
57
+ # v7 (task 1207, F511): the asserted `Confidence: HIGH|MEDIUM|LOW` machinery is retired — the
58
+ # verifier's and reviewer's self-graded levels (re-imported from the cc anti-hallucination skill
59
+ # by task 1068) are no longer written, checked, or gated on; spur certifies on deterministic
60
+ # evidence (rows MET, proof digests, findings dispositioned). The `confidence` check row, the
61
+ # `ackLowConfidence` var, and the guards' LOW/absent clauses are gone; the derived
62
+ # feature-receipt confidence (ADR-131/1196) is a different family and stays.
63
+ version: "7"
74
64
  description: "Standard task pipeline: precheck → implement → quality-gate (test/fix/recheck) → review → approve → verify → record → done"
75
65
  # Task entity lifecycle (owned by task-lifecycle.yaml):
76
66
  # normal: backlog → todo → wip → testing → done
@@ -195,14 +185,6 @@ vars:
195
185
  # Escalation counter: .spur/run/<wbs>-escalation-count. Default 2 = two answered
196
186
  # questions; a third pause routes to failed with a report note.
197
187
  maxEscalations: "2"
198
- # Operator acknowledgement of a LOW-confidence certification (session finding after 1088).
199
- # The verify answer's `Confidence:` line is captured into the verdict artifact; a LOW (or
200
- # absent) level fails the completion guards unless this is "true", because a PASS the
201
- # verifier would not stand behind is an operator risk decision, not a mechanical one.
202
- # Set per run: `--vars '{"ackLowConfidence":"true"}'` (and export it on the inline path).
203
- # Deliberately NOT settable from the task file or the verifier's own answer: the point is
204
- # that a second party, not the producer, accepts the residual uncertainty.
205
- ackLowConfidence: ""
206
188
  # Runtime-written, 0933: the escalate hop's file.read.into-var fills this from
207
189
  # .spur/run/<wbs>-question.md; the hitl.input prompt below references it. Declared
208
190
  # here (empty) so the static var-reference validator sees the template source.
@@ -897,20 +879,6 @@ states:
897
879
  onError: continue
898
880
  options:
899
881
  command: "$spurBin task verdict $wbs --from-answer .spur/run/$wbs-verify-answer.txt"
900
- # Session finding after 1088: the verifier's confidence level becomes a `confidence` check
901
- # row and a gate-log line, so the level the completion guards enforce is visible in the
902
- # artifact and the log — not only in the answer file. v6 (task 1134 run): the row warns for
903
- # an unacknowledged LOW/absent level ONLY, matching the guards' ack rule; warning for
904
- # MEDIUM too made an admitted certification aggregate to PARTIAL (self-inconsistent artifact,
905
- # done refused). This is its own action because the proof-binding stamp below must stay the
906
- # state's LAST action AND under the ADR-115 800-char shell cap.
907
- - kind: shell
908
- options:
909
- command: >-
910
- V=".spur/run/$wbs-verdict.json"; [ -f "$V" ] || exit 0;
911
- jq --arg ack "$ackLowConfidence" '. + {checks: (((.checks // []) | map(select(.name != "confidence"))) + [{name: "confidence", status: (if ((.confidence // "LOW") != "LOW" or $ack == "true") then "pass" else "warn" end), evidence: ((.confidence // "LOW (absent from artifact)") + (if $ack == "true" then " (operator-acknowledged)" else "" end))}])}' "$V" > "$V.tmp" && mv "$V.tmp" "$V";
912
- printf 'confidence: %s (ack=%s)\n' "$(jq -r '.confidence // "LOW (absent)"' "$V")" "$ackLowConfidence" >> ".spur/run/$wbs-test-gate.log";
913
- exit 0
914
882
  # (e) one jq mutation binds the verdict to the proof digest (0703 R3; runId 0730 §B.2 /
915
883
  # 0757 R4; definitionDigest 0759 R5; honest review stamp 0785 R4; soft action + hard guard).
916
884
  - kind: shell
@@ -1312,16 +1280,15 @@ transitions:
1312
1280
  # re-enters quality → review → verify on a fresh digest. Before 1088 a FAIL review had no
1313
1281
  # outgoing edge at all; before 1122 a PASS-with-findings cost a full re-certification cycle per
1314
1282
  # attempt (knowledge-kit 0210/0213). The reviewer writes `Verdict: PASS|FAIL` in its answer;
1315
- # both plain and bold forms are accepted. Since 1204 a PASS must also be GRADED: the reviewer
1316
- # states `Confidence: HIGH|MEDIUM|LOW` (verify-chain semantics, 1068), HIGH/MEDIUM cross the
1317
- # PASS edges unadorned, and LOW or an absent line needs the operator's `ackLowConfidence` —
1318
- # otherwise the PASS falls to the catch-all like any other verdict the reviewer would not stand
1319
- # behind (same policy as the verify confidence gate). Review stays advisory: verify certifies.
1283
+ # both plain and bold forms are accepted. (F511: the v4-era PASS confidence grading — the
1284
+ # reviewer's self-stated HIGH/MEDIUM/LOW level and its `ackLowConfidence` escape hatch — was
1285
+ # retired; a PASS with no open P1-P3 finding is what the gate reads.) Review stays advisory:
1286
+ # verify certifies.
1320
1287
  # Under `profile=auto` the approve gate is skipped, so the PASS+auto edge is tried first and the
1321
1288
  # interactive PASS edge second.
1322
1289
  - from: review
1323
1290
  to: verify
1324
- description: profile=auto, the review certified a HIGH/MEDIUM-confidence PASS (LOW/absent needs ackLowConfidence) with no open P1-P3 finding — skip the human approval gate.
1291
+ description: profile=auto, the review certified a PASS with no open P1-P3 finding — skip the human approval gate.
1325
1292
  guard:
1326
1293
  kind: shell
1327
1294
  options:
@@ -1329,23 +1296,22 @@ transitions:
1329
1296
  test "$profile" = auto &&
1330
1297
  grep -qiE '^[[:space:]]*\**Verdict:\** *PASS' ".spur/run/$__runId-review-answer.txt" &&
1331
1298
  eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/residual-scan.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/residual-scan.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)" &&
1332
- [ -f "$S" ] && "$RUNNER" "$S" review-gate "$wbs" --spur-bin "$spurBin" --review-answer ".spur/run/$__runId-review-answer.txt" >&2
1299
+ [ -f "$S" ] && "$RUNNER" "$S" review-gate "$wbs" --spur-bin "$spurBin" >&2
1333
1300
  - from: review
1334
1301
  to: approve
1335
- description: Review certified a HIGH/MEDIUM-confidence PASS (LOW/absent needs ackLowConfidence) with no open P1-P3 finding — gate on human approval before verification.
1302
+ description: Review certified a PASS with no open P1-P3 finding — gate on human approval before verification.
1336
1303
  guard:
1337
1304
  kind: shell
1338
1305
  options:
1339
1306
  command: >-
1340
1307
  grep -qiE '^[[:space:]]*\**Verdict:\** *PASS' ".spur/run/$__runId-review-answer.txt" &&
1341
1308
  eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/residual-scan.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/residual-scan.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)" &&
1342
- [ -f "$S" ] && "$RUNNER" "$S" review-gate "$wbs" --spur-bin "$spurBin" --review-answer ".spur/run/$__runId-review-answer.txt" >&2
1309
+ [ -f "$S" ] && "$RUNNER" "$S" review-gate "$wbs" --spur-bin "$spurBin" >&2
1343
1310
  - from: review
1344
1311
  to: review-fail-triage
1345
1312
  description: >-
1346
- No certified PASS without an open P1-P3 finding (FAIL, PARTIAL, missing, unparseable, a
1347
- PASS whose review-gate check found an open P1-P3 row, or a PASS the reviewer graded below
1348
- HIGH/MEDIUM — or left ungraded — without the operator's ackLowConfidence; fail closed) —
1313
+ No certified PASS without an open P1-P3 finding (FAIL, PARTIAL, missing, unparseable, or
1314
+ a PASS whose review-gate check found an open P1-P3 row; fail closed) —
1349
1315
  classify the failure and route it into the bounded repair hop instead of dead-ending the run.
1350
1316
  guard:
1351
1317
  kind: always
@@ -1383,23 +1349,21 @@ transitions:
1383
1349
  # The verify step emits .spur/run/<wbs>-verdict.json with a required proof block (task 0703 R3/R5).
1384
1350
  # Only `verdict: PASS` PLUS a proof block whose digest — top level and every named stage — equals
1385
1351
  # the captured `proofDigest` clears the gate to `record`; any non-PASS, a missing file, malformed
1386
- # JSON, or missing/mismatched proof evidence does not. The verifier's confidence level is part of
1387
- # that certification (session finding after 1088): a PASS the verifier itself marked LOW — or left
1388
- # unstated — clears the gate only when the operator accepted it with
1389
- # `--vars '{"ackLowConfidence":"true"}'`. Declaration order: PASS+proof guard FIRST,
1390
- # then the bounded remediation route (R4), then the always catch-all so a PASS verdict with a
1391
- # missing/malformed proof block still terminates at `failed` instead of hanging the state.
1352
+ # JSON, or missing/mismatched proof evidence does not. (F511: the v4-era LOW/absent-confidence
1353
+ # clause and its `ackLowConfidence` escape hatch were retired.) Declaration order: PASS+proof
1354
+ # guard FIRST, then the bounded remediation route (R4), then the always catch-all so a PASS
1355
+ # verdict with a missing/malformed proof block still terminates at `failed` instead of hanging
1356
+ # the state.
1392
1357
  - from: verify
1393
1358
  to: record
1394
- description: Verification verdict is PASS, its proof block names the captured digest on every stage, and any LOW confidence was operator-acknowledged — record results and proceed to done.
1359
+ description: Verification verdict is PASS and its proof block names the captured digest on every stage — record results and proceed to done.
1395
1360
  guard:
1396
1361
  # (one jq -e predicate) PASS verdict; proof, quality-gate, review and verification digests
1397
- # equal to proofDigest; review completed; matching run id and definition digest (0703 R5, 0785 R4);
1398
- # confidence HIGH/MEDIUM, or LOW/absent with the operator's ack (session finding after 1088).
1362
+ # equal to proofDigest; review completed; matching run id and definition digest (0703 R5, 0785 R4).
1399
1363
  kind: shell
1400
1364
  options:
1401
1365
  command: >-
1402
- jq -e --arg d "$proofDigest" --arg r "$__runId" --arg dd "$__definitionDigest" --arg ack "$ackLowConfidence" '
1366
+ jq -e --arg d "$proofDigest" --arg r "$__runId" --arg dd "$__definitionDigest" '
1403
1367
  .verdict == "PASS"
1404
1368
  and (.proof.digest // "") == $d
1405
1369
  and (.proof.stages.qualityGate.digest // "") == $d
@@ -1408,7 +1372,6 @@ transitions:
1408
1372
  and (.proof.stages.verification.digest // "") == $d
1409
1373
  and (.proof.runId // "") == $r
1410
1374
  and (.proof.definitionDigest // "") == $dd
1411
- and ((.confidence // "LOW") != "LOW" or $ack == "true")
1412
1375
  ' ".spur/run/$wbs-verdict.json" >/dev/null 2>&1
1413
1376
  - from: verify
1414
1377
  to: test-fix
@@ -1436,12 +1399,10 @@ transitions:
1436
1399
  # ── done gate: record → done/failed gated on `spur task check` (ADR-026 amendment 2026-06-23)
1437
1400
  # PLUS the proof-block re-assertion (task 0703 R5): the verdict artifact must still be PASS and
1438
1401
  # still name the captured digest — a forged or mutated completion artifact fails closed here.
1439
- # PLUS the confidence re-assertion (session finding after 1088): the same ack rule as verify →
1440
- # record, re-read from the artifact so a mutation between the two boundaries cannot slip through.
1441
1402
  # Declaration order: pass guard first.
1442
1403
  - from: record
1443
1404
  to: done
1444
- description: Task check passed, the verdict proof block still names the captured digest, and any LOW confidence was acknowledged — certify done.
1405
+ description: Task check passed and the verdict proof block still names the captured digest — certify done.
1445
1406
  guard:
1446
1407
  kind: shell
1447
1408
  options:
@@ -1451,14 +1412,13 @@ transitions:
1451
1412
  # comments inside the folded scalar: `>-` joins same-indent lines into
1452
1413
  # one shell line.
1453
1414
  # Two logical commands, deliberately (ADR-115): the `task check` projection plus
1454
- # ONE jq predicate re-asserting the whole completion contract — PASS verdict, the
1455
- # captured proof digest, and the confidence rule (session finding after 1088).
1415
+ # ONE jq predicate re-asserting the whole completion contract — PASS verdict and the
1416
+ # captured proof digest.
1456
1417
  command: >-
1457
1418
  $spurBin task check $wbs --as done &&
1458
- jq -e --arg p "$proofDigest" --arg ack "$ackLowConfidence" '
1419
+ jq -e --arg p "$proofDigest" '
1459
1420
  .verdict == "PASS"
1460
1421
  and ((.proof.digest // "") == $p)
1461
- and ((.confidence // "LOW") != "LOW" or $ack == "true")
1462
1422
  ' ".spur/run/$wbs-verdict.json" >/dev/null 2>&1
1463
1423
  - from: record
1464
1424
  to: failed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobing-ai/spur",
3
- "version": "0.4.4",
3
+ "version": "0.4.6",
4
4
  "description": "Spur CLI — local-first harness for mainstream coding agents: constraint checking, workflow orchestration, agent health, and history analytics. Bun-native; exposes the `spur` command.",
5
5
  "keywords": [
6
6
  "spur",
@@ -200,7 +200,6 @@ shallower.
200
200
  **Scope:** <wbs diff | path glob>
201
201
  **Dimensions:** functional, security, efficiency, correctness, usability, architecture
202
202
  **Verdict:** PASS | PARTIAL | FAIL
203
- **Confidence:** HIGH | MEDIUM | LOW
204
203
  ##### Findings (ranked)
205
204
 
206
205
  | # | Priority | Dimension | Finding | Location | Disposition |
@@ -226,30 +225,14 @@ FAIL, PARTIAL, a missing line, a line split across two lines — routes the run
226
225
  `review-fail-triage` and its bounded repair hop. Keep it on one line, in that shape, in every
227
226
  review answer; never restate it as prose only.
228
227
 
229
- **The Confidence line is machine-read too (one confidence contract, 2026-10-12).** Every review
230
- report carries exactly one `Confidence: HIGH | MEDIUM | LOW` line, stated at the level the review can
231
- actually defend — the same enum and the same earning rule the verify answer uses
232
- ([verdict-schema.md](../skills/code-verification/references/verdict-schema.md) § Confidence level):
233
-
234
- - `HIGH` — every requirement row is `MET`, every finding carries a disposition, and the report cites
235
- its evidence. `HIGH` says the evidence needs no re-check.
236
- - `MEDIUM` — the verdict holds but evidence gaps remain; name them.
237
- - `LOW` — the verdict rests on unverified assumptions that could plausibly flip it; name them.
238
-
239
- A missing line, a level outside the enum, or a `HIGH` the rows do not earn turns an otherwise usable
240
- PASS into a refused one: consumer repositories gate the review answer artifact and every level it
241
- claims, exactly as they gate the verify answer. This is a contract change — review answers written
242
- before it were never asked for a level, so pre-adoption artifacts read as debt, not defects.
243
-
244
- **Machine-checked at the gate.** The pipeline's own review PASS edges enforce the line before verify:
245
- `residual-scan review-gate` reads the recorded `### Review` body, and a missing, duplicated or
246
- out-of-enum level becomes a **blocking** `review-contract` item — `review → verify` stops and the run
247
- enters `review-fail-triage` with the bounded repair hop, exactly as an open P1–P3 row does. The gate
248
- checks the recorded section's presence and vocabulary; the same scanner grades the answer passed
249
- by both PASS edges and refuses a `LOW` (or ungraded) PASS unless the operator sets
250
- `ackLowConfidence` exactly to `true` (task 1204 — the same policy the verify
251
- chain enforces), so whether a level is *earned* stays a judgement call (see the earning rule above):
252
- the report must still argue it.
228
+ **No confidence line (F511, task 1207).** Review reports do not state, and no gate reads, an
229
+ asserted `Confidence: HIGH | MEDIUM | LOW`. A model that can write a PASS can write `HIGH`, so the
230
+ gate grades what is checkable instead: the recorded section's presence and vocabulary, and the
231
+ findings disposition — an open P1–P3 row blocks the edge exactly as before. What a reviewer would
232
+ formerly have compressed into a level belongs in the report body: name the evidence gaps and the
233
+ assumptions explicitly, so a reader can re-check them. (The derived confidence family is
234
+ untouched: feature-verification receipts under ADR-131, the decision subsystem threshold, and
235
+ history-anatomy reading.)
253
236
 
254
237
  **Source citations for external claims (one claim contract, 2026-10-12).** A Finding cell or a
255
238
  Functional Traceability `Evidence` cell that asserts an external API/library claim carries a
@@ -260,8 +243,9 @@ answer's rule verbatim, owned by
260
243
  for external claims — claim markers and accepted forms are defined once there and are not restated
261
244
  here. The findings table's `Location` column does not stand in for it: `Location` anchors the
262
245
  finding's subject, not the claim's source. Cell-free receipts (test counts, reviewed-log notes)
263
- assert no external claim and need no citation. An uncited external claim is an assumption, so it
264
- caps the level the report can defend (above).
246
+ assert no external claim and need no citation. An uncited external claim is an assumption: name it
247
+ as an explicit gap in the report body (above), so a reader can re-check it.
248
+
265
249
 
266
250
  **Machine-checked at the gate (findings table).** `residual-scan review-gate` applies the same two
267
251
  predicates to every finding row: a Finding cell carrying one of the verify lint's claim markers with
@@ -43,7 +43,7 @@ Put the target first: a bare token after `--worktree` is read as the worktree na
43
43
  - **WBS mode (per task target):** `Skill(skill="sp:functional-review", args="<wbs> $FLAGS")` + `Skill(skill="sp:code-verification", args="review <wbs> $FLAGS")` + `Skill(skill="sp:code-improvement", args="<wbs> $FLAGS")` (functional traceability + SECUA framework + architectural depth — each skill receives its one resolved WBS exactly once plus `$FLAGS` = `$ARGUMENTS` minus the selector (`--tasks`/`--feature`/`--scope` or positional) and its value, never the raw selector, and returns a review fragment only — F92 0593 R1)
44
44
  - **Task fan-out (`--tasks` / `--feature`).** One WBS-mode review per task in the frozen set. Tasks in `backlog`/`todo`/`blocked` are reported NOT-STARTED and skipped (§ 3a outcome vocabulary); a per-task failure does not stop the remaining tasks. Each implemented task gets its own merged `## Review`; the run ends with a combined summary table (WBS, verdict, P1/P2 counts).
45
45
  - Coordinator = this session. No `sp:super-reviewer` subagent is dispatched: act as the review coordinator defined in [agents/super-reviewer.md](../agents/super-reviewer.md) — merge the fragments per its Output Format (native `P1`–`P4` priority cells, section-relative headings) and, for every task target (standalone or pipeline), write that task's combined `## Review` via `spur task update <wbs> --section Review --from-file`. Path mode emits advisory output only.
46
- - **Answer contract (pipeline dispatches).** The captured review answer (`.spur/run/<runId>-review-answer.txt`) must carry exactly one `Verdict: PASS|FAIL` line and exactly one `Confidence: HIGH|MEDIUM|LOW` line stating how strongly the review stands behind its verdict — HIGH = the reviewer re-executed the checks behind the verdict, MEDIUM = partial reliance on prior/external evidence, LOW = key evidence not re-executed. The pipeline's PASS edges admit HIGH/MEDIUM unadorned; LOW or an absent line crosses only with the operator's `ackLowConfidence` (same policy as the verify confidence gate, task 1068).
46
+ - **Answer contract (pipeline dispatches).** The captured review answer (`.spur/run/<runId>-review-answer.txt`) must carry exactly one `Verdict: PASS|FAIL` line; the PASS edges grep it before the review gate runs. No confidence line exists and none is graded (F511, task 1207): model-asserted confidence is not verification — the gate's job is the findings disposition, and an open P1–P3 finding blocks the edge on its own.
47
47
  - **Path mode (per path target):** `Skill(skill="sp:code-verification", args="review <path> $FLAGS")` + `Skill(skill="sp:code-improvement", args="<path> $FLAGS")` (advisory SECUA quality + architectural depth — one normalized path forwarded once plus `$FLAGS`; performs no task mutation). Under `--scope <path>[,<path>]`: paths must exist (exit 2 otherwise), are normalized, duplicates dropped and nested paths collapse to the ancestor (`--scope apps,apps/cli` → `apps`); each surviving path gets a sub-review (Step 3p path scope), eligible for native-subagent dispatch per [dispatch-surface.md](../skills/parallel-execution/references/dispatch-surface.md); the coordinator merges the sub-reviews, runs **one** cross-path architecture pass (`sp:code-improvement` over the inter-path imports), and emits **one** advisory report. No task mutation.
48
48
  - **Positional alias (deprecated).** A positional `<wbs|path>` is accepted for one release: a `^\d{4}$` token with a resolvable task behaves as `--tasks <wbs>`; an existing path as `--scope <path>`; otherwise exit 2. Print a deprecation warning naming the replacement selector; removal is a follow-up.
49
49
  - `--triage`: after the review returns, run the triage protocol in [dev-operations.md § 2. review](../skills/spur-dev/references/dev-operations.md#2-review) **inline in this session** — the review skills and `sp:super-reviewer` stay report-only. With multiple targets, bucket the findings across all targets once (identical `file:line` findings deduped before bucketing). `Edit`/`Write` in `allowed-tools` exist only for these direct fixes.