@gobing-ai/spur 0.3.85 → 0.3.87
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/pipeline-budgets.json +0 -25
- package/config/plugin-scripts.json +4 -5
- package/config/rules/boundary/env-var-hygiene.yaml +41 -0
- package/config/templates/feature/default.md +2 -0
- package/config/templates/task/brainstorm.md +2 -2
- package/config/templates/task/feature-impl.md +2 -2
- package/config/templates/task/issue.md +2 -2
- package/config/templates/task/meta.md +2 -2
- package/config/templates/task/review.md +2 -2
- package/config/templates/task/standard.md +2 -2
- package/config/transition-shims.json +1 -1
- package/config/workflow-candidates.json +19 -0
- package/config/workflows/feature-lifecycle.yaml +10 -2
- package/config/workflows/feature-verification.yaml +71 -0
- package/config/workflows/idea-pipeline.yaml +87 -39
- package/config/workflows/task-pipeline.yaml +43 -12
- package/config/workflows/wrapup-pipeline.yaml +70 -7
- package/package.json +9 -9
- package/plugins/sp/README.md +7 -7
- package/plugins/sp/commands/dev-idea.md +9 -2
- package/plugins/sp/commands/dev-refactor.md +33 -0
- package/plugins/sp/hooks/agent-hint.ts +5 -4
- package/plugins/sp/hooks/careful-guard.ts +3 -1
- package/plugins/sp/hooks/context-post-tool.ts +2 -1
- package/plugins/sp/hooks/context-session-start.ts +4 -3
- package/plugins/sp/hooks/context-session-stop.ts +2 -1
- package/plugins/sp/hooks/pi/guard-extension.ts +4 -3
- package/plugins/sp/hooks/task-write-guard.ts +4 -3
- package/plugins/sp/lib/idea-handoff.generated.mjs +260 -260
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/references/roles.md +1 -1
- package/plugins/sp/scripts/daily-summary/daily-summary.mjs +13 -4
- package/plugins/sp/scripts/daily-summary/daily-summary.ts +6 -4
- package/plugins/sp/scripts/feature-sync-bounded.mjs +10 -2
- package/plugins/sp/scripts/feature-sync-bounded.ts +2 -1
- package/plugins/sp/scripts/idea-coverage-check.ts +168 -0
- package/plugins/sp/scripts/idea-handoff.mjs +6 -1
- package/plugins/sp/scripts/idea-handoff.ts +4 -1
- package/plugins/sp/scripts/inline-pipeline-parity-check.ts +115 -4
- package/plugins/sp/scripts/inline-run-setup.ts +195 -2
- package/plugins/sp/scripts/pr-reviewing.mjs +8 -1
- package/plugins/sp/scripts/pr-reviewing.ts +2 -1
- package/plugins/sp/scripts/quality-gate.mjs +8 -1
- package/plugins/sp/scripts/quality-gate.ts +2 -1
- package/plugins/sp/scripts/surface-drift-inventory.ts +1 -4
- package/plugins/sp/scripts/task-evidence-precheck.ts +2 -1
- package/plugins/sp/scripts/task-size-precheck.ts +6 -4
- package/plugins/sp/scripts/verify-answer-lint.ts +2 -1
- package/plugins/sp/scripts/workflow-step-profile.mjs +10 -2
- package/plugins/sp/scripts/workflow-step-profile.ts +2 -1
- package/plugins/sp/scripts/wrapup-steps.mjs +8 -1
- package/plugins/sp/scripts/wrapup-steps.ts +2 -1
- package/plugins/sp/skills/brainstorm/SKILL.md +4 -0
- package/plugins/sp/skills/code-refactoring/SKILL.md +155 -0
- package/plugins/sp/skills/code-refactoring/references/finding-schema.md +74 -0
- package/plugins/sp/skills/code-refactoring/references/fix-ladder.md +52 -0
- package/plugins/sp/skills/code-refactoring/references/focus-detection.md +44 -0
- package/plugins/sp/skills/code-refactoring/references/refactor-finding.schema.json +95 -0
- package/plugins/sp/skills/spec-decomposition/references/decomposition.md +23 -16
- package/plugins/sp/skills/spur-cli/references/features/acceptance-criteria.md +4 -2
- package/plugins/sp/skills/spur-cli/references/features.md +6 -1
- package/plugins/sp/skills/spur-cli/references/workflows/authoring-workflows.md +2 -2
- package/plugins/sp/skills/spur-cli/references/workflows/operations.md +3 -3
- package/plugins/sp/skills/spur-cli/references/workflows/workflow-fit-and-tuning.md +1 -1
- package/plugins/sp/skills/spur-cli/references/workflows.md +8 -7
- package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +24 -0
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +4 -5
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +18 -2
- package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +1 -1
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +22 -3
- package/plugins/sp/skills/spur-dev/references/gate-checklists.md +2 -2
- package/plugins/sp/skills/spur-dev/references/idea-evaluation.md +11 -1
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +91 -1
- package/plugins/sp/skills/taste-refactoring-api/SKILL.md +44 -1
- package/plugins/sp/skills/taste-refactoring-api/references/protocol-modes.md +31 -0
- package/plugins/sp/skills/taste-refactoring-architect/SKILL.md +43 -0
- package/plugins/sp/skills/taste-refactoring-tests/SKILL.md +42 -0
- package/plugins/sp/skills/taste-refactoring-ui/SKILL.md +43 -0
- package/schemas/state-machine-workflow.schema.json +5 -0
- package/schemas/task-batch.schema.json +2 -2
- package/schemas/transition-flow-workflow.schema.json +5 -0
- package/spur.js +21106 -20669
- package/web/_astro/BoardApp.CJiqp5pS.js +1 -0
- package/web/_astro/{BoardApp.yW425dRZ.js → BoardApp.yBBcFXWP.js} +4 -4
- package/web/_astro/{TaskDetail.CGwJAinW.js → TaskDetail.DqFJbRFc.js} +1 -1
- package/web/_astro/{arc.B-qNXzSO.js → arc.DL-BpHoi.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.Bdg-xiji.js → architectureDiagram-3BPJPVTR.9IdQYyDq.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.DFArg3Kp.js → blockDiagram-GPEHLZMM.BKsFCqTl.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.BkOLcjyx.js → c4Diagram-AAUBKEIU.DhwI0dh1.js} +1 -1
- package/web/_astro/channel.CX5453qQ.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.DN3c20V4.js → chunk-2J33WTMH.B3QVmQ9S.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.B64K0Ttd.js → chunk-4BX2VUAB.DBSuqs9F.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.C-AJvNwa.js → chunk-55IACEB6.BSYTWAYD.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.DMkr46uS.js → chunk-727SXJPM.cWVuxXfS.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.4_WGbI64.js → chunk-AQP2D5EJ.DpU_Ob3d.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.cbFW_lVE.js → chunk-FMBD7UC4.BykFkyji.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.CDW_-2O1.js → chunk-ND2GUHAM.DwgHlMdY.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.BoYOt_yg.js → chunk-QZHKN3VN.CusXUGWM.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.BNT6XpHQ.js → classDiagram-4FO5ZUOK.fx0ObzkN.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.BNT6XpHQ.js → classDiagram-v2-Q7XG4LA2.fx0ObzkN.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.CI1DQxR3.js → cose-bilkent-S5V4N54A.Z4HgOlsd.js} +1 -1
- package/web/_astro/{cynefin-OW5HDTMX.A8ARH61p.js → cynefin-OW5HDTMX.B5dIZHJu.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.u28ZmqwR.js → dagre-BM42HDAG.DT70Q_Yw.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.Dx8JcrGc.js → diagram-2AECGRRQ.DqHA3XBF.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.BXJUG9GY.js → diagram-5GNKFQAL.BmCem957.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.BtlMuWqW.js → diagram-KO2AKTUF.sn0-hrE0.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.C4T7qaAy.js → diagram-LMA3HP47.BSHe9tVc.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.D5HECE10.js → diagram-OG6HWLK6.DHIc-86k.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.B_hMR3yw.js → erDiagram-TEJ5UH35.Bxayrs7v.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.BAmpcYl3.js → flowDiagram-I6XJVG4X.BkzoE_5I.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.DV1bSWK-.js → ganttDiagram-6RSMTGT7.okT6CvTo.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.DxYKkKrJ.js → gitGraphDiagram-PVQCEYII.CJuYbhC7.js} +1 -1
- package/web/_astro/{infoDiagram-5YYISTIA.BAWY2xMb.js → infoDiagram-5YYISTIA.RqLy7nBo.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.CZssRn6V.js → ishikawaDiagram-YF4QCWOH.BwIcoagw.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.C--muARd.js → journeyDiagram-JHISSGLW.UB1VbWtH.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.D_QCK4et.js → kanban-definition-UN3LZRKU.AaxMKpTk.js} +1 -1
- package/web/_astro/{linear.DzrmTtZ0.js → linear.Nv_xOUjP.js} +1 -1
- package/web/_astro/{mermaid.core.Da03W3iu.js → mermaid.core.Bc4LqQgX.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.6cy-8hR_.js → mindmap-definition-RKZ34NQL.oKUvU_qi.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.C5rS1pdU.js → pieDiagram-4H26LBE5.DQk0oo03.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.w56GZZ6Q.js → quadrantDiagram-W4KKPZXB.BdDjESDa.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.CipX3Pwu.js → requirementDiagram-4Y6WPE33.C2u9hUeH.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.C0VVzgJm.js → sankeyDiagram-5OEKKPKP.CDEoiJST.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.BX2dUUbF.js → sequenceDiagram-3UESZ5HK.D_hT_GAT.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.ypCdgODQ.js → stateDiagram-AJRCARHV.DI8RYG0b.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.In0baEtg.js → stateDiagram-v2-BHNVJYJU.Bkxz4DnP.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.CJN4Vkvl.js → timeline-definition-PNZ67QCA.DSY-kH3-.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.Cf8KkIPY.js → vennDiagram-CIIHVFJN.CpaDtuGr.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.DCZBo9xw.js → wardleyDiagram-YWT4CUSO.DujQWvo8.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.Cm4v_MiJ.js → xychartDiagram-2RQKCTM6.DcM5Y4b9.js} +1 -1
- package/web/index.html +1 -1
- package/config/workflows/basic.yaml +0 -146
- package/config/workflows/docs-pipeline.yaml +0 -350
- package/config/workflows/feature-dev.yaml +0 -288
- package/plugins/sp/scripts/feature-dev-precheck.mjs +0 -146
- package/plugins/sp/scripts/feature-dev-precheck.ts +0 -238
- package/web/_astro/BoardApp.CHenHFia.js +0 -1
- package/web/_astro/channel.CbDHK5UQ.js +0 -1
|
@@ -28,17 +28,6 @@
|
|
|
28
28
|
"source": "Post-merge count (0607 R2: doc-sync + learning-capture consolidated, 2 -> 1). Real-run reading (R5): median 253s, max-sane 2319s (n=44). Budget = 60 min ceiling.",
|
|
29
29
|
"decision": null
|
|
30
30
|
},
|
|
31
|
-
"docs-pipeline": {
|
|
32
|
-
"modelQueries": 2,
|
|
33
|
-
"wallClockMs": null,
|
|
34
|
-
"tokenCostUsd": null,
|
|
35
|
-
"source": "No fixture (0607 option a) and only dry/short runs recorded in history (max 1s, n=4) — wall-clock budget unenforced until a real docs-pipeline run exists. Query budget 2 matches the live workflow definition's query list ['draft','verify'] (added by task 0704; 0607 R3 recorded 1, which is stale against the definition). 0754 R6: FIX, not raise — the value was wrong against the definition, the workflow's declared query count did not change.",
|
|
36
|
-
"decision": {
|
|
37
|
-
"date": "2026-09-03",
|
|
38
|
-
"wbs": "0754",
|
|
39
|
-
"note": "align docs-pipeline.modelQueries to the live workflow definition's query list ['draft','verify']; not a measured-cost raise — the workflow's declared query count was already 2 (added by 0704); the budget was the stale side, not the workflow. Per D8 Decision 11."
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
31
|
"pr-review": {
|
|
43
32
|
"modelQueries": 0,
|
|
44
33
|
"wallClockMs": null,
|
|
@@ -53,26 +42,12 @@
|
|
|
53
42
|
"source": "Coverage entry (0826 R2): the live definition's model-query count (extractResolvedWorkflowFacts, 2026-09-11). No real-run measurement yet: wall-clock and cost are unenforced until measured, never 0.",
|
|
54
43
|
"decision": null
|
|
55
44
|
},
|
|
56
|
-
"feature-dev": {
|
|
57
|
-
"modelQueries": 2,
|
|
58
|
-
"wallClockMs": null,
|
|
59
|
-
"tokenCostUsd": null,
|
|
60
|
-
"source": "Coverage entry (0826 R2): the live definition's model-query count (extractResolvedWorkflowFacts, 2026-09-11). No real-run measurement yet: wall-clock and cost are unenforced until measured, never 0.",
|
|
61
|
-
"decision": null
|
|
62
|
-
},
|
|
63
45
|
"wayfinder-resolution": {
|
|
64
46
|
"modelQueries": 2,
|
|
65
47
|
"wallClockMs": null,
|
|
66
48
|
"tokenCostUsd": null,
|
|
67
49
|
"source": "Coverage entry (0826 R2): the live definition's model-query count (extractResolvedWorkflowFacts, 2026-09-11). No real-run measurement yet: wall-clock and cost are unenforced until measured, never 0.",
|
|
68
50
|
"decision": null
|
|
69
|
-
},
|
|
70
|
-
"basic": {
|
|
71
|
-
"modelQueries": 1,
|
|
72
|
-
"wallClockMs": null,
|
|
73
|
-
"tokenCostUsd": null,
|
|
74
|
-
"source": "Coverage entry (0826 R2): the live definition's model-query count (extractResolvedWorkflowFacts, 2026-09-11). No real-run measurement yet: wall-clock and cost are unenforced until measured, never 0.",
|
|
75
|
-
"decision": null
|
|
76
51
|
}
|
|
77
52
|
}
|
|
78
53
|
}
|
|
@@ -26,11 +26,6 @@
|
|
|
26
26
|
"contract": "standard",
|
|
27
27
|
"twin": "dogfood-testing/validate-report.mjs"
|
|
28
28
|
},
|
|
29
|
-
{
|
|
30
|
-
"rel": "feature-dev-precheck.ts",
|
|
31
|
-
"contract": "standard",
|
|
32
|
-
"twin": "feature-dev-precheck.mjs"
|
|
33
|
-
},
|
|
34
29
|
{
|
|
35
30
|
"rel": "feature-sync-bounded.ts",
|
|
36
31
|
"contract": "standard",
|
|
@@ -55,6 +50,10 @@
|
|
|
55
50
|
"rel": "inline-run-setup.ts",
|
|
56
51
|
"contract": "repo-only"
|
|
57
52
|
},
|
|
53
|
+
{
|
|
54
|
+
"rel": "idea-coverage-check.ts",
|
|
55
|
+
"contract": "repo-only"
|
|
56
|
+
},
|
|
58
57
|
{
|
|
59
58
|
"rel": "inline-pipeline-parity-check.ts",
|
|
60
59
|
"contract": "repo-only"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
$schema: "@gobing-ai/spur/schemas/rule-file.schema.json"
|
|
2
|
+
# Environment-variable hygiene — env access funnels through the config gateway (task 0902).
|
|
3
|
+
#
|
|
4
|
+
# Contract:
|
|
5
|
+
# - `@gobing-ai/ts-utils` (`packages/utils/src/env.ts` in ts-libs) is the single
|
|
6
|
+
# implementation source; `packages/config/src/index.ts` re-exports `getEnvVar` /
|
|
7
|
+
# `getEnvVars` / `setEnvVar` / `removeEnvVar` / `getAppOptions` as the app-side funnel,
|
|
8
|
+
# and NO file in this repo touches `process.env` directly — packages/config included.
|
|
9
|
+
# Env flows into the app as typed config or injected `env` records (ADR-027). Runtime
|
|
10
|
+
# options belong in `.spur/config.yaml` `bootstrap.options` via `getAppOptions`;
|
|
11
|
+
# dev-only knobs belong in consts.
|
|
12
|
+
# - Plugin scripts/hooks import the same functions from `@gobing-ai/ts-utils`; the
|
|
13
|
+
# `superskill script convert` `.mjs` twins bundle them in (self-contained on any
|
|
14
|
+
# install target).
|
|
15
|
+
# - `apps/web` uses `import.meta.env` (Vite browser plane) — not process env, never matches.
|
|
16
|
+
# - Which variables exist and who consumes them is documented in `.env.example`.
|
|
17
|
+
# (The former per-var lease table moved there; the rule now enforces the funnel,
|
|
18
|
+
# not a file-by-var inventory.)
|
|
19
|
+
#
|
|
20
|
+
# Scope: apps/**, packages/**, scripts/**, plugins/sp/** — src AND tests. No exclusions:
|
|
21
|
+
# even the gateway package itself is free of direct access.
|
|
22
|
+
include:
|
|
23
|
+
- "apps/**/src/**/*.{ts,tsx}"
|
|
24
|
+
- "apps/**/tests/**/*.{ts,tsx}"
|
|
25
|
+
- "packages/**/src/**/*.{ts,tsx}"
|
|
26
|
+
- "packages/**/tests/**/*.{ts,tsx}"
|
|
27
|
+
- "scripts/**/*.ts"
|
|
28
|
+
- "plugins/sp/**/*.ts"
|
|
29
|
+
rules:
|
|
30
|
+
- id: env-var-hygiene
|
|
31
|
+
description: >
|
|
32
|
+
No direct `process.env` or `Bun.env` access outside the packages/config gateway.
|
|
33
|
+
Read via `getEnvVar` (single var, undefined-only fallback), seed/compose via
|
|
34
|
+
`getEnvVars()` (live record — also the sanctioned form for setting/deleting
|
|
35
|
+
parent→child contract markers), or take an injected `env` record parameter.
|
|
36
|
+
Aliasing (`const env = process.env`) is caught too — it must touch `process.env`.
|
|
37
|
+
severity: error
|
|
38
|
+
evaluator:
|
|
39
|
+
type: rg
|
|
40
|
+
config:
|
|
41
|
+
pattern: "process\\.env|\\bBun\\.env\\b"
|
|
@@ -23,6 +23,8 @@ updated_at: "{{ CREATED_AT }}"
|
|
|
23
23
|
## Acceptance Criteria
|
|
24
24
|
|
|
25
25
|
```gherkin
|
|
26
|
+
# Keep the Feature: line (feature check L3.ac-bdd-error without it). Each Scenario: title is the
|
|
27
|
+
# identity key tasks reference verbatim ("- [ ] AC1 — <title>"); number R1, R2, …; never rename after tasks link.
|
|
26
28
|
Feature: {{ NAME }}
|
|
27
29
|
|
|
28
30
|
Scenario: Basic acceptance
|
|
@@ -23,11 +23,11 @@ updated_at: "{{ CREATED_AT }}"
|
|
|
23
23
|
|
|
24
24
|
### Requirements
|
|
25
25
|
|
|
26
|
-
<!-- Constraints the eventual direction must satisfy, if known. -->
|
|
26
|
+
<!-- One R-item per line, exactly `- [ ] R1. <text>` (checkbox + `R<n>.`); `spur task check` flags any other form. Constraints the eventual direction must satisfy, if known. -->
|
|
27
27
|
|
|
28
28
|
### Acceptance Criteria
|
|
29
29
|
|
|
30
|
-
<!--
|
|
30
|
+
<!-- Number items AC1, AC2, … (never R<n> — that is the Requirements namespace): `- [ ] AC1 — <feature scenario title without its R-number>` bullets or `Scenario: AC1 — <title>` blocks; add `(req: R<n>)` to bind a task requirement; task-only checks go in prose below, or set `ac_altitude: task-local`. Keep empty if not applicable. -->
|
|
31
31
|
|
|
32
32
|
### Q&A
|
|
33
33
|
|
|
@@ -23,11 +23,11 @@ updated_at: "{{ CREATED_AT }}"
|
|
|
23
23
|
|
|
24
24
|
### Requirements
|
|
25
25
|
|
|
26
|
-
<!-- R-
|
|
26
|
+
<!-- One R-item per line, exactly `- [ ] R1. <text>` (checkbox + `R<n>.`); `spur task check` flags any other form. Derive from the linked feature or refined task scope. -->
|
|
27
27
|
|
|
28
28
|
### Acceptance Criteria
|
|
29
29
|
|
|
30
|
-
<!--
|
|
30
|
+
<!-- Number items AC1, AC2, … (never R<n> — that is the Requirements namespace): `- [ ] AC1 — <feature scenario title without its R-number>` bullets or `Scenario: AC1 — <title>` blocks; add `(req: R<n>)` to bind a task requirement; task-only checks go in prose below, or set `ac_altitude: task-local`. Do not leave placeholder AC here. -->
|
|
31
31
|
|
|
32
32
|
### Q&A
|
|
33
33
|
|
|
@@ -23,11 +23,11 @@ updated_at: "{{ CREATED_AT }}"
|
|
|
23
23
|
|
|
24
24
|
### Requirements
|
|
25
25
|
|
|
26
|
-
<!-- R-
|
|
26
|
+
<!-- One R-item per line, exactly `- [ ] R1. <text>` (checkbox + `R<n>.`); `spur task check` flags any other form. Include repro/expected behavior if it helps traceability. -->
|
|
27
27
|
|
|
28
28
|
### Acceptance Criteria
|
|
29
29
|
|
|
30
|
-
<!--
|
|
30
|
+
<!-- Number items AC1, AC2, … (never R<n> — that is the Requirements namespace): `- [ ] AC1 — <feature scenario title without its R-number>` bullets or `Scenario: AC1 — <title>` blocks; add `(req: R<n>)` to bind a task requirement; task-only checks go in prose below, or set `ac_altitude: task-local`. Use a regression scenario proving the bug is fixed. -->
|
|
31
31
|
|
|
32
32
|
### Q&A
|
|
33
33
|
|
|
@@ -23,11 +23,11 @@ updated_at: "{{ CREATED_AT }}"
|
|
|
23
23
|
|
|
24
24
|
### Requirements
|
|
25
25
|
|
|
26
|
-
<!-- R-
|
|
26
|
+
<!-- One R-item per line, exactly `- [ ] R1. <text>` (checkbox + `R<n>.`); `spur task check` flags any other form. Keep empty if not applicable. -->
|
|
27
27
|
|
|
28
28
|
### Acceptance Criteria
|
|
29
29
|
|
|
30
|
-
<!--
|
|
30
|
+
<!-- Number items AC1, AC2, … (never R<n> — that is the Requirements namespace): `- [ ] AC1 — <feature scenario title without its R-number>` bullets or `Scenario: AC1 — <title>` blocks; add `(req: R<n>)` to bind a task requirement; task-only checks go in prose below, or set `ac_altitude: task-local`. Keep empty if not applicable. -->
|
|
31
31
|
|
|
32
32
|
### Q&A
|
|
33
33
|
|
|
@@ -33,11 +33,11 @@ in the reviewed PR/commit/diff). Fix in priority order (P1 → P2 → …); re-r
|
|
|
33
33
|
|
|
34
34
|
### Requirements
|
|
35
35
|
|
|
36
|
-
<!-- R-
|
|
36
|
+
<!-- One R-item per line, exactly `- [ ] R1. <text>` (checkbox + `R<n>.`); `spur task check` flags any other form. Fill after triage/refinement from the findings. -->
|
|
37
37
|
|
|
38
38
|
### Acceptance Criteria
|
|
39
39
|
|
|
40
|
-
<!--
|
|
40
|
+
<!-- Number items AC1, AC2, … (never R<n> — that is the Requirements namespace): `- [ ] AC1 — <feature scenario title without its R-number>` bullets or `Scenario: AC1 — <title>` blocks; add `(req: R<n>)` to bind a task requirement; task-only checks go in prose below, or set `ac_altitude: task-local`. Keep empty until the review task becomes executable work. -->
|
|
41
41
|
|
|
42
42
|
### Q&A
|
|
43
43
|
|
|
@@ -23,11 +23,11 @@ updated_at: "{{ CREATED_AT }}"
|
|
|
23
23
|
|
|
24
24
|
### Requirements
|
|
25
25
|
|
|
26
|
-
<!-- R-
|
|
26
|
+
<!-- One R-item per line, exactly `- [ ] R1. <text>` (checkbox + `R<n>.`); `spur task check` flags any other form. Keep empty until requirements are known. -->
|
|
27
27
|
|
|
28
28
|
### Acceptance Criteria
|
|
29
29
|
|
|
30
|
-
<!--
|
|
30
|
+
<!-- Number items AC1, AC2, … (never R<n> — that is the Requirements namespace): `- [ ] AC1 — <feature scenario title without its R-number>` bullets or `Scenario: AC1 — <title>` blocks; add `(req: R<n>)` to bind a task requirement; task-only checks go in prose below, or set `ac_altitude: task-local`. Keep empty if this task has no objective AC yet. -->
|
|
31
31
|
|
|
32
32
|
### Q&A
|
|
33
33
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"note": "Transition-shim manifest (task 0541, feature B2). Each entry records one compatibility path marked @transition-shim(<id>) in source. Every field is required. The gate (bun run transition-shim-check,
|
|
2
|
+
"note": "Transition-shim manifest (task 0541, feature B2). Each entry records one compatibility path marked @transition-shim(<id>) in source. Every field is required. The gate (bun run transition-shim-check, in the feature-scoped `spur-check-feature` pass since task 0872) is two-sided: an unregistered marker fails, and a listed entry whose marker is gone fails. Emptying this file is the definition of the transition being complete (docs/04_DESIGN.md §2.5). Removal conditions must be objectively checkable against the repository, not 'when convenient'. Shims are registered by the tasks that create them (0536/0537/0538/0542).",
|
|
3
3
|
"entries": [
|
|
4
4
|
{
|
|
5
5
|
"id": "agent-bare-binary-name",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"note": "Workflow graph-change promotion candidates (task 0873, feature D62; ADR-076 amendment). A candidate is shadow-run against recorded real-run inputs and is promoted into the canonical definition or deleted by its named deadline — never left as a standing parallel <name>2.yaml. `verdict` is null while pending and is filled by `bun scripts/spur-dev.ts promotion evaluate <id>`; `promotion check` (spur-check-feature) fails any candidate still present past its deadline, any unreferenced parallel definition in config/workflows/, and (0877 R8) any retired definition with real (non-dry) terminal runs lacking a recorded decision in `retirements[]`.",
|
|
4
|
+
"candidates": [],
|
|
5
|
+
"retirements": [
|
|
6
|
+
{
|
|
7
|
+
"name": "planning-pipeline",
|
|
8
|
+
"recordedBy": "0872 (ADR-072/075 composition-baseline pass 2dc86579a)",
|
|
9
|
+
"date": "2026-08-19",
|
|
10
|
+
"rationale": "Planning pipeline superseded by the task-pipeline planning stages; 3 real terminal runs retained in history."
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"name": "task-pipeline2",
|
|
14
|
+
"recordedBy": "ADR-076 (commit 017ac7a30)",
|
|
15
|
+
"date": "2026-08-20",
|
|
16
|
+
"rationale": "Standing parallel definition deleted with the D5-N fixture promotion bar; 5 real terminal runs retained in history."
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -37,6 +37,12 @@ states:
|
|
|
37
37
|
description: >
|
|
38
38
|
Feature verification work (DD-13). Makes verification derivable —
|
|
39
39
|
listable, event-triggerable, assignable.
|
|
40
|
+
onEnter:
|
|
41
|
+
# Caller wiring (task 0880, ADR-119): entering verification RUNS the
|
|
42
|
+
# feature-scoped pass instead of only passively reading its status file.
|
|
43
|
+
- kind: shell
|
|
44
|
+
options:
|
|
45
|
+
command: '$spurBin workflow run feature-verification.yaml --vars "{\"featureId\":\"$featureId\"}"'
|
|
40
46
|
- id: blocked
|
|
41
47
|
description: Impediment; work suspended.
|
|
42
48
|
- id: done
|
|
@@ -62,11 +68,13 @@ transitions:
|
|
|
62
68
|
- from: verifying
|
|
63
69
|
to: done
|
|
64
70
|
description: >
|
|
65
|
-
Feature verified — complete.
|
|
71
|
+
Feature verified — complete. Requires the feature-scoped verification pass
|
|
72
|
+
(ADR-119) to have recorded PASS, then strict check (AC validated,
|
|
73
|
+
traceability clean).
|
|
66
74
|
guard:
|
|
67
75
|
kind: shell
|
|
68
76
|
options:
|
|
69
|
-
command: '$spurBin feature check $featureId --strict --as done'
|
|
77
|
+
command: 'test "$(cat .spur/run/$featureId-feature-verification.status 2>/dev/null)" = PASS && $spurBin feature check $featureId --strict --as done'
|
|
70
78
|
|
|
71
79
|
# Rework: verifying → active (mandatory History entry)
|
|
72
80
|
- from: verifying
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Feature-scoped verification pass (ADR-119, feature D62, task 0872).
|
|
2
|
+
#
|
|
3
|
+
# Owns a lifecycle boundary no per-task graph owns: the repo-wide checks whose
|
|
4
|
+
# invariant spans the repository rather than a single task's diff — corpus
|
|
5
|
+
# consistency, contract baselines, dependency/schema drift, the frozen History
|
|
6
|
+
# surface, and the repo-wide test set. They run once per feature, deliberately
|
|
7
|
+
# the slow pass; `feature-lifecycle`'s verifying entry invokes this workflow (task
|
|
8
|
+
# 0880 caller wiring), and its verifying→done guard refuses to complete the
|
|
9
|
+
# feature until this pass records PASS (ADR-119 consequence: a feature is not
|
|
10
|
+
# done until it passes).
|
|
11
|
+
#
|
|
12
|
+
# Run: spur workflow run feature-verification.yaml --vars '{"featureId":"D62"}'
|
|
13
|
+
#
|
|
14
|
+
# Shape: verify -> done | failed. The shell action writes the verdict to
|
|
15
|
+
# `.spur/run/<featureId>-feature-verification.status` and always exits 0; the
|
|
16
|
+
# transition guard reads the status so a missing, corrupt or FAIL verdict routes
|
|
17
|
+
# to `failed` (fail-closed), never a silent PASS.
|
|
18
|
+
#
|
|
19
|
+
# Reliability (aligned with task-pipeline / ADR-043): no agent.run nodes; the
|
|
20
|
+
# verification command is a trusted config var executed via `sh -c` (same
|
|
21
|
+
# surface as task-pipeline's qualityGateCmd — never interpolate untrusted input).
|
|
22
|
+
"$schema": "@gobing-ai/spur/schemas/state-machine-workflow.schema.json"
|
|
23
|
+
kind: state-machine
|
|
24
|
+
name: feature-verification
|
|
25
|
+
version: "1"
|
|
26
|
+
description: "Feature-scoped verification pass (ADR-119): runs the repo-wide check set once per feature and records PASS/FAIL. Invoked by feature-lifecycle's verifying entry."
|
|
27
|
+
iterationBound: 2
|
|
28
|
+
initialState: verify
|
|
29
|
+
terminalStates:
|
|
30
|
+
- done
|
|
31
|
+
- failed
|
|
32
|
+
failureStates:
|
|
33
|
+
- failed
|
|
34
|
+
vars:
|
|
35
|
+
featureId: "X"
|
|
36
|
+
spurBin: "spur"
|
|
37
|
+
verificationCmd: "bun run spur-check-feature"
|
|
38
|
+
|
|
39
|
+
states:
|
|
40
|
+
- id: verify
|
|
41
|
+
description: >
|
|
42
|
+
Run the repo-wide check set, record the verdict, always exit 0.
|
|
43
|
+
onEnter:
|
|
44
|
+
- kind: shell
|
|
45
|
+
options:
|
|
46
|
+
command: >-
|
|
47
|
+
mkdir -p .spur/run;
|
|
48
|
+
sh -c "$verificationCmd" > ".spur/run/$featureId-feature-verification.log" 2>&1
|
|
49
|
+
&& printf 'PASS\n' > ".spur/run/$featureId-feature-verification.status"
|
|
50
|
+
|| printf 'FAIL\n' > ".spur/run/$featureId-feature-verification.status";
|
|
51
|
+
exit 0
|
|
52
|
+
|
|
53
|
+
- id: done
|
|
54
|
+
description: Terminal — repo-wide checks passed.
|
|
55
|
+
|
|
56
|
+
- id: failed
|
|
57
|
+
description: Terminal — repo-wide checks failed or the verdict is missing/corrupt.
|
|
58
|
+
|
|
59
|
+
transitions:
|
|
60
|
+
- from: verify
|
|
61
|
+
to: done
|
|
62
|
+
description: Repo-wide checks passed — the feature-scoped verification pass records PASS.
|
|
63
|
+
guard:
|
|
64
|
+
kind: shell
|
|
65
|
+
options:
|
|
66
|
+
command: 'test "$(cat .spur/run/$featureId-feature-verification.status 2>/dev/null)" = PASS'
|
|
67
|
+
- from: verify
|
|
68
|
+
to: failed
|
|
69
|
+
description: Repo-wide checks failed (or the verdict is missing/corrupt) — stop at failed.
|
|
70
|
+
guard:
|
|
71
|
+
kind: always
|