@gobing-ai/spur 0.3.34 → 0.3.36
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/config/corpus-baseline.json +61 -0
- package/config/launchd/ai.gobing.spur.history.daily.plist +56 -0
- package/config/rules/strict/runtime-boundaries.yaml +1 -0
- package/config/templates/task/brainstorm.md +1 -0
- package/config/templates/task/feature-impl.md +4 -1
- package/config/templates/task/issue.md +1 -0
- package/config/templates/task/meta.md +4 -1
- package/config/templates/task/review.md +1 -0
- package/config/templates/task/standard.md +4 -1
- package/config/workflows/idea-pipeline.yaml +1 -1
- package/config/workflows/task-pipeline.yaml +28 -5
- package/package.json +10 -10
- package/spur.js +3015 -743
- package/web/_astro/{BoardApp.CyyIiK76.js → BoardApp.8sc6Rb1t.js} +14 -14
- package/web/_astro/BoardApp.ChKnY1JD.js +1 -0
- package/web/_astro/{TaskDetail.BfUuRsfM.js → TaskDetail.DOKJP-Kp.js} +1 -1
- package/web/_astro/{arc.C7fql4LL.js → arc.CTqmqspU.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.IJPsRX-V.js → architectureDiagram-3BPJPVTR.B0iBdehs.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.B1AUwBxq.js → blockDiagram-GPEHLZMM.BHE5UFj5.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.BuSJPR3z.js → c4Diagram-AAUBKEIU.DQApkgGM.js} +1 -1
- package/web/_astro/channel.B0q9WGrH.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.CaOPTr9l.js → chunk-2J33WTMH.fPrKLM8v.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.DQzxExn8.js → chunk-4BX2VUAB.DExvwBhn.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.IIb103c7.js → chunk-55IACEB6.EjNkjuD6.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.DOYz1K1b.js → chunk-727SXJPM.Dl8xy5rT.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.CFcfW-wt.js → chunk-AQP2D5EJ.BSzMBgBs.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.C7Hn0jo3.js → chunk-FMBD7UC4.CAeOHpbb.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.Ba83VQ1m.js → chunk-ND2GUHAM.Bbeu_ZOH.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.CizNbIIP.js → chunk-QZHKN3VN.Da_GaIAZ.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.2NYYPXHq.js → classDiagram-4FO5ZUOK.sMfFYSQp.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.2NYYPXHq.js → classDiagram-v2-Q7XG4LA2.sMfFYSQp.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.DwBqVzml.js → cose-bilkent-S5V4N54A.PS3IwOH4.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.DqnYsHWG.js → dagre-BM42HDAG.EQCx8a6D.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.D8TKhgy-.js → diagram-2AECGRRQ.aEFQl8v8.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.BUD6Prj5.js → diagram-5GNKFQAL.jyN4tqFX.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.Cvg7hmND.js → diagram-KO2AKTUF.DaTVHnme.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.FUG_B9eS.js → diagram-LMA3HP47.DWsGRLAN.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.XsBZQ0hQ.js → diagram-OG6HWLK6.DYxmOViu.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.M_LSGgLQ.js → erDiagram-TEJ5UH35.BKM75coa.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.DZikZBRa.js → flowDiagram-I6XJVG4X.B7qpqDW5.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.DTKuEmXY.js → ganttDiagram-6RSMTGT7.CYBL-hwy.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.Dt-E9XmY.js → gitGraphDiagram-PVQCEYII.Cz4ly3Kq.js} +1 -1
- package/web/_astro/{infoDiagram-5YYISTIA.D5snevU1.js → infoDiagram-5YYISTIA.CIS7cXrJ.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.DmXdBf9W.js → ishikawaDiagram-YF4QCWOH.DQ-pmaOG.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.HPJSRkkU.js → journeyDiagram-JHISSGLW.DVS6F7UM.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.BxCqCnL1.js → kanban-definition-UN3LZRKU.D8t-G-U6.js} +1 -1
- package/web/_astro/{linear.BnXQUpS-.js → linear.IO8rTd_n.js} +1 -1
- package/web/_astro/{mermaid.core.D-ZeOmpg.js → mermaid.core.CjVnvFNf.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.DxrftiFR.js → mindmap-definition-RKZ34NQL.DZoEMTnU.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.D-ZcWxwg.js → pieDiagram-4H26LBE5.86r1QWnX.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.C-dVJ7GW.js → quadrantDiagram-W4KKPZXB.DzFA9uPk.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.lalE_R8X.js → requirementDiagram-4Y6WPE33.dQvdvfMr.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.C4uPynAF.js → sankeyDiagram-5OEKKPKP.BvC-VNI8.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.uBOenkqh.js → sequenceDiagram-3UESZ5HK.DDQNwHs8.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.CQOusSP2.js → stateDiagram-AJRCARHV.BKwYy-tQ.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.Bw0ZdjYb.js → stateDiagram-v2-BHNVJYJU.KxCiRYYf.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.DbkPA5ce.js → timeline-definition-PNZ67QCA.Bh9NDjOx.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.CIKhzwoA.js → vennDiagram-CIIHVFJN.DIM-n6us.js} +1 -1
- package/web/_astro/{wardley-L42UT6IY.0P-tqaFs.js → wardley-L42UT6IY.DW15qOFQ.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.DrwTvM_M.js → wardleyDiagram-YWT4CUSO.UTIvjsG9.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.BgJsQVms.js → xychartDiagram-2RQKCTM6.CQYhkVDS.js} +1 -1
- package/web/index.html +1 -1
- package/web/_astro/BoardApp.CBVEjvSW.js +0 -1
- package/web/_astro/channel.D3uZSASb.js +0 -1
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"note": "Accepted `spur task check` / `spur feature check` errors. This is a POLICY file, not a status dump: it is an INPUT to `bun run corpus-check`, so it must be committed — an untracked baseline means the gate behaves differently on every clone and CI, and the first person to meet 8 unexplained failures disables it. Do not move it under `.spur/` (gitignored, ephemeral run artifacts). The gate fails on any error NOT listed here, and ALSO on any entry that no longer reproduces, so this cannot rot into a silent suppression list. Every entry needs a real diagnosis, a reason, and a date — 'pre-existing, not investigated' is not a reason.",
|
|
3
|
+
"entries": [
|
|
4
|
+
{
|
|
5
|
+
"kind": "task",
|
|
6
|
+
"id": "0368",
|
|
7
|
+
"code": "L3.required-section-placeholder",
|
|
8
|
+
"reason": "RATCHET DRIFT, not a bypass. Closed 2026-07-28; the rule that flags it landed 2026-08-01 (f373e90b), four days later. It was legally closed under the rules of its day and became non-compliant retroactively. Backfill Testing/Solution or exempt permanently when someone next touches it.",
|
|
9
|
+
"since": "2026-08-07"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"kind": "task",
|
|
13
|
+
"id": "0454",
|
|
14
|
+
"code": "L3.solution-file-line",
|
|
15
|
+
"reason": "GENUINE PRE-FIX BYPASS. Closed 2026-08-06, well after the rule existed (2026-07-24), via the `--no-lifecycle` hole closed on 2026-08-07. Its Solution needs one file:line citation. The only entry here representing real unpaid debt.",
|
|
16
|
+
"since": "2026-08-07"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"kind": "feature",
|
|
20
|
+
"id": "M",
|
|
21
|
+
"code": "L3.ac-bdd-error",
|
|
22
|
+
"reason": "CHECKER GAP, not corpus debt. M is a wayfinder MAP; its Acceptance Criteria section carries an explicit prose disclaimer ('This feature is a wayfinder MAP... It has no acceptance criteria — its target is the ## Goal'). The BDD validator requires a `Feature:` declaration and has no notion of the map feature type. Correct fix is to teach `feature check` about wayfinder maps, not to bolt fake Gherkin onto a map.",
|
|
23
|
+
"since": "2026-08-07"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"kind": "feature",
|
|
27
|
+
"id": "M",
|
|
28
|
+
"code": "L3.ac-bdd-invalid",
|
|
29
|
+
"reason": "Downstream of the M ac-bdd-error entry — same missing-Feature-declaration cause, reported twice by the validator.",
|
|
30
|
+
"since": "2026-08-07"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"kind": "feature",
|
|
34
|
+
"id": "F82",
|
|
35
|
+
"code": "L3.ac-bdd-error",
|
|
36
|
+
"reason": "CHECKER GAP, same class as M: wayfinder map with a deliberate no-AC prose disclaimer (plus a noted exception for two implementation-ready child tickets). Not a syntax error to fix.",
|
|
37
|
+
"since": "2026-08-07"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"kind": "feature",
|
|
41
|
+
"id": "F82",
|
|
42
|
+
"code": "L3.ac-bdd-invalid",
|
|
43
|
+
"reason": "Downstream of the F82 ac-bdd-error entry — same cause, reported twice.",
|
|
44
|
+
"since": "2026-08-07"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"kind": "feature",
|
|
48
|
+
"id": "F821",
|
|
49
|
+
"code": "L3.ac-bdd-error",
|
|
50
|
+
"reason": "LEGACY AC FORMAT, not a map. F821's Acceptance Criteria are written as plain `R1 @core — …` prose rows rather than Gherkin, an older convention predating the BDD validator. Converting them is a real (small) job with traceability risk: AC titles are identity keys, so renaming breaks child-task scenario references.",
|
|
51
|
+
"since": "2026-08-07"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"kind": "feature",
|
|
55
|
+
"id": "F821",
|
|
56
|
+
"code": "L3.ac-bdd-invalid",
|
|
57
|
+
"reason": "Downstream of the F821 ac-bdd-error entry — same cause, reported twice.",
|
|
58
|
+
"since": "2026-08-07"
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>Label</key>
|
|
6
|
+
<string>ai.gobing.spur.history.daily</string>
|
|
7
|
+
|
|
8
|
+
<!-- ── Program: run the nightly history pipeline (task 0470+) ──────────── -->
|
|
9
|
+
<!-- Replace SPUR_BIN with the absolute path to your `spur` binary -->
|
|
10
|
+
<!-- (e.g. /opt/homebrew/bin/spur or the bun-linked monorepo CLI). -->
|
|
11
|
+
<!-- Replace PROJECT_DIR with the absolute path to your Spur project root. -->
|
|
12
|
+
<key>ProgramArguments</key>
|
|
13
|
+
<array>
|
|
14
|
+
<string>SPUR_BIN</string>
|
|
15
|
+
<string>history</string>
|
|
16
|
+
<string>daily</string>
|
|
17
|
+
<string>--json</string>
|
|
18
|
+
</array>
|
|
19
|
+
|
|
20
|
+
<!-- Working directory: the Spur project root. The daily command resolves -->
|
|
21
|
+
<!-- .spur/reports, .spur/logs, and the SQLite ledger relative to this. -->
|
|
22
|
+
<key>WorkingDirectory</key>
|
|
23
|
+
<string>PROJECT_DIR</string>
|
|
24
|
+
|
|
25
|
+
<!-- ── Schedule: daily wall-clock trigger (R3) ─────────────────────────── -->
|
|
26
|
+
<!-- 02:00 local time — picks a low-activity hour. Adjust Hour to taste. -->
|
|
27
|
+
<!-- launchd survives reboot and runs missed CalendarInterval jobs at the -->
|
|
28
|
+
<!-- next login, so a laptop closed overnight self-heals. -->
|
|
29
|
+
<key>StartCalendarInterval</key>
|
|
30
|
+
<dict>
|
|
31
|
+
<key>Hour</key>
|
|
32
|
+
<integer>2</integer>
|
|
33
|
+
<key>Minute</key>
|
|
34
|
+
<integer>0</integer>
|
|
35
|
+
</dict>
|
|
36
|
+
|
|
37
|
+
<!-- ── Log capture (R4): failures before Spur's own logging initializes ── -->
|
|
38
|
+
<!-- are still written here. launchd owns these file handles from the first -->
|
|
39
|
+
<!-- byte — there is no window where output is lost. -->
|
|
40
|
+
<key>StandardOutPath</key>
|
|
41
|
+
<string>PROJECT_DIR/.spur/logs/history-daily.out</string>
|
|
42
|
+
<key>StandardErrorPath</key>
|
|
43
|
+
<string>PROJECT_DIR/.spur/logs/history-daily.err</string>
|
|
44
|
+
|
|
45
|
+
<!-- RunAtLoad=false: do NOT fire every time the agent loads (boot/login). -->
|
|
46
|
+
<!-- StartCalendarInterval already re-fires a missed slot when the machine -->
|
|
47
|
+
<!-- wakes, so RunAtLoad would only cause duplicate runs. -->
|
|
48
|
+
|
|
49
|
+
<!-- If the process exits non-zero, do NOT auto-restart — the daily command -->
|
|
50
|
+
<!-- has its own retry semantics (checkpoint resume), and a tight retry loop -->
|
|
51
|
+
<!-- would mask a configuration error. The operator checks the four detection -->
|
|
52
|
+
<!-- layers (R5) instead. -->
|
|
53
|
+
<key>KeepAlive</key>
|
|
54
|
+
<false/>
|
|
55
|
+
</dict>
|
|
56
|
+
</plist>
|
|
@@ -60,6 +60,7 @@ rules:
|
|
|
60
60
|
- "packages/app/src/services/token-ledger-service.ts" # FD byte-window log tailing
|
|
61
61
|
- "packages/app/src/services/token-ledger-watcher.ts" # node:fs watch() live watcher
|
|
62
62
|
- "packages/app/src/services/project-registry.ts" # atomic projects.json persistence
|
|
63
|
+
- "packages/app/src/services/history-service.ts" # versioned analyze artifact + bounded-errors sidecar + latest.json symlink pointer (task 0474); ts-runtime FileSystem seam has no symlink, so the pointer uses node:fs directly (mirrors project-registry.ts persistence exemption)
|
|
63
64
|
- "packages/app/src/observability/workflow-run-log-sink.ts" # sync FD append for mid-run tail-able all-in-one run log (task 0426 / feature D2); append() is sync from the observability bus
|
|
64
65
|
- "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
|
|
65
66
|
- "apps/web/src/modules/discover.ts" # Vite/Astro module scanner fallback under bun test
|
|
@@ -10,6 +10,7 @@ parent_wbs: null
|
|
|
10
10
|
priority: P2
|
|
11
11
|
tags: []
|
|
12
12
|
dependencies: []
|
|
13
|
+
ac_numbering: task-local
|
|
13
14
|
created_at: "{{ CREATED_AT }}"
|
|
14
15
|
updated_at: "{{ CREATED_AT }}"
|
|
15
16
|
---
|
|
@@ -30,7 +31,9 @@ updated_at: "{{ CREATED_AT }}"
|
|
|
30
31
|
|
|
31
32
|
### Q&A
|
|
32
33
|
|
|
33
|
-
<!--
|
|
34
|
+
<!-- CLOSED decisions from refinement: what was chosen and why, what was deferred and on what
|
|
35
|
+
condition. Not a parking lot for open questions — an unanswered question here means the task
|
|
36
|
+
is not ready to hand off. Keep empty if none. -->
|
|
34
37
|
|
|
35
38
|
### Design
|
|
36
39
|
|
|
@@ -10,6 +10,7 @@ parent_wbs: null
|
|
|
10
10
|
priority: P2
|
|
11
11
|
tags: ["meta"]
|
|
12
12
|
dependencies: []
|
|
13
|
+
ac_numbering: task-local
|
|
13
14
|
created_at: "{{ CREATED_AT }}"
|
|
14
15
|
updated_at: "{{ CREATED_AT }}"
|
|
15
16
|
---
|
|
@@ -30,7 +31,9 @@ updated_at: "{{ CREATED_AT }}"
|
|
|
30
31
|
|
|
31
32
|
### Q&A
|
|
32
33
|
|
|
33
|
-
<!--
|
|
34
|
+
<!-- CLOSED decisions from refinement: what was chosen and why, what was deferred and on what
|
|
35
|
+
condition. Not a parking lot for open questions — an unanswered question here means the task
|
|
36
|
+
is not ready to hand off. Keep empty if none. -->
|
|
34
37
|
|
|
35
38
|
### Design
|
|
36
39
|
|
|
@@ -10,6 +10,7 @@ parent_wbs: null
|
|
|
10
10
|
priority: P2
|
|
11
11
|
tags: []
|
|
12
12
|
dependencies: []
|
|
13
|
+
ac_numbering: task-local
|
|
13
14
|
created_at: "{{ CREATED_AT }}"
|
|
14
15
|
updated_at: "{{ CREATED_AT }}"
|
|
15
16
|
---
|
|
@@ -30,7 +31,9 @@ updated_at: "{{ CREATED_AT }}"
|
|
|
30
31
|
|
|
31
32
|
### Q&A
|
|
32
33
|
|
|
33
|
-
<!--
|
|
34
|
+
<!-- CLOSED decisions from refinement: what was chosen and why, what was deferred and on what
|
|
35
|
+
condition. Not a parking lot for open questions — an unanswered question here means the task
|
|
36
|
+
is not ready to hand off. Keep empty if none. -->
|
|
34
37
|
|
|
35
38
|
### Design
|
|
36
39
|
|
|
@@ -247,7 +247,7 @@ states:
|
|
|
247
247
|
- kind: agent.run
|
|
248
248
|
options:
|
|
249
249
|
agent: ${vars.agent}
|
|
250
|
-
input: "Run sp:spec-decomposition for feature ${vars.featureId}. Read the brainstorm artifact, feature AC, and design doc.
|
|
250
|
+
input: "Run sp:spec-decomposition for feature ${vars.featureId}. Read the brainstorm artifact, feature AC, and design doc. SIZING FIRST, before any JSON: apply the skill's `Default to NOT decomposing` rubric to the whole unit of work — if it scores 0-2 the correct output is a ONE-entry batch, not many. Scenario count is not task count: merge scenarios that one task delivers (same file surface, same subsystem, or unreadable apart in review), and list every scenario a task covers in its background. Merging never costs AC coverage — one task may carry several scenarios. Do not emit one entry per scenario or per requirement by reflex. Then produce a task-batch JSON array at .spur/run/${vars.__runId}-idea-task-batch.json, validated against apps/cli/schemas/task-batch.schema.json. Schema-permitted fields per entry: `name`, `background`, `requirements`, `feature_id`, `parent_wbs`, `priority`, `tags`, `template` — schema validation rejects anything else. Acceptance Criteria, Design, and Plan sections are filled in by the per-task refine step after batch-create, NOT at decompose time. Validate locally against the schema before emitting."
|
|
251
251
|
expectFile: .spur/run/${vars.__runId}-idea-task-batch.json
|
|
252
252
|
timeoutMs: ${vars.stepTimeoutMs}
|
|
253
253
|
|
|
@@ -57,6 +57,10 @@ vars:
|
|
|
57
57
|
# `--vars '{"agent":"claude"}'`. Pinned (not left to the AiRunner's <default>
|
|
58
58
|
# selection) so a broken/misconfigured agent on the box can't silently capture the run.
|
|
59
59
|
agent: "omp"
|
|
60
|
+
# Implement-only executor override (R1, task 0454). Defaults to same as agent.
|
|
61
|
+
# Override with `--vars '{"implementAgent":"omp-zai"}'` to pin implement to a
|
|
62
|
+
# specific executor while other hops keep the default agent.
|
|
63
|
+
implementAgent: "omp"
|
|
60
64
|
# Step-level timeout for agentic hops (review / verify / test-fix) in ms.
|
|
61
65
|
# Soft quality-gate shells are unbounded by this var (host shell only).
|
|
62
66
|
# Raised 600s → 1800s (task 0398 R4 / H6 dogfood). Override:
|
|
@@ -78,7 +82,7 @@ vars:
|
|
|
78
82
|
# and the fixall slash input all use this same var so the command stays single-sourced.
|
|
79
83
|
# TRUSTED CONFIG ONLY — this string is executed via `sh -c` (see test/test-recheck). Never
|
|
80
84
|
# interpolate untrusted operator/LLM input into qualityGateCmd (task 0436 SECUA residual).
|
|
81
|
-
qualityGateCmd: "bun run
|
|
85
|
+
qualityGateCmd: "bun run format && bun run spur-check"
|
|
82
86
|
# Max /sp:dev-fixall attempts after a red quality-gate probe/recheck (bounded; no thrash).
|
|
83
87
|
# Attempt counter: .spur/run/<wbs>-test-fix-attempt. Default 2 = two fixall hops before failed.
|
|
84
88
|
qualityGateMaxFixAttempts: "2"
|
|
@@ -86,6 +90,12 @@ vars:
|
|
|
86
90
|
# project can point it at its own formatter; invoked best-effort (a missing or
|
|
87
91
|
# failing formatter must never abort a run — the quality gate is the real gate).
|
|
88
92
|
formatCmd: "bun run format"
|
|
93
|
+
# Max R-items in ## Requirements before size precheck fails (R2, task 0454).
|
|
94
|
+
# Override with `--vars '{"maxImplementReqs":"12"}'`.
|
|
95
|
+
maxImplementReqs: "5"
|
|
96
|
+
# Max checklist items under ## Plan before size precheck fails (R2, task 0454).
|
|
97
|
+
# Override with `--vars '{"maxImplementPlanItems":"15"}'`.
|
|
98
|
+
maxImplementPlanItems: "8"
|
|
89
99
|
|
|
90
100
|
states:
|
|
91
101
|
- id: precheck
|
|
@@ -128,6 +138,17 @@ states:
|
|
|
128
138
|
fi;
|
|
129
139
|
fi;
|
|
130
140
|
exit 0
|
|
141
|
+
# R2 (0454): task size precheck — evaluate R-item and Plan-item counts.
|
|
142
|
+
# Writes PASS/FAIL to .spur/run/<wbs>-precheck-size.status. Always exit 0
|
|
143
|
+
# (soft check, like doctor). The precheck→implement guard reads the file.
|
|
144
|
+
- kind: shell
|
|
145
|
+
options:
|
|
146
|
+
command: >-
|
|
147
|
+
SIZE_FILE=".spur/run/$wbs-precheck-size.status" &&
|
|
148
|
+
mkdir -p .spur/run &&
|
|
149
|
+
bun plugins/sp/scripts/task-size-precheck.ts "$wbs"
|
|
150
|
+
--max-reqs "$maxImplementReqs" --max-plan-items "$maxImplementPlanItems" &&
|
|
151
|
+
exit 0
|
|
131
152
|
|
|
132
153
|
- id: implement
|
|
133
154
|
description: >
|
|
@@ -145,7 +166,7 @@ states:
|
|
|
145
166
|
onEnter:
|
|
146
167
|
- kind: agent.run
|
|
147
168
|
options:
|
|
148
|
-
agent: ${vars.
|
|
169
|
+
agent: ${vars.implementAgent}
|
|
149
170
|
# Pure slash command only (ADR-043). Anti-recursion / implement discipline
|
|
150
171
|
# lives in /sp:dev-run --mode implement → sp:code-implementation, not YAML prose.
|
|
151
172
|
input: /sp:dev-run --mode implement ${vars.wbs} --auto
|
|
@@ -269,8 +290,10 @@ states:
|
|
|
269
290
|
- id: verify
|
|
270
291
|
description: >
|
|
271
292
|
Functional verification (BDD + traceability) via /sp:dev-verify. The agent's
|
|
272
|
-
captured answer is written to `.spur/run/<wbs>-verify-answer.txt
|
|
273
|
-
|
|
293
|
+
captured answer is written to `.spur/run/<wbs>-verify-answer.txt` and MUST follow
|
|
294
|
+
the answer-file schema contract (explicit `Verdict: PASS|PARTIAL|FAIL` line plus
|
|
295
|
+
`| Req | Status | Evidence |` and `| AC | Status | Evidence Type | Evidence |` tables);
|
|
296
|
+
a deterministic shell step then derives the verdict and writes the gate artifact
|
|
274
297
|
`.spur/run/<wbs>-verdict.json` (so the completion gate reads a real verdict, not
|
|
275
298
|
agent discretion — R9). The verdict is PASS only if the agent both reported PASS
|
|
276
299
|
AND `spur task check` passes; otherwise FAIL.
|
|
@@ -352,7 +375,7 @@ transitions:
|
|
|
352
375
|
guard:
|
|
353
376
|
kind: shell
|
|
354
377
|
options:
|
|
355
|
-
command: 'test "$(cat .spur/run/$wbs-precheck-doctor.status 2>/dev/null)" = PASS && $spurBin task check $wbs'
|
|
378
|
+
command: 'test "$(cat .spur/run/$wbs-precheck-doctor.status 2>/dev/null)" = PASS && test "$(cat .spur/run/$wbs-precheck-size.status 2>/dev/null)" = PASS && $spurBin task check $wbs'
|
|
356
379
|
- from: precheck
|
|
357
380
|
to: failed
|
|
358
381
|
description: Doctor FAIL and/or task check failed — stop before implement.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/spur",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "Spur CLI
|
|
3
|
+
"version": "0.3.36",
|
|
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",
|
|
7
7
|
"cli",
|
|
@@ -50,14 +50,14 @@
|
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@commander-js/extra-typings": "^14.0.0",
|
|
53
|
-
"@gobing-ai/ts-db": "^0.4.
|
|
54
|
-
"@gobing-ai/ts-ai-runner": "^0.4.
|
|
55
|
-
"@gobing-ai/ts-dual-workflow-engine": "^0.4.
|
|
56
|
-
"@gobing-ai/ts-infra": "^0.4.
|
|
57
|
-
"@gobing-ai/ts-llm-jsonl-importer": "^0.4.
|
|
58
|
-
"@gobing-ai/ts-rule-engine": "^0.4.
|
|
59
|
-
"@gobing-ai/ts-runtime": "^0.4.
|
|
60
|
-
"@gobing-ai/ts-utils": "^0.4.
|
|
53
|
+
"@gobing-ai/ts-db": "^0.4.23",
|
|
54
|
+
"@gobing-ai/ts-ai-runner": "^0.4.23",
|
|
55
|
+
"@gobing-ai/ts-dual-workflow-engine": "^0.4.23",
|
|
56
|
+
"@gobing-ai/ts-infra": "^0.4.23",
|
|
57
|
+
"@gobing-ai/ts-llm-jsonl-importer": "^0.4.23",
|
|
58
|
+
"@gobing-ai/ts-rule-engine": "^0.4.23",
|
|
59
|
+
"@gobing-ai/ts-runtime": "^0.4.23",
|
|
60
|
+
"@gobing-ai/ts-utils": "^0.4.23",
|
|
61
61
|
"@types/bun": "1.3.14",
|
|
62
62
|
"@types/figlet": "^1.7.0",
|
|
63
63
|
"@types/node-notifier": "8.0.5",
|