@gobing-ai/spur 0.4.2 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/config/decisions/maker-liveness.yaml +39 -0
- package/config/plugin-scripts.json +0 -4
- package/config/rules/README.md +1 -0
- package/config/rules/docs/sourced-api-claims.yaml +56 -12
- package/config/rules/docs/verdict-confidence.yaml +68 -0
- package/config/rules/quality/coverage-gate.yaml +13 -0
- package/config/rules/recommended-pre-check.yaml +6 -2
- package/config/rules/strict/runtime-boundaries.yaml +10 -0
- package/config/rules/surface/check-cli-surface.yaml +1 -3
- package/config/script-placement-baseline.json +1 -19
- package/config/templates/AGENTS.md +7 -0
- package/config/workflows/feature-lifecycle.yaml +46 -1
- package/config/workflows/feature-verification.yaml +20 -1
- package/config/workflows/task-lifecycle.yaml +50 -0
- package/config/workflows/task-pipeline.yaml +15 -9
- package/package.json +10 -10
- package/plugins/sp/README.md +22 -16
- package/plugins/sp/agents/super-reviewer.md +46 -0
- package/plugins/sp/bunfig.toml +8 -5
- package/plugins/sp/commands/dev-changelog.md +1 -1
- package/plugins/sp/commands/dev-gitmsg.md +6 -2
- package/plugins/sp/commands/dev-handover.md +1 -0
- package/plugins/sp/commands/dev-job-dump.md +2 -1
- package/plugins/sp/commands/dev-refine.md +14 -2
- package/plugins/sp/commands/dev-refineall.md +7 -1
- package/plugins/sp/commands/dev-review.md +1 -0
- package/plugins/sp/hooks/careful-guard.ts +1 -1
- package/plugins/sp/hooks/context-post-tool.ts +7 -427
- package/plugins/sp/hooks/context-session-start.ts +5 -213
- package/plugins/sp/hooks/context-session-stop.ts +5 -191
- package/plugins/sp/hooks/pi/guard-extension.ts +6 -5
- package/plugins/sp/hooks/task-write-guard.ts +1 -1
- package/plugins/sp/{hooks → lib}/agent-hint.ts +1 -1
- package/plugins/sp/lib/context-post-tool.ts +432 -0
- package/plugins/sp/lib/context-session-start.ts +214 -0
- package/plugins/sp/lib/context-session-stop.ts +196 -0
- package/plugins/sp/lib/dogfood-pipeline.ts +265 -0
- package/plugins/sp/lib/dogfood-report.ts +278 -0
- package/plugins/sp/lib/history-anatomy.generated.mjs +18 -18
- package/plugins/sp/lib/idea-handoff.generated.mjs +91 -91
- package/plugins/sp/lib/inline-run-app.ts +40 -0
- package/plugins/sp/lib/inline-run.generated.d.mts +3 -3
- package/plugins/sp/lib/inline-run.generated.mjs +1425 -212
- package/plugins/sp/lib/plan-projection.generated.d.mts +150 -0
- package/plugins/sp/lib/plan-projection.generated.mjs +623 -9
- package/plugins/sp/lib/quality-gate.generated.d.mts +1 -0
- package/plugins/sp/lib/quality-gate.generated.mjs +13809 -13969
- package/plugins/sp/lib/residual-scan.generated.d.mts +20 -1
- package/plugins/sp/lib/residual-scan.generated.mjs +120 -25
- package/plugins/sp/lib/run-summary-core.ts +34 -370
- package/plugins/sp/lib/step-profile.generated.mjs +8 -8
- package/plugins/sp/lib/transcript.ts +37 -228
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/scripts/batch-plan.mjs +619 -11
- package/plugins/sp/scripts/batch-preflight.mjs +57 -13
- package/plugins/sp/scripts/batch-preflight.ts +35 -295
- package/plugins/sp/scripts/commit-guard.mjs +6 -6
- package/plugins/sp/scripts/daily-summary/daily-summary.mjs +127 -108
- package/plugins/sp/scripts/daily-summary/daily-summary.ts +111 -104
- package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.mjs +13 -12
- package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts +7 -265
- package/plugins/sp/scripts/dogfood-testing/validate-report.mjs +7 -4
- package/plugins/sp/scripts/dogfood-testing/validate-report.ts +6 -272
- package/plugins/sp/scripts/feature-verification-steps.mjs +20 -125
- package/plugins/sp/scripts/feature-verification-steps.ts +57 -181
- package/plugins/sp/scripts/history-anatomy-cache.mjs +19 -19
- package/plugins/sp/scripts/idea-handoff.mjs +2 -2
- package/plugins/sp/scripts/inline-run-dispatch.mjs +25 -24
- package/plugins/sp/scripts/inline-run-dispatch.ts +1 -21
- package/plugins/sp/scripts/inline-run-setup.mjs +164 -137
- package/plugins/sp/scripts/inline-run-setup.ts +1 -21
- package/plugins/sp/scripts/persist-out-check.mjs +5 -5
- package/plugins/sp/scripts/pr-reviewing.mjs +13 -13
- package/plugins/sp/scripts/quality-gate.mjs +13730 -13887
- package/plugins/sp/scripts/residual-scan.mjs +129 -31
- package/plugins/sp/scripts/residual-scan.ts +16 -13
- package/plugins/sp/scripts/run-summary.mjs +166 -112
- package/plugins/sp/scripts/run-summary.ts +7 -5
- package/plugins/sp/scripts/script-root.mjs +6 -6
- package/plugins/sp/scripts/session-timeline.mjs +62 -35
- package/plugins/sp/scripts/task-diffstat.mjs +19 -9
- package/plugins/sp/scripts/task-diffstat.ts +8 -39
- package/plugins/sp/scripts/workflow-step-profile.mjs +12 -12
- package/plugins/sp/scripts/wrapup-drift-probe.mjs +9 -9
- package/plugins/sp/scripts/wrapup-steps.mjs +25 -25
- package/plugins/sp/skills/code-implementation/SKILL.md +7 -1
- package/plugins/sp/skills/code-verification/references/secu-review.md +2 -1
- package/plugins/sp/skills/code-verification/references/verdict-schema.md +4 -0
- package/plugins/sp/skills/dogfood-testing/SKILL.md +2 -2
- package/plugins/sp/skills/next-feature/SKILL.md +1 -1
- package/plugins/sp/skills/next-router/SKILL.md +3 -1
- package/plugins/sp/skills/next-router/references/routing-table.md +9 -3
- package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +1 -1
- package/plugins/sp/skills/source-driven-development/SKILL.md +7 -4
- package/plugins/sp/skills/spur-cli/references/builder.md +3 -2
- package/plugins/sp/skills/spur-cli/references/decision.md +32 -7
- package/plugins/sp/skills/spur-cli/references/features.md +46 -5
- package/plugins/sp/skills/spur-cli/references/tasks.md +24 -4
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +8 -1
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +37 -11
- package/plugins/sp/skills/spur-dev/references/execution-batch-report.md +1 -1
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +19 -6
- package/plugins/sp/skills/spur-dev/references/execution-worktree-landing.md +22 -0
- package/plugins/sp/skills/spur-dev/references/execution-worktree-setup.md +14 -0
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +4 -2
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +49 -12
- package/schemas/section-matrix.schema.json +3 -2
- package/spur.js +66591 -73262
- package/web/_astro/{BoardApp.B3GQZvj8.js → BoardApp.Niubpe6z.js} +1 -1
- package/web/_astro/{BoardApp.BT7L2kSb.js → BoardApp.hF0RAIrg.js} +150 -150
- package/web/_astro/TaskDetail.DJpapt38.js +1 -0
- package/web/_astro/{arc.vaT7tPOB.js → arc.BgKcK0i8.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.DRMmTjkN.js → architectureDiagram-3BPJPVTR.ChP-Ig0V.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.cla0LO_q.js → blockDiagram-GPEHLZMM.BVaCBoeN.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.D4YAIBKn.js → c4Diagram-AAUBKEIU.CHSDpEO5.js} +1 -1
- package/web/_astro/channel.DkpvN2tD.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.BrSJbMRZ.js → chunk-2J33WTMH.MYRcYVRa.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.CuLMgKF5.js → chunk-4BX2VUAB.S5j22Zqa.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.zkvgu54F.js → chunk-55IACEB6.gciRPvmZ.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.DxWkACh8.js → chunk-727SXJPM.CdqrSQkX.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.42XrmIlH.js → chunk-AQP2D5EJ.CyokdHT3.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.Bao2wMK9.js → chunk-FMBD7UC4.Bg9KJhjW.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.BhydojD1.js → chunk-ND2GUHAM.1gxxI-vD.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.CmZ82g-H.js → chunk-QZHKN3VN.DDEYtCKU.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.Blr83Gt_.js → classDiagram-4FO5ZUOK.Ch3zi37T.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.Blr83Gt_.js → classDiagram-v2-Q7XG4LA2.Ch3zi37T.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.qmfv0SPn.js → cose-bilkent-S5V4N54A.D2q5AINI.js} +1 -1
- package/web/_astro/{cynefin-OW5HDTMX.BtELhXPR.js → cynefin-OW5HDTMX.BA9kC2YT.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.AWmaAvXo.js → dagre-BM42HDAG.CHO08nRp.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.DdH34KDi.js → diagram-2AECGRRQ.BfFQt0LW.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.BmNPix1k.js → diagram-5GNKFQAL.CHMwMTe4.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.BNQd_Ppo.js → diagram-KO2AKTUF.BJ-7gK-w.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.BAPgDi0e.js → diagram-LMA3HP47.C5xqcc0t.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.DZ4zyLdC.js → diagram-OG6HWLK6.C2pQjfrC.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.Q1TySMmw.js → erDiagram-TEJ5UH35._FoNyxgC.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.BXhFBicG.js → flowDiagram-I6XJVG4X.B_ENkT2I.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.vHSgcuo2.js → ganttDiagram-6RSMTGT7.B3q8h77C.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.Bi1f73C7.js → gitGraphDiagram-PVQCEYII.QWZFDboZ.js} +1 -1
- package/web/_astro/index.BFyW13JJ.css +1 -0
- package/web/_astro/{infoDiagram-5YYISTIA.DPvXZEWm.js → infoDiagram-5YYISTIA.Cs6eEc92.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.Cz829fsV.js → ishikawaDiagram-YF4QCWOH.BU9DJMHA.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.enRnB9Me.js → journeyDiagram-JHISSGLW.D35k6Jpe.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.DnTNk6d2.js → kanban-definition-UN3LZRKU.DBqcAT4m.js} +1 -1
- package/web/_astro/{linear.BzGnBwNL.js → linear.D-LSNK8W.js} +1 -1
- package/web/_astro/{mermaid.core.CSbTpIVz.js → mermaid.core.CSruWVOa.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.DGJDy8zT.js → mindmap-definition-RKZ34NQL.BiFaUsfj.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.HSPdi5_8.js → pieDiagram-4H26LBE5.D1KTKqb9.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.6Gv8mz2Y.js → quadrantDiagram-W4KKPZXB.DBHflsMG.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.CnBCtFwa.js → requirementDiagram-4Y6WPE33.hwX9CNdk.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.5M8VWAu8.js → sankeyDiagram-5OEKKPKP.DkI8mJiE.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.DN41XN-U.js → sequenceDiagram-3UESZ5HK.DMz7jBDx.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.ErOO3W8j.js → stateDiagram-AJRCARHV.B6Ef2xJ1.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.B_ZHICM-.js → stateDiagram-v2-BHNVJYJU.CgoaufB9.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.CWdosr07.js → timeline-definition-PNZ67QCA.B3c8h1t-.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.BHzYjNV5.js → vennDiagram-CIIHVFJN.BdHPAxAb.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.h8x4IwPX.js → wardleyDiagram-YWT4CUSO.BrJXPPAj.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.RTapW2X8.js → xychartDiagram-2RQKCTM6.CMH5yFsV.js} +1 -1
- package/web/index.html +2 -2
- package/web/spur_logo.svg +1 -1
- package/config/proportional-route-table.ts +0 -155
- package/plugins/sp/scripts/daily-summary/logger.ts +0 -28
- package/web/_astro/TaskDetail.Cxov1_N_.js +0 -1
- package/web/_astro/channel.D4nG9YLf.js +0 -1
- package/web/_astro/index.BhSwN8yY.css +0 -1
- /package/plugins/sp/{hooks → lib}/context-owner.ts +0 -0
- /package/plugins/sp/{hooks → lib}/destructive-policy.ts +0 -0
- /package/plugins/sp/{hooks → lib}/task-file-policy.ts +0 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
$schema: "@gobing-ai/spur/schemas/decision-catalog.schema.json"
|
|
2
|
+
# Liveness probe catalog (feature P11, docs/design/decision-observability-and-adoption.md §3.4).
|
|
3
|
+
#
|
|
4
|
+
# `maker-liveness` is served by exactly one caller: `spur decision status --probe`,
|
|
5
|
+
# which asks it once per distinct registered effective maker to prove the maker
|
|
6
|
+
# answers *now* rather than inferring health from configuration. No workflow may
|
|
7
|
+
# reference this id — a decision whose answer classifies nothing real has no place
|
|
8
|
+
# in a run, and `spur decision status --reliability` would otherwise count probe
|
|
9
|
+
# runs as adoption evidence.
|
|
10
|
+
#
|
|
11
|
+
# The probe writes no `decision_logs` row and emits no `decision.*` event, so these
|
|
12
|
+
# runs never enter the recorded evidence the same report displays next to them.
|
|
13
|
+
#
|
|
14
|
+
# Resolution: this file ships in the shared layer (the installed package's
|
|
15
|
+
# config/decisions/). A project can override it per basename through
|
|
16
|
+
# .spur/decisions/ or decisions.paths (first layer wins, ADR-113 style). Replacing it
|
|
17
|
+
# with a catalog that omits the id makes `--probe` fail loudly before any maker call.
|
|
18
|
+
version: 1
|
|
19
|
+
|
|
20
|
+
defaults:
|
|
21
|
+
# Deliberately not the 0.7 upstream / 0.8 catalog floor. minConfidence gates
|
|
22
|
+
# whether an *answer* is accepted; the probe asks whether the *maker* answered.
|
|
23
|
+
# Under a 0.8 floor a live maker reporting 0.6 would fall back and the probe would
|
|
24
|
+
# report "not working" for a backend that is working. A maker that never answered
|
|
25
|
+
# (no-backend, timeout, error) falls back regardless of this value.
|
|
26
|
+
minConfidence: 0
|
|
27
|
+
|
|
28
|
+
decisions:
|
|
29
|
+
maker-liveness:
|
|
30
|
+
type: choice
|
|
31
|
+
# Rendered as the question when the caller passes no `instructions`: the probe
|
|
32
|
+
# always does pass one, so this description is the fallback wording, not the
|
|
33
|
+
# probe prompt.
|
|
34
|
+
description: >
|
|
35
|
+
Liveness probe. Answer `ok` if this maker can serve a decision right now.
|
|
36
|
+
criteria:
|
|
37
|
+
ok: The maker answered the question it was asked.
|
|
38
|
+
unclear: The maker could not answer.
|
|
39
|
+
fallback: unclear
|
package/config/rules/README.md
CHANGED
|
@@ -17,6 +17,7 @@ install or to ts-libs.
|
|
|
17
17
|
| `surface` | `surface/` | CLI surface consistency (registerXxxCommand wiring, --json serialization) |
|
|
18
18
|
| `migration` | `migration/` | Transitional helpers for the regex → `rg` evaluator move (`rg-dialect`) |
|
|
19
19
|
| `ui` | `ui/` | Web UI seam boundaries (import seam, daisyUI class leak) |
|
|
20
|
+
| `docs` | `docs/` | Sourced API/library claims in markdown — citation anchor + HIGH/MEDIUM/LOW level. Advisory (`info`), and deliberately **not** in a preset: see the file header for its calibration audit and the one-line promotion step. |
|
|
20
21
|
|
|
21
22
|
## Presets
|
|
22
23
|
|
|
@@ -9,22 +9,43 @@ $schema: "@gobing-ai/spur/schemas/rule-file.schema.json"
|
|
|
9
9
|
# gate runs --fail-on warning, so this rule surfaces findings for review without
|
|
10
10
|
# reddening gates — changed-file enforcement happens in SECUA review).
|
|
11
11
|
#
|
|
12
|
+
# Calibration audit (2026-10-12, `spur rule run --file … --json`, unsuppressed):
|
|
13
|
+
# the category was pulled from `recommended-pre-check` on 2026-10-08 for "finding
|
|
14
|
+
# noise" — 593 findings. The audit split them 580 `cited-version-strings` /
|
|
15
|
+
# 13 `cited-api-claims`, and 579 of the 580 were false positives on two shapes
|
|
16
|
+
# that are not external claims at all: a document's own version
|
|
17
|
+
# (`docs/00_ADR.md:5` → `version: 1.69.0`), a section number in a heading
|
|
18
|
+
# (`docs/04_DESIGN.md:116` → `### 1.0.1 Shared option registry`) and a
|
|
19
|
+
# `§`-numbered cross-reference (`docs/00_ADR.md:1118` → `§1.2.1`). All three are
|
|
20
|
+
# excluded by the pattern below — the first two on the line's shape, the third on
|
|
21
|
+
# the token itself. The remaining source was a stale exclude list that stopped at
|
|
22
|
+
# `docs/tasks4/` while the active corpus folder is `docs/tasks5/`, which alone
|
|
23
|
+
# produced 226 findings; it is now one `docs/tasks*/**` glob. 593 → 330 after those
|
|
24
|
+
# two fixes, then 277 once the `§` shape was excluded too — the residual are
|
|
25
|
+
# version-pinned package claims that genuinely lack a same-line anchor, and they
|
|
26
|
+
# stay visible rather than suppressed.
|
|
27
|
+
#
|
|
12
28
|
# The semantic contract — every external API/library claim carries a source
|
|
13
29
|
# citation (URL or path:line) AND a confidence level (HIGH/MEDIUM/LOW) — is
|
|
14
30
|
# owned by the sp-source-driven-development skill and verified in SECUA review
|
|
15
|
-
# (code-verification secu-review checklist).
|
|
16
|
-
#
|
|
17
|
-
#
|
|
31
|
+
# (code-verification secu-review checklist). These rules are its deterministic
|
|
32
|
+
# backstop: the two `cited-*` rules cover the citation half, and
|
|
33
|
+
# `cited-api-claims-confidence` covers the level half. All are severity `info`,
|
|
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.
|
|
18
37
|
include:
|
|
19
38
|
- "docs/**/*.md"
|
|
20
39
|
- "plugins/sp/skills/**/references/**/*.md"
|
|
21
40
|
exclude:
|
|
22
41
|
# Legacy task archives are historical records — retro-citing ~900 closed
|
|
23
|
-
# lines is make-work; the tripwire targets active authoring surfaces.
|
|
24
|
-
|
|
25
|
-
-
|
|
26
|
-
|
|
27
|
-
|
|
42
|
+
# lines is make-work; the tripwire targets active authoring surfaces. One glob
|
|
43
|
+
# rather than the literal tasks/…tasks4/ list that let the active folder through.
|
|
44
|
+
# The trailing `/**` is load-bearing: `docs/tasks*/` ends as a pattern segment
|
|
45
|
+
# tested against `x.md`, so the anchored matcher binds nothing and the fragment
|
|
46
|
+
# fallback strips the `*` down to `docs/tasks/` — which is why that form
|
|
47
|
+
# silently excluded nothing (measured 2026-10-12).
|
|
48
|
+
- "docs/tasks*/**"
|
|
28
49
|
- "drizzle/**"
|
|
29
50
|
- "**/node_modules/**"
|
|
30
51
|
rules:
|
|
@@ -41,10 +62,15 @@ rules:
|
|
|
41
62
|
config:
|
|
42
63
|
mode: forbid
|
|
43
64
|
# Fire when the line has NO citation anchor (no URL, no path:line) AND
|
|
44
|
-
# contains a semver-ish token. Lookarounds exclude IPs (127.0.0.1)
|
|
45
|
-
# longer dotted numerics
|
|
46
|
-
#
|
|
47
|
-
|
|
65
|
+
# contains a semver-ish token. Lookarounds exclude IPs (127.0.0.1),
|
|
66
|
+
# longer dotted numerics, a heading's section number (`### 1.0.1 Title`),
|
|
67
|
+
# a document-version metadata line (`version: 1.69.0`) and a `§`-numbered
|
|
68
|
+
# section reference (`§7.3.1`) — none of which is an external claim;
|
|
69
|
+
# fenced-code lines are out of regex reach — that residual noise is why
|
|
70
|
+
# this is info, not warning. The `§` guard sits on the token itself, not on
|
|
71
|
+
# the line, so a line carrying both a section reference and a real version
|
|
72
|
+
# still fires on the version.
|
|
73
|
+
pattern: "^(?!.*(?:https?://|(?:[\\w.-]+/)+[\\w.-]+:\\d+))(?!\\s*#{1,6}\\s+\\d+\\.\\d+\\.\\d+)(?!\\s*[\\w-]+:\\s*\\d+\\.\\d+\\.\\d+\\s*$).*(?<![\\d.§])\\d+\\.\\d+\\.\\d+(?!\\.\\d)"
|
|
48
74
|
- id: cited-api-claims
|
|
49
75
|
description: >
|
|
50
76
|
A markdown line making a time- or version-anchored external API claim
|
|
@@ -58,3 +84,21 @@ rules:
|
|
|
58
84
|
config:
|
|
59
85
|
mode: forbid
|
|
60
86
|
pattern: "^(?!.*(?:https?://|(?:[\\w.-]+/)+[\\w.-]+:\\d+)).*\\b(?:deprecated (?:since|in|as of)|introduced in|added in|available since|stable since)\\b"
|
|
87
|
+
- id: cited-api-claims-confidence
|
|
88
|
+
description: >
|
|
89
|
+
A markdown line making a time- or version-anchored external API claim
|
|
90
|
+
("deprecated since 1.2", "introduced in v3", "available since 0.9") must
|
|
91
|
+
also state its confidence level — HIGH, MEDIUM or LOW — so a reader can
|
|
92
|
+
tell a checked fact from model memory; contract in
|
|
93
|
+
sp-source-driven-development. Pairs with `cited-api-claims`, which covers
|
|
94
|
+
the citation half: a line missing both halves reports once per rule,
|
|
95
|
+
deliberately, because each missing half is its own defect.
|
|
96
|
+
severity: info
|
|
97
|
+
evaluator:
|
|
98
|
+
type: regex
|
|
99
|
+
config:
|
|
100
|
+
mode: forbid
|
|
101
|
+
# Fires on a claim line carrying no uppercase level token. The verbs match
|
|
102
|
+
# `cited-api-claims` exactly, so the two rules never disagree about which
|
|
103
|
+
# lines are claims.
|
|
104
|
+
pattern: "^(?!.*\\b(?:HIGH|MEDIUM|LOW)\\b).*\\b(?:deprecated (?:since|in|as of)|introduced in|added in|available since|stable since)\\b"
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
$schema: "@gobing-ai/spur/schemas/rule-file.schema.json"
|
|
2
|
+
# Verdict-confidence rules (report corpus) — a committed verification record that states
|
|
3
|
+
# a machine `Verdict:` line must also state the verifier's confidence, so a reader can
|
|
4
|
+
# tell a PASS the verifier stands behind from one it would not.
|
|
5
|
+
#
|
|
6
|
+
# Contract owners: `Confidence: HIGH|MEDIUM|LOW` is specified for verify answers by
|
|
7
|
+
# plugins/sp/skills/code-verification/SKILL.md (one `Verdict: PASS|PARTIAL|FAIL` line, one
|
|
8
|
+
# `Confidence:` line, then the traceability tables) and for review reports by
|
|
9
|
+
# plugins/sp/agents/super-reviewer.md. Both are already enforced for pipeline answers —
|
|
10
|
+
# packages/app/src/services/verify-answer-lint.ts (`confidence-missing`,
|
|
11
|
+
# `confidence-value`, and the coherence pair `confidence-unwarranted` /
|
|
12
|
+
# `confidence-understated`) plus the verify stamp in config/workflows/task-pipeline.yaml —
|
|
13
|
+
# but no rule read the standalone report documents agents commit under `docs/`. This file
|
|
14
|
+
# is that backstop: the same three-level vocabulary, checked at the document level.
|
|
15
|
+
#
|
|
16
|
+
# Shape: one file-spanning forbidden match (`multiline: true` hands the evaluator the whole
|
|
17
|
+
# document and the negative lookahead spans the newline) instead of line counting. The
|
|
18
|
+
# lookahead demands a valid level, so a hedge (`Confidence: mostly`) reads as missing too.
|
|
19
|
+
# The verdict prefix requires the closed `PASS|PARTIAL|FAIL` value on its own line, which is
|
|
20
|
+
# what separates a record from prose: docs/reports/i31/0912-workflow-baseline.md:84 and
|
|
21
|
+
# i31/1107-runall-p1-pilot.md:9 both open a bolded *conclusion* sentence
|
|
22
|
+
# ("**Verdict: `partial — INSUFFICIENT_EVIDENCE retained`.**") and are not this contract.
|
|
23
|
+
#
|
|
24
|
+
# Severity `info`, and deliberately not in a preset — the same calibration choice the `docs`
|
|
25
|
+
# category makes for sourced claims: findings surface for review without reddening gates
|
|
26
|
+
# (`recommended-pre-check` runs `--fail-on warning`). To promote it, add `- docs` to that
|
|
27
|
+
# preset's `extends` once the residual is triaged.
|
|
28
|
+
#
|
|
29
|
+
# Calibration (2026-10-13, `spur rule run --file config/rules/docs/verdict-confidence.yaml
|
|
30
|
+
# --json`, unsuppressed): 3 findings over the 91 documents the include globs matched at that
|
|
31
|
+
# timestamp (29 under docs/reports/, 62 under docs/plans/), all three the hole this closes —
|
|
32
|
+
# docs/reports/2026-09-12-i21-verifyall.md:3,
|
|
33
|
+
# docs/reports/2026-10-01-E71-force-verification.md:3 and
|
|
34
|
+
# docs/reports/g61-verifyall-2026-09-12.md:3 each open `Verdict: PASS` and state no
|
|
35
|
+
# confidence level anywhere in the document. They stay visible rather than suppressed:
|
|
36
|
+
# retro-fitting a level into a historical record would invent the verifier's own claim.
|
|
37
|
+
# Both directions were controlled in the same run: a scratch report holding
|
|
38
|
+
# `Verdict: PASS` + `Confidence: HIGH` is not flagged, and the same file with
|
|
39
|
+
# `Confidence: mostly` is.
|
|
40
|
+
#
|
|
41
|
+
# Include is deliberately the report corpus. `docs/plans/*brainstorm*.md` states confidence
|
|
42
|
+
# as prose with its rationale (`**Confidence: HIGH.** All primitives … are verified present`,
|
|
43
|
+
# 61 such lines across 18 plans) — a different, human-facing contract that a
|
|
44
|
+
# level-only vocabulary check would drown in false positives, and those plans carry no
|
|
45
|
+
# machine verdict line to anchor on.
|
|
46
|
+
include:
|
|
47
|
+
- "docs/reports/**/*.md"
|
|
48
|
+
- "docs/plans/**/*.md"
|
|
49
|
+
exclude:
|
|
50
|
+
- "docs/tasks*/**"
|
|
51
|
+
rules:
|
|
52
|
+
- id: verdict-line-confidence-missing
|
|
53
|
+
description: >
|
|
54
|
+
A committed verification record that asserts a machine verdict line
|
|
55
|
+
(`Verdict: PASS|PARTIAL|FAIL`) must follow it with the verifier's confidence level —
|
|
56
|
+
`Confidence: HIGH|MEDIUM|LOW` — so a reader can tell a verdict the verifier stands
|
|
57
|
+
behind from one it would not. Contract in sp-code-verification (verify answers) and
|
|
58
|
+
sp-super-reviewer (review reports); a missing level is a lint failure for pipeline
|
|
59
|
+
answers (`confidence-missing`), and this rule is the backstop for the reports those
|
|
60
|
+
surfaces do not read.
|
|
61
|
+
severity: info
|
|
62
|
+
evaluator:
|
|
63
|
+
type: regex
|
|
64
|
+
config:
|
|
65
|
+
mode: forbid
|
|
66
|
+
multiline: true
|
|
67
|
+
flags: "i"
|
|
68
|
+
pattern: "^[ \\t]*\\**Verdict\\**:\\**[ \\t]*(?:PASS|PARTIAL|FAIL)\\**[ \\t]*\\n(?:[ \\t]*\\n)*(?![ \\t]*\\**Confidence\\**:\\**[ \\t]*\\**(?:HIGH|MEDIUM|LOW)\\**[ \\t]*\\.?[ \\t]*$)"
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
$schema: "@gobing-ai/spur/schemas/rule-file.schema.json"
|
|
2
2
|
# Coverage gate — per-file line coverage meets threshold from Bun's lcov output.
|
|
3
|
+
#
|
|
4
|
+
# PROVENANCE (task 1203): since task 1203 the repository post-check scripts
|
|
5
|
+
# (`test-post-check`, `test-post-check:full`) validate canonical coverage
|
|
6
|
+
# certification BEFORE this rule evaluates: only a completed successful canonical
|
|
7
|
+
# full-suite run (`bun run test`, `test:coverage`, `test:full`) certifies
|
|
8
|
+
# .coverage/lcov.info (marker: .coverage/coverage-certification.json, written by
|
|
9
|
+
# scripts/commands/run-tests.ts --publish-coverage). Missing/pending/superseded/
|
|
10
|
+
# stale-tree/byte-mismatched artifacts fail the post-check with a
|
|
11
|
+
# `coverage-artifact:` diagnostic before per-file findings; recovery is rerunning
|
|
12
|
+
# `bun run test:full`. Running this rule directly via `spur rule run` outside the
|
|
13
|
+
# repository wrapper bypasses that certification wrapper and is outside this
|
|
14
|
+
# repository's certification contract. This rule and its evaluator are unchanged.
|
|
15
|
+
#
|
|
3
16
|
# Absorbed from ts-libs/.spur/rules/quality/coverage-gate.yaml, re-scoped to
|
|
4
17
|
# Spur's monorepo layout:
|
|
5
18
|
# - lcovPath kept at .coverage/lcov.info (Spur's `bun run test:coverage`
|
|
@@ -8,8 +8,12 @@ $schema: "@gobing-ai/spur/schemas/preset.schema.json"
|
|
|
8
8
|
# post-check alongside coverage-gate.
|
|
9
9
|
#
|
|
10
10
|
# TEMPORARY (2026-10-08): `docs` removed from extends to unblock the gate —
|
|
11
|
-
# restore it (add `- docs` back) once
|
|
12
|
-
#
|
|
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.
|
|
13
17
|
name: recommended-pre-check
|
|
14
18
|
extends:
|
|
15
19
|
- typescript
|
|
@@ -38,6 +38,12 @@ rules:
|
|
|
38
38
|
|
|
39
39
|
# Low-level system primitives:
|
|
40
40
|
- "packages/app/src/services/quality-gate.ts" # gate runs `sh -c` with stdout+stderr merged onto ONE fd; ProcessExecutor captures streams separately and cannot reproduce the stream-order contract (task 1006 R1; mirrors the history-anatomy bundling exemptions)
|
|
41
|
+
# The feature-verification pass runs one long command with stdout+stderr merged onto the
|
|
42
|
+
# run's single log fd and a 4 h ceiling (the frozen contract from task 0915: `safe argv
|
|
43
|
+
# spawn, timeout and status handling`). ProcessExecutor captures the two streams separately
|
|
44
|
+
# and exposes no timeout, so it cannot reproduce either half (task 1176 R2; same class as
|
|
45
|
+
# the quality-gate exemption above).
|
|
46
|
+
- "packages/app/src/workflow/feature-verification-run.ts"
|
|
41
47
|
|
|
42
48
|
- id: no-direct-fs-io
|
|
43
49
|
description: "Prefer ts-runtime's FileSystem seam for fs IO."
|
|
@@ -64,6 +70,7 @@ rules:
|
|
|
64
70
|
- "packages/app/src/services/token-ledger-service.ts" # FD byte-window log tailing
|
|
65
71
|
- "packages/app/src/services/token-ledger-watcher.ts" # node:fs watch() live watcher
|
|
66
72
|
- "packages/app/src/services/project-registry.ts" # atomic projects.json persistence
|
|
73
|
+
- "packages/app/src/services/project-process.ts" # port/pid probes moved verbatim out of project-registry.ts to break the registry↔stop import cycle (same exemption)
|
|
67
74
|
- "packages/app/src/services/project-server-owner.ts" # atomic mkdir lifetime claim + unique-marker stale recovery; FileSystem has no exclusive mkdir primitive (1082)
|
|
68
75
|
- "packages/app/src/services/slash-commands-service.ts" # synchronous ~/.config/spur/slash_commands.json persistence (mirrors project-registry.ts)
|
|
69
76
|
- "packages/app/src/services/agent-usage-producer.ts" # atomic agent-usage snapshot write (tmp + rename, mirrors project-registry.ts; task 0892 R1)
|
|
@@ -74,7 +81,9 @@ rules:
|
|
|
74
81
|
- "apps/cli/src/commands/workflow.ts" # FD byte-window tail of the mid-run run log for `workflow trace --follow` streaming (task 0428 / feature D2); readSync at offset over the observability sink's FDs
|
|
75
82
|
- "apps/web/src/modules/discover.ts" # Vite/Astro module scanner fallback under bun test
|
|
76
83
|
- "packages/app/src/services/quality-gate.ts" # gate artifacts (log/findings/receipt) written directly; merged-fd gate log and fsync-free atomic writes must stay byte-stable; bundled standalone for the bare-node plugin twin (task 1006 R1; mirrors history-anatomy.ts)
|
|
84
|
+
- "packages/app/src/workflow/feature-verification-run.ts" # the pass opens the run's single merged log fd (`openSync(path,'a')`) and mkdirs the run dir beside the receipt writer, exactly as the plugin entry did before the move; the fd cannot be expressed through the FileSystem seam (task 1176 R2; same class as the quality-gate exemption above)
|
|
77
85
|
- "packages/app/src/services/run-storage.ts" # durable-evidence migration core (task 1025 R4): atomic tmp+rename byte copies with digest reread and atomic manifest publish must stay byte-stable (mirrors agent-usage-producer.ts / project-registry.ts exemptions)
|
|
86
|
+
- "packages/app/src/services/durable-plane-ignore.ts" # .git/info/exclude append moved verbatim out of run-storage.ts to break an import cycle (same exemption)
|
|
78
87
|
|
|
79
88
|
# Electron Node adapters cannot load Bun runtime implementations; keep the
|
|
80
89
|
# synchronous existence/directory probes injected for unit testing (desktop contract).
|
|
@@ -84,6 +93,7 @@ rules:
|
|
|
84
93
|
# Synchronous bootstrap & path resolution:
|
|
85
94
|
- "packages/config/src/bundled-config.ts" # sync bundledConfigRoot() directory walk
|
|
86
95
|
- "packages/config/src/loader.ts" # sync resolveConfigFile() / schema specifier lookup
|
|
96
|
+
- "packages/config/src/config-layers.ts" # sync resolveConfigLayers() existence probes moved verbatim out of loader.ts to break the loader↔executor-update cycle (same exemption)
|
|
87
97
|
- "packages/config/src/executor-update.ts" # atomic single-entry config update (task 0797): O_EXCL lock, fsync'd tmp+rename commit, lstat symlink refusal, mode preservation — ts-runtime FileSystem seam has no lstat/fsync/chmod/O_EXCL
|
|
88
98
|
- "packages/app/src/services/project-start.ts" # sync CLI binary path checks before daemon spawn
|
|
89
99
|
- "apps/cli/src/commands/serve.ts" # sync resolveServeCwd() directory validation before server startup (task 0805 R2); mirrors task.ts sync-template exemption
|
|
@@ -10,9 +10,7 @@ include:
|
|
|
10
10
|
- "apps/cli/src/commands/*.ts"
|
|
11
11
|
|
|
12
12
|
exclude:
|
|
13
|
-
# Not command
|
|
14
|
-
# excludes it too); shared-options.ts is the option registry.
|
|
15
|
-
- "apps/cli/src/commands/stubs.ts"
|
|
13
|
+
# Not a command file: shared-options.ts is the option registry.
|
|
16
14
|
- "apps/cli/src/commands/shared-options.ts"
|
|
17
15
|
|
|
18
16
|
rules:
|
|
@@ -16,32 +16,14 @@
|
|
|
16
16
|
"reason": "Keep (budget exemption; reviewed W4) (plan \u00a72)",
|
|
17
17
|
"exempt": true
|
|
18
18
|
},
|
|
19
|
-
"plugins/sp/scripts/feature-verification-steps.ts": {
|
|
20
|
-
"kinds": ["budget"],
|
|
21
|
-
"reason": "Keep (ADR-119 receipt writer; budget exemption) (plan \u00a72)",
|
|
22
|
-
"exempt": true
|
|
23
|
-
},
|
|
24
19
|
"plugins/sp/scripts/wrapup-drift-probe.ts": {
|
|
25
20
|
"kinds": ["budget", "corpus-parse"],
|
|
26
21
|
"reason": "Keep (glue over capture file; budget exemption) (plan \u00a72)",
|
|
27
22
|
"exempt": true
|
|
28
23
|
},
|
|
29
24
|
"plugins/sp/scripts/daily-summary/daily-summary.ts": {
|
|
30
|
-
"kinds": ["budget", "db-import"],
|
|
31
|
-
"reason": "Keep (daily-summary/, plan \u00a72); read-only history-health query via dynamic bun:sqlite import (task 1018)"
|
|
32
|
-
},
|
|
33
|
-
"plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts": {
|
|
34
25
|
"kinds": ["budget"],
|
|
35
|
-
"reason": "Keep (
|
|
36
|
-
},
|
|
37
|
-
"plugins/sp/scripts/dogfood-testing/validate-report.ts": {
|
|
38
|
-
"kinds": ["budget"],
|
|
39
|
-
"reason": "Keep (dogfood-testing/, plan \u00a72)"
|
|
40
|
-
},
|
|
41
|
-
"plugins/sp/hooks/context-post-tool.ts": {
|
|
42
|
-
"kinds": ["budget"],
|
|
43
|
-
"reason": "Keep: ADR-129 core (budget exemption) (plan \u00a72)",
|
|
44
|
-
"exempt": true
|
|
26
|
+
"reason": "Keep (daily-summary/, plan \u00a72); read-only history-health reads via the app service (task 1178)"
|
|
45
27
|
},
|
|
46
28
|
"plugins/sp/hooks/pi/guard-extension.ts": {
|
|
47
29
|
"kinds": ["budget"],
|
|
@@ -147,6 +147,13 @@ _(Fill from package manifests / README — or during `sp:doc-evolve` customize.)
|
|
|
147
147
|
**Done gate (minimum):** lint + tests clean; only intentional `git status` changes; no
|
|
148
148
|
`--no-verify` / silent suppressions. Harness task done ⇒ real verify **PASS** when the pipeline ran.
|
|
149
149
|
|
|
150
|
+
**Gate scope:** the gate verifies code changes. Scribe commands — `/sp:dev-gitmsg`,
|
|
151
|
+
`/sp:dev-changelog`, `/sp:dev-handover`, `/sp:dev-job-dump` — produce text or a commit and run no
|
|
152
|
+
gate (lint, typecheck, tests) unless asked: `gitmsg --check <cmd>`, or `/sp:dev-gtd --no-push` for
|
|
153
|
+
gate → fix → commit. Commands that own a gate (`dev-run`, `dev-runall`, `dev-fixall`, `dev-gtd`,
|
|
154
|
+
`dev-fixgha`, `dev-unit`, `--check` loops) run exactly what their contract names — no extra
|
|
155
|
+
completion-gate pass on top.
|
|
156
|
+
|
|
150
157
|
---
|
|
151
158
|
|
|
152
159
|
## Spur CLI surface
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"$schema": "@gobing-ai/spur/schemas/state-machine-workflow.schema.json"
|
|
10
10
|
kind: state-machine
|
|
11
11
|
name: feature-lifecycle
|
|
12
|
-
version: "
|
|
12
|
+
version: "3"
|
|
13
13
|
description: >
|
|
14
14
|
Feature lifecycle FSM (design §2.3, §5.1, DD-13). States are the canonical
|
|
15
15
|
FeatureStatus vocabulary; transitions encode the §2.3 graph including the
|
|
@@ -64,6 +64,11 @@ states:
|
|
|
64
64
|
description: Completed and verified.
|
|
65
65
|
- id: cancelled
|
|
66
66
|
description: Terminal — abandoned.
|
|
67
|
+
- id: deprecated
|
|
68
|
+
description: >
|
|
69
|
+
Retained and frozen (ADR-136). Non-terminal: the record stays readable and
|
|
70
|
+
countable, nothing may attach new work to it, and leaving it is explicit —
|
|
71
|
+
un-deprecate to active, or cancelled once the feature is removed.
|
|
67
72
|
|
|
68
73
|
transitions:
|
|
69
74
|
# Forward path: backlog → active → verifying → done
|
|
@@ -142,3 +147,43 @@ transitions:
|
|
|
142
147
|
description: Cancel feature
|
|
143
148
|
guard:
|
|
144
149
|
kind: always
|
|
150
|
+
|
|
151
|
+
# Deprecate: any non-terminal-or-done state → deprecated (frozen, retained — ADR-136)
|
|
152
|
+
- from: backlog
|
|
153
|
+
to: deprecated
|
|
154
|
+
description: Deprecate feature (frozen, retained)
|
|
155
|
+
guard:
|
|
156
|
+
kind: always
|
|
157
|
+
- from: active
|
|
158
|
+
to: deprecated
|
|
159
|
+
description: Deprecate feature (frozen, retained)
|
|
160
|
+
guard:
|
|
161
|
+
kind: always
|
|
162
|
+
- from: verifying
|
|
163
|
+
to: deprecated
|
|
164
|
+
description: Deprecate feature (frozen, retained)
|
|
165
|
+
guard:
|
|
166
|
+
kind: always
|
|
167
|
+
- from: blocked
|
|
168
|
+
to: deprecated
|
|
169
|
+
description: Deprecate feature (frozen, retained)
|
|
170
|
+
guard:
|
|
171
|
+
kind: always
|
|
172
|
+
- from: done
|
|
173
|
+
to: deprecated
|
|
174
|
+
description: Deprecate feature (frozen, retained)
|
|
175
|
+
guard:
|
|
176
|
+
kind: always
|
|
177
|
+
|
|
178
|
+
# Exits out of deprecated: un-deprecate or remove only. Any other edge is
|
|
179
|
+
# undeclared and refused by the graph (ADR-135).
|
|
180
|
+
- from: deprecated
|
|
181
|
+
to: active
|
|
182
|
+
description: Un-deprecate (mandatory History entry)
|
|
183
|
+
guard:
|
|
184
|
+
kind: always
|
|
185
|
+
- from: deprecated
|
|
186
|
+
to: cancelled
|
|
187
|
+
description: Remove deprecated feature
|
|
188
|
+
guard:
|
|
189
|
+
kind: always
|
|
@@ -10,6 +10,17 @@
|
|
|
10
10
|
#
|
|
11
11
|
# Run: spur workflow run feature-verification.yaml --vars '{"featureId":"D63"}'
|
|
12
12
|
#
|
|
13
|
+
# No project-side override is required (task 1185, A33). Since the pass moved into the
|
|
14
|
+
# application (1176 / efd78f058) the bundled definition owns it end to end, so a
|
|
15
|
+
# project-layer copy of this file (plus a rooted port under `.spur/scripts/`) is a
|
|
16
|
+
# leftover — the port was written against an entry export contract that has since
|
|
17
|
+
# changed. Remove the override so this definition applies, or migrate the port to the
|
|
18
|
+
# current app-owned operation `runFeatureVerification` (the generated inline bundle's
|
|
19
|
+
# export). If a stale consumer is still reached, feature-lifecycle's `verifying` entry
|
|
20
|
+
# names it: the override path, the consumer script, the export it requires that the
|
|
21
|
+
# shipped entry no longer provides, and the entry path. Reinstalling or upgrading the
|
|
22
|
+
# plugin cannot supply a retired export — only the two remedies above can.
|
|
23
|
+
#
|
|
13
24
|
# Shape: verify -> done | failed. The onEnter step runs the standard script
|
|
14
25
|
# `feature-verification-steps.ts` (no public CLI verb, D63 task 0915): it
|
|
15
26
|
# resolves this very definition for the verifier identity (name, source path,
|
|
@@ -40,6 +51,14 @@ vars:
|
|
|
40
51
|
featureId: "X"
|
|
41
52
|
spurBin: "spur"
|
|
42
53
|
verificationCmd: "bun run spur-check-feature"
|
|
54
|
+
# Operator-declared confidence level; empty derives it from the pass (HIGH when the selected
|
|
55
|
+
# definition's own command exited 0 with an unchanged proof-input digest, MEDIUM under a caller
|
|
56
|
+
# `--cmd` override, LOW otherwise). The completion boundary refuses a PASS carrying no level or
|
|
57
|
+
# LOW unless the receipt records the acknowledgement below.
|
|
58
|
+
confidence: ""
|
|
59
|
+
# Operator acknowledgement of a LOW level. It rides the receipt, so the transition reads it from
|
|
60
|
+
# the evidence rather than from whatever flags a later command happens to pass.
|
|
61
|
+
ackLowConfidence: "false"
|
|
43
62
|
__runId: ""
|
|
44
63
|
|
|
45
64
|
states:
|
|
@@ -59,7 +78,7 @@ states:
|
|
|
59
78
|
- kind: shell
|
|
60
79
|
options:
|
|
61
80
|
command: >-
|
|
62
|
-
mkdir -p .spur/run; eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/feature-verification-steps.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/feature-verification-steps.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)"; [ -f "$S" ] && "$RUNNER" "$S" verify --feature-id "$featureId" --run-id "$__runId" --spur-bin "$spurBin" || printf 'FAIL feature-verification failed closed — script not found — run superskill install sp --marketplace gobing-ai/spur\n' > ".spur/run/$__runId-feature-verification.status"; exit 0
|
|
81
|
+
mkdir -p .spur/run; eval "$(jq -r 'if .mode=="source-repo" then "S="+@sh"\(.dir)/feature-verification-steps.ts"+" RUNNER=bun" elif .mode=="installed" then "S="+@sh"\(.dir)/feature-verification-steps.mjs"+" RUNNER=node" else empty end' ".spur/run/$__runId-script-root.json" 2>/dev/null)"; ACK=""; [ "$ackLowConfidence" = "true" ] && ACK="--ack-low-confidence"; [ -f "$S" ] && "$RUNNER" "$S" verify --feature-id "$featureId" --run-id "$__runId" --spur-bin "$spurBin" --confidence "$confidence" $ACK || printf 'FAIL feature-verification failed closed — script not found — run superskill install sp --marketplace gobing-ai/spur\n' > ".spur/run/$__runId-feature-verification.status"; exit 0
|
|
63
82
|
|
|
64
83
|
- id: done
|
|
65
84
|
description: Terminal — repo-wide checks passed and the receipt is bound.
|
|
@@ -64,6 +64,11 @@ states:
|
|
|
64
64
|
Completed. Re-enterable (reopen with warning + mandatory History entry).
|
|
65
65
|
- id: cancelled
|
|
66
66
|
description: Terminal — abandoned.
|
|
67
|
+
- id: deprecated
|
|
68
|
+
description: >
|
|
69
|
+
Retained and frozen (ADR-137). Non-terminal: the record stays readable and
|
|
70
|
+
countable, nothing new may attach to it, and leaving it is explicit —
|
|
71
|
+
un-deprecate to todo, or cancelled once the task is removed.
|
|
67
72
|
|
|
68
73
|
transitions:
|
|
69
74
|
# Forward path: backlog → todo → wip → testing → done
|
|
@@ -157,3 +162,48 @@ transitions:
|
|
|
157
162
|
description: Cancel task
|
|
158
163
|
guard:
|
|
159
164
|
kind: always
|
|
165
|
+
|
|
166
|
+
# Deprecate: any non-terminal-or-done state → deprecated (frozen, retained — ADR-137)
|
|
167
|
+
- from: backlog
|
|
168
|
+
to: deprecated
|
|
169
|
+
description: Deprecate task (frozen, retained)
|
|
170
|
+
guard:
|
|
171
|
+
kind: always
|
|
172
|
+
- from: todo
|
|
173
|
+
to: deprecated
|
|
174
|
+
description: Deprecate task (frozen, retained)
|
|
175
|
+
guard:
|
|
176
|
+
kind: always
|
|
177
|
+
- from: wip
|
|
178
|
+
to: deprecated
|
|
179
|
+
description: Deprecate task (frozen, retained)
|
|
180
|
+
guard:
|
|
181
|
+
kind: always
|
|
182
|
+
- from: testing
|
|
183
|
+
to: deprecated
|
|
184
|
+
description: Deprecate task (frozen, retained)
|
|
185
|
+
guard:
|
|
186
|
+
kind: always
|
|
187
|
+
- from: blocked
|
|
188
|
+
to: deprecated
|
|
189
|
+
description: Deprecate task (frozen, retained)
|
|
190
|
+
guard:
|
|
191
|
+
kind: always
|
|
192
|
+
- from: done
|
|
193
|
+
to: deprecated
|
|
194
|
+
description: Deprecate task (frozen, retained)
|
|
195
|
+
guard:
|
|
196
|
+
kind: always
|
|
197
|
+
|
|
198
|
+
# Exits out of deprecated: un-deprecate or remove only. Any other edge is
|
|
199
|
+
# undeclared and refused by the graph (ADR-135).
|
|
200
|
+
- from: deprecated
|
|
201
|
+
to: todo
|
|
202
|
+
description: Un-deprecate (mandatory History entry)
|
|
203
|
+
guard:
|
|
204
|
+
kind: always
|
|
205
|
+
- from: deprecated
|
|
206
|
+
to: cancelled
|
|
207
|
+
description: Remove deprecated task
|
|
208
|
+
guard:
|
|
209
|
+
kind: always
|
|
@@ -1312,11 +1312,16 @@ transitions:
|
|
|
1312
1312
|
# re-enters quality → review → verify on a fresh digest. Before 1088 a FAIL review had no
|
|
1313
1313
|
# outgoing edge at all; before 1122 a PASS-with-findings cost a full re-certification cycle per
|
|
1314
1314
|
# attempt (knowledge-kit 0210/0213). The reviewer writes `Verdict: PASS|FAIL` in its answer;
|
|
1315
|
-
# both plain and bold forms are accepted.
|
|
1316
|
-
#
|
|
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.
|
|
1320
|
+
# Under `profile=auto` the approve gate is skipped, so the PASS+auto edge is tried first and the
|
|
1321
|
+
# interactive PASS edge second.
|
|
1317
1322
|
- from: review
|
|
1318
1323
|
to: verify
|
|
1319
|
-
description: profile=auto, the review certified PASS
|
|
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.
|
|
1320
1325
|
guard:
|
|
1321
1326
|
kind: shell
|
|
1322
1327
|
options:
|
|
@@ -1324,23 +1329,24 @@ transitions:
|
|
|
1324
1329
|
test "$profile" = auto &&
|
|
1325
1330
|
grep -qiE '^[[:space:]]*\**Verdict:\** *PASS' ".spur/run/$__runId-review-answer.txt" &&
|
|
1326
1331
|
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)" &&
|
|
1327
|
-
[ -f "$S" ] && "$RUNNER" "$S" review-gate "$wbs" --spur-bin "$spurBin" >&2
|
|
1332
|
+
[ -f "$S" ] && "$RUNNER" "$S" review-gate "$wbs" --spur-bin "$spurBin" --review-answer ".spur/run/$__runId-review-answer.txt" >&2
|
|
1328
1333
|
- from: review
|
|
1329
1334
|
to: approve
|
|
1330
|
-
description: Review certified PASS with no open P1-P3
|
|
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.
|
|
1331
1336
|
guard:
|
|
1332
1337
|
kind: shell
|
|
1333
1338
|
options:
|
|
1334
1339
|
command: >-
|
|
1335
1340
|
grep -qiE '^[[:space:]]*\**Verdict:\** *PASS' ".spur/run/$__runId-review-answer.txt" &&
|
|
1336
1341
|
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)" &&
|
|
1337
|
-
[ -f "$S" ] && "$RUNNER" "$S" review-gate "$wbs" --spur-bin "$spurBin" >&2
|
|
1342
|
+
[ -f "$S" ] && "$RUNNER" "$S" review-gate "$wbs" --spur-bin "$spurBin" --review-answer ".spur/run/$__runId-review-answer.txt" >&2
|
|
1338
1343
|
- from: review
|
|
1339
1344
|
to: review-fail-triage
|
|
1340
1345
|
description: >-
|
|
1341
|
-
No certified PASS without an open P1-P3 finding (FAIL, PARTIAL, missing, unparseable,
|
|
1342
|
-
|
|
1343
|
-
|
|
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) —
|
|
1349
|
+
classify the failure and route it into the bounded repair hop instead of dead-ending the run.
|
|
1344
1350
|
guard:
|
|
1345
1351
|
kind: always
|
|
1346
1352
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/spur",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
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",
|
|
@@ -57,15 +57,15 @@
|
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@commander-js/extra-typings": "^14.0.0",
|
|
60
|
-
"@gobing-ai/ts-db": "^0.5.
|
|
61
|
-
"@gobing-ai/ts-ai-runner": "^0.5.
|
|
62
|
-
"@gobing-ai/ts-dual-workflow-engine": "^0.5.
|
|
63
|
-
"@gobing-ai/ts-infra": "^0.5.
|
|
64
|
-
"@gobing-ai/ts-llm-jsonl-importer": "^0.5.
|
|
65
|
-
"@gobing-ai/ts-rule-engine": "^0.5.
|
|
66
|
-
"@gobing-ai/ts-runtime": "^0.5.
|
|
67
|
-
"@gobing-ai/ts-utils": "^0.5.
|
|
68
|
-
"@types/bun": "1.3
|
|
60
|
+
"@gobing-ai/ts-db": "^0.5.28",
|
|
61
|
+
"@gobing-ai/ts-ai-runner": "^0.5.28",
|
|
62
|
+
"@gobing-ai/ts-dual-workflow-engine": "^0.5.28",
|
|
63
|
+
"@gobing-ai/ts-infra": "^0.5.28",
|
|
64
|
+
"@gobing-ai/ts-llm-jsonl-importer": "^0.5.28",
|
|
65
|
+
"@gobing-ai/ts-rule-engine": "^0.5.28",
|
|
66
|
+
"@gobing-ai/ts-runtime": "^0.5.28",
|
|
67
|
+
"@gobing-ai/ts-utils": "^0.5.28",
|
|
68
|
+
"@types/bun": "1.4.3",
|
|
69
69
|
"@types/figlet": "^1.7.0",
|
|
70
70
|
"@types/node-notifier": "8.0.5",
|
|
71
71
|
"commander": "^14.0.3",
|