@gobing-ai/spur 0.4.11 → 0.4.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/config.example.yaml +22 -0
  3. package/config/rules/boundary/config-loading-ownership.yaml +1 -1
  4. package/config/rules/quality/coverage-gate.yaml +2 -2
  5. package/config/rules/strict/runtime-boundaries.yaml +2 -2
  6. package/config/rules/surface/check-cli-surface.yaml +4 -0
  7. package/config/rules/typescript/output-boundaries.yaml +4 -10
  8. package/config/workflows/feature-verification.yaml +14 -5
  9. package/config/workflows/idea-pipeline.yaml +92 -12
  10. package/config/workflows/task-pipeline.yaml +456 -830
  11. package/config/workflows/wayfinder-resolution.yaml +20 -3
  12. package/config/workflows/wrapup-pipeline.yaml +22 -9
  13. package/package.json +1 -1
  14. package/plugins/sp/README.md +2 -2
  15. package/plugins/sp/agents/super-planner.md +2 -2
  16. package/plugins/sp/agents/super-reviewer.md +17 -8
  17. package/plugins/sp/bunfig.toml +3 -3
  18. package/plugins/sp/commands/dev-changelog.md +1 -1
  19. package/plugins/sp/commands/dev-gitmsg.md +2 -2
  20. package/plugins/sp/commands/dev-handover.md +1 -1
  21. package/plugins/sp/commands/dev-idea.md +23 -13
  22. package/plugins/sp/commands/dev-job-dump.md +1 -1
  23. package/plugins/sp/commands/dev-plan.md +17 -6
  24. package/plugins/sp/commands/dev-review.md +1 -1
  25. package/plugins/sp/commands/dev-run.md +8 -7
  26. package/plugins/sp/commands/dev-runall.md +1 -1
  27. package/plugins/sp/plugin.json +1 -1
  28. package/plugins/sp/skills/code-implementation/SKILL.md +7 -7
  29. package/plugins/sp/skills/code-refactoring/SKILL.md +1 -1
  30. package/plugins/sp/skills/code-verification/SKILL.md +1 -1
  31. package/plugins/sp/skills/code-verification/references/secu-review.md +1 -1
  32. package/plugins/sp/skills/code-verification/references/verdict-schema.md +23 -10
  33. package/plugins/sp/skills/doc-evolve/SKILL.md +1 -1
  34. package/plugins/sp/skills/next-router/references/routing-table.md +1 -1
  35. package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +7 -7
  36. package/plugins/sp/skills/spec-decomposition/references/decomposition.md +4 -4
  37. package/plugins/sp/skills/spur-check/SKILL.md +9 -8
  38. package/plugins/sp/skills/spur-cli/SKILL.md +2 -2
  39. package/plugins/sp/skills/spur-cli/references/self.md +37 -2
  40. package/plugins/sp/skills/spur-cli/references/tasks/l3-guard-cheatsheet.md +1 -1
  41. package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +3 -3
  42. package/plugins/sp/skills/spur-cli/references/tasks.md +1 -1
  43. package/plugins/sp/skills/spur-cli/references/workflows.md +5 -3
  44. package/plugins/sp/skills/spur-dev/SKILL.md +3 -3
  45. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +12 -11
  46. package/plugins/sp/skills/spur-dev/references/dev-operations.md +15 -15
  47. package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +4 -3
  48. package/plugins/sp/skills/spur-dev/references/execution-batch-report.md +4 -4
  49. package/plugins/sp/skills/spur-dev/references/execution-batch.md +13 -11
  50. package/plugins/sp/skills/spur-dev/references/execution-workflow.md +32 -23
  51. package/plugins/sp/skills/spur-dev/references/execution-worktree-landing.md +5 -5
  52. package/plugins/sp/skills/spur-dev/references/execution-worktree-setup.md +4 -4
  53. package/plugins/sp/skills/spur-dev/references/gate-checklists.md +4 -4
  54. package/plugins/sp/skills/spur-dev/references/idea-evaluation.md +1 -1
  55. package/schemas/spur-config.schema.json +19 -1
  56. package/spur.js +31459 -31868
  57. package/web/_astro/{BoardApp.BMprmPRc.js → BoardApp.Bjdp3XWV.js} +36 -36
  58. package/web/_astro/{BoardApp.B5rTVNd_.js → BoardApp.DCDZxLlQ.js} +1 -1
  59. package/web/_astro/{TaskDetail.Ddsur8qd.js → TaskDetail.B3vBxynO.js} +1 -1
  60. package/web/_astro/{arc.DLqVVBxP.js → arc.DcuHTB_T.js} +1 -1
  61. package/web/_astro/{architectureDiagram-3BPJPVTR.C-Pk3uAi.js → architectureDiagram-3BPJPVTR.ClOFWBON.js} +1 -1
  62. package/web/_astro/{blockDiagram-GPEHLZMM.BRO1i_Nm.js → blockDiagram-GPEHLZMM.otYyr7Zb.js} +1 -1
  63. package/web/_astro/{c4Diagram-AAUBKEIU.BU_cWu6e.js → c4Diagram-AAUBKEIU.BCjpc9LP.js} +1 -1
  64. package/web/_astro/channel.qgOLXjI_.js +1 -0
  65. package/web/_astro/{chunk-2J33WTMH.D2VXiQ2t.js → chunk-2J33WTMH.D5Wpnpt_.js} +1 -1
  66. package/web/_astro/{chunk-4BX2VUAB.BcHT772J.js → chunk-4BX2VUAB.DkQGtWNz.js} +1 -1
  67. package/web/_astro/{chunk-55IACEB6.DhDtICmo.js → chunk-55IACEB6.B7dqjAip.js} +1 -1
  68. package/web/_astro/{chunk-727SXJPM.BoKHp7gV.js → chunk-727SXJPM.BDQvnKE2.js} +1 -1
  69. package/web/_astro/{chunk-AQP2D5EJ.Chu4JRpE.js → chunk-AQP2D5EJ.D92doBX5.js} +1 -1
  70. package/web/_astro/{chunk-FMBD7UC4.wHdwKPlq.js → chunk-FMBD7UC4.C968oI5G.js} +1 -1
  71. package/web/_astro/{chunk-ND2GUHAM.ffN-M1JB.js → chunk-ND2GUHAM.AkkYC1bY.js} +1 -1
  72. package/web/_astro/{chunk-QZHKN3VN.FRubwg4S.js → chunk-QZHKN3VN.sCc-rKKo.js} +1 -1
  73. package/web/_astro/{classDiagram-4FO5ZUOK.c22tQsc_.js → classDiagram-4FO5ZUOK.pOQ9u0mY.js} +1 -1
  74. package/web/_astro/{classDiagram-v2-Q7XG4LA2.c22tQsc_.js → classDiagram-v2-Q7XG4LA2.pOQ9u0mY.js} +1 -1
  75. package/web/_astro/{cose-bilkent-S5V4N54A.B9c6fiSj.js → cose-bilkent-S5V4N54A.CRaeD6FY.js} +1 -1
  76. package/web/_astro/{cynefin-OW5HDTMX.DrZsrUHl.js → cynefin-OW5HDTMX.BiCPBu54.js} +1 -1
  77. package/web/_astro/{dagre-BM42HDAG.DG1U4b3y.js → dagre-BM42HDAG.C1-q3vkT.js} +1 -1
  78. package/web/_astro/{diagram-2AECGRRQ.CH15b-K3.js → diagram-2AECGRRQ.BSVOv30O.js} +1 -1
  79. package/web/_astro/{diagram-5GNKFQAL.BH1j7twR.js → diagram-5GNKFQAL.CHMkjJ-V.js} +1 -1
  80. package/web/_astro/{diagram-KO2AKTUF.q2zCkbAj.js → diagram-KO2AKTUF.CKY9M564.js} +1 -1
  81. package/web/_astro/{diagram-LMA3HP47.BLaaZnHV.js → diagram-LMA3HP47.B9yNJiTP.js} +1 -1
  82. package/web/_astro/{diagram-OG6HWLK6.BcpRdQwI.js → diagram-OG6HWLK6.Dk8AUGsk.js} +1 -1
  83. package/web/_astro/{erDiagram-TEJ5UH35.D7KBlqfM.js → erDiagram-TEJ5UH35.BQHR89TZ.js} +1 -1
  84. package/web/_astro/{flowDiagram-I6XJVG4X.D_gmuRqg.js → flowDiagram-I6XJVG4X.oNkWVgoK.js} +1 -1
  85. package/web/_astro/{ganttDiagram-6RSMTGT7.DzgWYniD.js → ganttDiagram-6RSMTGT7.Kz2U2nu9.js} +1 -1
  86. package/web/_astro/{gitGraphDiagram-PVQCEYII.576i3hm3.js → gitGraphDiagram-PVQCEYII.DHIZ_wPq.js} +1 -1
  87. package/web/_astro/{infoDiagram-5YYISTIA.DMCclBiz.js → infoDiagram-5YYISTIA.D0NJLcv9.js} +1 -1
  88. package/web/_astro/{ishikawaDiagram-YF4QCWOH.9Kyca4SH.js → ishikawaDiagram-YF4QCWOH.CFEfTWRG.js} +1 -1
  89. package/web/_astro/{journeyDiagram-JHISSGLW.chbdG-8q.js → journeyDiagram-JHISSGLW.Dc7IE7I4.js} +1 -1
  90. package/web/_astro/{kanban-definition-UN3LZRKU.Bds54-e0.js → kanban-definition-UN3LZRKU.D5v0xO9k.js} +1 -1
  91. package/web/_astro/{linear.D5ND9GN_.js → linear.wR5KzXnE.js} +1 -1
  92. package/web/_astro/{mermaid.core.D9N_PGbj.js → mermaid.core.BDQ2FoPd.js} +4 -4
  93. package/web/_astro/{mindmap-definition-RKZ34NQL.t0xop5vp.js → mindmap-definition-RKZ34NQL.W6_INsia.js} +1 -1
  94. package/web/_astro/{pieDiagram-4H26LBE5.DqgKh6hM.js → pieDiagram-4H26LBE5.61ihbgkK.js} +1 -1
  95. package/web/_astro/{quadrantDiagram-W4KKPZXB.DeuHVi2t.js → quadrantDiagram-W4KKPZXB.B5lEpFLo.js} +1 -1
  96. package/web/_astro/{requirementDiagram-4Y6WPE33.BdYFSG4W.js → requirementDiagram-4Y6WPE33.CmhVBVX0.js} +1 -1
  97. package/web/_astro/{sankeyDiagram-5OEKKPKP.k1LPPETJ.js → sankeyDiagram-5OEKKPKP.D7Vvj9Wf.js} +1 -1
  98. package/web/_astro/{sequenceDiagram-3UESZ5HK.DdyfpzoG.js → sequenceDiagram-3UESZ5HK.B1vPLixM.js} +1 -1
  99. package/web/_astro/{stateDiagram-AJRCARHV.DSEI8il0.js → stateDiagram-AJRCARHV.BnACmrGi.js} +1 -1
  100. package/web/_astro/{stateDiagram-v2-BHNVJYJU.CoMnQRKo.js → stateDiagram-v2-BHNVJYJU.CW4pnmc3.js} +1 -1
  101. package/web/_astro/{timeline-definition-PNZ67QCA.DM1AHNm-.js → timeline-definition-PNZ67QCA.CkzMCPnC.js} +1 -1
  102. package/web/_astro/{vennDiagram-CIIHVFJN.C-cJmVtl.js → vennDiagram-CIIHVFJN.CY4aNdAR.js} +1 -1
  103. package/web/_astro/{wardleyDiagram-YWT4CUSO.D0xMzKPb.js → wardleyDiagram-YWT4CUSO.BtoU9UFk.js} +1 -1
  104. package/web/_astro/{xychartDiagram-2RQKCTM6.BH5xJcEq.js → xychartDiagram-2RQKCTM6._9ijUUAs.js} +1 -1
  105. package/web/index.html +1 -1
  106. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +0 -997
  107. package/plugins/sp/skills/spur-dev/references/structured-trace-emission.md +0 -178
  108. package/web/_astro/channel.Bs3Illhy.js +0 -1
@@ -52,8 +52,8 @@ that a flat FSM cannot express.
52
52
  The active batch orchestrator owns the spaces **between** task runs: resolve+freeze the set,
53
53
  topo-sort, run each task's pipeline, inspect terminal state, decide continue/halt, and emit the
54
54
  report. It does not redefine individual steps. Interactive sequential omit/inline delegates each
55
- ready WBS to [inline-pipeline-driver.md](inline-pipeline-driver.md); explicit/parallel/headless paths
56
- delegate to the workflow engine and `vars.agent` resolution.
55
+ ready WBS to the same engine loop as every other path (host executor by default); explicit/parallel/
56
+ headless paths delegate to the workflow engine and `vars.agent` resolution.
57
57
 
58
58
  ## Step 1 — Selector resolution (R1)
59
59
 
@@ -316,7 +316,8 @@ per-task letter is ever hand-assigned.
316
316
  4. **When a task ends:** mark the task's letter (and its published digits) with the task's terminal
317
317
  outcome — `done` renders completed; `failed`/`skipped`/`blocked` render pending + ` [<outcome>]`
318
318
  per the frozen status mapping in
319
- [inline-pipeline-driver.md](inline-pipeline-driver.md) § Host todo update styles.
319
+ [cross-cutting.md](cross-cutting.md#shared-startup-contract-task-0814-r1r3r4r6r7r8) § Publish the
320
+ generated plan (per-item and full-list host update styles).
320
321
 
321
322
  ## Step 3 — The driver loop (R3, R4)
322
323
 
@@ -338,7 +339,8 @@ for wbs in plan: # default sequential mode
338
339
  report += preflight-skip(wbs, preflight); continue
339
340
  visible plan (§2.7): letter in_progress + task-children digits at start; letter ← outcome at end
340
341
  run: if interactive sequential omit/inline:
341
- inline-pipeline-driver(task-pipeline.yaml, wbs)
342
+ spur workflow run task-pipeline.yaml --vars <vars with executor=host> --json
343
+ perform the returned work item; spur workflow continue <run-id> --answer-text <receipt>
342
344
  else:
343
345
  spur workflow run task-pipeline.yaml --vars <vars> --async --json
344
346
  follow trace until terminal # spur workflow trace "$RUN" --follow --timeout 600000
@@ -371,9 +373,9 @@ record the reason.
371
373
  ### 3.1 Per-task execution reuses the pipeline verbatim (R4)
372
374
 
373
375
  Each task runs through the **standard single-task pipeline** — `task-pipeline.yaml`
374
- — with no new FSM and no step edits. Interactive sequential omit/inline invokes the host
375
- [inline pipeline driver](inline-pipeline-driver.md), which interprets that file; explicit/parallel
376
- execution invokes the workflow engine. The batch loop inspects the result and never redefines a
376
+ — with no new FSM and no step edits. Interactive sequential omit/inline and explicit/parallel
377
+ execution both invoke the workflow engine on that file; only the executor differs (host session vs
378
+ child process). The batch loop inspects the result and never redefines a
377
379
  step.
378
380
 
379
381
  **Explicit/parallel path: launch async, then one bounded follow** (per execution-workflow.md §"Step 2"): a pipeline with
@@ -606,15 +608,15 @@ command doc so it does not read as a bug.
606
608
 
607
609
  The cheap rule gates fail fast when run first — the full-gate run is dominated by the ~65 s test
608
610
  suite, so a gate run that dies at `test-post-check` or `corpus-check` wastes most of its wall time.
609
- Before launching a full `spur-check-new`:
611
+ Before launching a full `spur-check:full`:
610
612
 
611
- 1. **Run the static checks first** — `bun run lint` (biome over the whole tree plus every workspace
613
+ 1. **Run the static checks first** — `spur self exec lint` (biome over the whole tree plus every workspace
612
614
  typecheck). They fail in ~20 s and are the two defects that most often kill a full launch: a
613
615
  formatting miss in a touched test file, or a generated declaration surface that no longer lists a
614
616
  new export. Measured 2026-10-12: two consecutive `spur-check` launches died here and each spent
615
617
  its whole wall time before reaching the suite.
616
- 2. **Then the two rule gates** — `bun run test-pre-check` (43 rules: `no-console-output`,
617
- `no-direct-process-spawn`, `cli-*`, `require-corresponding-test`) and `bun run test-post-check`
618
+ 2. **Then the two rule gates** — `spur self exec rules-pre` (43 rules: `no-console-output`,
619
+ `no-direct-process-spawn`, `cli-*`, `require-corresponding-test`) and `spur self exec rules-post`
618
620
  (`every-export-has-tsdoc`, `coverage-gate`). They catch boundary/TSDoc violations in seconds.
619
621
  Two `coverage-gate` facts change how you call post-check: it **fails closed when
620
622
  `.coverage/lcov.info` is absent**, which is the normal state of a fresh worktree, so run it after
@@ -46,14 +46,15 @@ one thing and yields, so the **pipeline (not the agent) owns the loop**.
46
46
  | Stage | Operation | Defined in |
47
47
  | ------- | ----------- | ------------ |
48
48
  | `implement` | `/sp:dev-run --mode implement <wbs>` — write the code that satisfies the task; author `## Solution`. | [dev-operations.md §4 run](dev-operations.md) → `sp:code-implementation` |
49
- | `test` → (`test-fix` ↔ `test-recheck`) → `review` \| `failed` | **Project quality gate** (not `/sp:dev-unit`). Soft shell probe of `${vars.qualityGateCmd}` (default `bun run spur-check`) — green path pays **one** full gate run. On FAIL: bounded `/sp:dev-fixall` loop (`qualityGateMaxFixAttempts`, default 2) with soft recheck; exhausted attempts route to pipeline `failed`. `/sp:dev-unit` remains **coverage gap-fill** (router C3/C5 / standalone). | [dev-operations.md §10 fixall](dev-operations.md); unit op still §1 |
49
+ | `test` → (`test-fix` ↔ `test-recheck`) → `review` \| `failed` | **Project quality gate** (not `/sp:dev-unit`). Soft shell probe of `${vars.qualityGateCmd}` (default `spur self exec check`) — green path pays **one** full gate run. On FAIL: bounded `/sp:dev-fixall` loop (`qualityGateMaxFixAttempts`, default 2) with soft recheck; exhausted attempts route to pipeline `failed`. `/sp:dev-unit` remains **coverage gap-fill** (router C3/C5 / standalone). | [dev-operations.md §10 fixall](dev-operations.md); unit op still §1 |
50
50
  | `review` | `/sp:dev-review --tasks <wbs>` — SECUA-framework review of the diff. | [dev-operations.md §2 review](dev-operations.md) |
51
51
  | `verify` | `sp:code-verification` — requirements traceability + verdict. | [dev-operations.md §3 verify](dev-operations.md) |
52
52
 
53
- Interactive omit/`inline` executes these model stages through the
54
- [inline pipeline driver](inline-pipeline-driver.md) in the host session and records stage/session
55
- provenance. The host is the controller; eligible `agent.run` stages may dispatch once to a native
56
- subagent (task 0508), with host fallback and no post-dispatch replay — see the driver reference.
53
+ Interactive omit/`inline` executes these model stages in the host session through the engine loop:
54
+ the engine owns every guard and transition, the host performs each returned work item and records
55
+ its receipt. Eligible `agent.run` stages may dispatch once to a native subagent (task 0508), with
56
+ host fallback and no post-dispatch replay — see
57
+ [cross-cutting.md](cross-cutting.md#inline-default-execution-surface).
57
58
  `--agent <name|auto>`, parallel batches, and headless workflow invocation select
58
59
  the existing subprocess actions. Direct invocations of the same dev operations remain inline by
59
60
  default. See the [inline-default execution-surface contract](cross-cutting.md#inline-default-execution-surface).
@@ -100,15 +101,15 @@ cache-conservation discipline (`plugins/sp/skills/dogfood-testing/references/mon
100
101
 
101
102
  **`--worktree [<name>]` wraps Step 2, on either surface.** When `/sp:dev-run --mode full` carries
102
103
  [`--worktree`](flag-glossary.md#flag-worktree), create or adopt the worktree *before* launching the
103
- pipeline, `cd` into it (`spur workflow run` and the inline driver both resolve cwd from the process),
104
+ pipeline, `cd` into it (`spur workflow run` and `spur workflow continue` both resolve cwd from the process),
104
105
  and merge-or-retain after the run reports. The lifecycle is
105
106
  [execution-batch.md § Worktree isolation](execution-batch.md#worktree-isolation---worktree-name)
106
107
  applied to a batch of one. Rejected with `--mode implement`.
107
108
 
108
109
  **Choose the surface before execution.** In an interactive `/sp:dev-run --mode full` invocation,
109
- omit/`--agent inline` selects the [inline pipeline driver](inline-pipeline-driver.md). Read the YAML
110
- at invocation time, allocate the inline run id/session provenance, record `task run-link`, and walk
111
- its actions/guards in declaration order. Do not call `spur workflow run` on this path. `--agent auto`,
110
+ omit/`--agent inline` selects the host executor. Start the run with `spur workflow run <file>
111
+ --vars '{"executor":"host",…}'` and advance it with `spur workflow continue <run-id> --answer-text
112
+ <receipt>`; the engine walks the YAML's actions/guards, this session never re-executes them. `--agent auto`,
112
113
  a named executor, an explicit `vars.agent`/`vars.implementAgent`, or a headless caller selects the
113
114
  workflow subprocess path below. Never fall back silently from inline to `agent.default`.
114
115
 
@@ -171,13 +172,7 @@ Two branches reach the bounded repair hop, not one (session finding after 1088):
171
172
  an on-graph, bounded path to remediation instead of dead-ending the run, and the fix re-enters
172
173
  quality → review → verify on a freshly captured proof digest.
173
174
 
174
- The completion gate reads deterministic evidence only (F511, task 1207): both `verify → record` and
175
- `record → done` check the proof digests in `.spur/run/<wbs>-verdict.json` — verdict PASS, matching
176
- run/definition digests, review stage completed. No confidence is read, stated or acknowledged; the
177
- asserted `Confidence:` line and the `ackLowConfidence` operator var were retired because a model
178
- that can write a PASS can write `HIGH` — the grade verified nothing. What protects a hand-driven
179
- `task update <wbs> done` is unchanged: the digests must match the run's captured proof, and the
180
- review stage must actually be completed in the artifact.
175
+ The completion gate reads deterministic evidence only: the review stage's **verdict artifact** (`.spur/run/<wbs>-verdict.json`, derived by `spur task verdict --from-answer`) and the **tree-hash gate receipt** (`.spur/run/<wbs>-check-receipt.json`, reused while the tree is unchanged). The ADR-071 proof chain this paragraph used to describe — proof digests, `verify → record`, review-inside-the-bracket — was deleted by the D65 pipeline rewrite; `record` now runs inside `done`'s onEnter and `verify` merged into `review`. Two grades are read, and only as cross-checks against the answer's own rows: the review answer states one `Confidence: HIGH|MEDIUM|LOW` line (ADR-141) and the review gate recomputes it from the finding dispositions, rejecting a disagreement. Nothing grades the *verifier's* opinion: an open P1–P3 finding blocks `done` on its own, and what protects a hand-driven `task update <wbs> done` is unchanged — the gate must show a PASS receipt for this tree and a recorded review artifact.
181
176
 
182
177
  Agentic steps use the pure slash inputs declared by each YAML `agent.run` action (ADR-043). The
183
178
  workflow engine dispatches them; the interactive driver invokes their backing skills in-session.
@@ -325,8 +320,8 @@ the partial work still in the working tree. The failure output names the partial
325
320
  1. **Recognise.** `.spur/memory/runs/<runId>/artifacts/<runId>-implement-partial.md` exists, the run reported `exited
326
321
  with code 3`, the task is at `todo`. The artifact's `git diff --stat` section is the partial
327
322
  work inventory.
328
- 2. **Establish green from the partial files.** `bun run format` then `bun run lint` + `bun
329
- test` (or the affected packages). Fix mechanical formatting/type fallout first; the partial
323
+ 2. **Establish green from the partial files.** `spur self exec format` then `spur self exec lint` + `spur
324
+ self exec test` (or the affected packages). Fix mechanical formatting/type fallout first; the partial
330
325
  tree is the baseline, not a code review target.
331
326
  3. **Resume the remaining requirements against that tree.** Re-run the implement step with the
332
327
  partial diff as explicit context — hand the continuation agent `git diff` (the partial
@@ -338,11 +333,25 @@ the partial work still in the working tree. The failure output names the partial
338
333
  [`done-housekeeping.md`](done-housekeeping.md) F6 — it carries the provenance obligations
339
334
  (honest `done_reason`, verdict regeneration).
340
335
 
341
- **Inline path (task 0727).** There is no `<runId>-implement-partial.md` artifact on the inline
342
- driver path — it is written only by the subprocess `agent.run` action. The inline equivalent is
343
- the dispatch-timeout contract in [`inline-pipeline-driver.md`](inline-pipeline-driver.md):
344
- resume from the partial tree, never restart the stage inline; the partial working tree is the
345
- recovery input.
336
+ **Host-executor path (task 0727).** There is no `<runId>-implement-partial.md` artifact on the
337
+ host path — it is written only by the subprocess `agent.run` action. A host-stage timeout is a
338
+ recorded stage failure: resume from the partial tree, never restart the stage inline; the partial
339
+ working tree is the recovery input.
340
+
341
+ **3a. Verify dispatch floor (task 1039).** A small, clean diff does not need a separate verify
342
+ session: when the diff is below the floor, `verify` runs host-inline in the current session and
343
+ records exactly one log line —
344
+
345
+ stage verify executed inline in session <session-id> (below dispatch floor: diffstat files <f> lines <n>)
346
+
347
+ The floor is read from the recorded diffstat artifact under `.spur/run/`; the filter that decides
348
+ it is
349
+
350
+ ([.files, .insertions, .deletions] | all(type == "number")) and .files <= 3 and (.insertions + .deletions) <= 60 and .sensitive == false
351
+
352
+ A diffstat that is missing, malformed, or names a sensitive path is never below the floor: the
353
+ floor is an optimisation, so an unreadable artifact dispatches the normal verify executor. (This
354
+ contract moved here from the retired inline driver reference, D65 1242.)
346
355
 
347
356
  **3. Match the executor to the size (task 0487 R3).** Size and executor capability are one
348
357
  decision, not two. **≥ 6 requirements or ≥ 9 Plan items → a `reviewer`-role executor (the
@@ -116,7 +116,7 @@ WT_PATH="$(cd "../<worktree-dir>" && pwd)" # hoisted: needed by WT-4a AND WT-4
116
116
  # automatically reconciles each forwarded terminal task's receiving lifecycle row in
117
117
  # the invoking tree (finalizing any stale in-flight or interrupted row left from the
118
118
  # task's creation), so a manual DB edit is never required:
119
- spur workflow inline persist-out --from "$WT_PATH" "${TASK_FILE_ARGS[@]}" \
119
+ spur workflow persist-out --from "$WT_PATH" "${TASK_FILE_ARGS[@]}" \
120
120
  || { echo "halt: worktree run-record persist-out failed - worktree retained (WT-5)" >&2; write_marker retained; exit 1; }
121
121
  #
122
122
  # WT-4b — bounded CWD-holder cleanup (task 0720 R1). $WT_PATH above is the EXACT
@@ -155,9 +155,9 @@ fi # NO prune/remove/branch delete
155
155
  # worktree while it still owns evidence absent from (or divergent from) the invoking tree —
156
156
  # the D63 landing skipped persist-out and silently lost verdicts + receipts. WBSes ride the
157
157
  # same TASK_FILE_ARGS resolved for WT-4a; run ids are a separate `--run-id <id>` per run and
158
- # belong to THIS check only — `spur workflow inline persist-out` accepts `--from` and
158
+ # belong to THIS check only — `spur workflow persist-out` accepts `--from` and
159
159
  # `--task-file` alone and exits 2 on `--run-id` (1089 driver note).
160
- spur workflow inline persist-check --from "$WT_PATH" "${TASK_FILE_ARGS[@]}" \
160
+ spur workflow persist-check --from "$WT_PATH" "${TASK_FILE_ARGS[@]}" \
161
161
  || { echo "WT-4 halt: worktree evidence would be abandoned - persist-out missing or stale (WT-5)" >&2; write_marker retained; exit 1; }
162
162
  git worktree remove "../<worktree-dir>" \
163
163
  || { echo "WT-4 halt: worktree remove failed after landed merge $BATCH_TIP" >&2; write_marker retained; exit 1; }
@@ -408,7 +408,7 @@ conflicts itself. Other halt causes (task failure, HITL pause) keep the hint as
408
408
  # (a test, a hook, a tool invocation) discards MERGE_HEAD silently. The failure is invisible
409
409
  # until the history is read — it produced a single-parent commit in run ada5a36c (task 1090),
410
410
  # which then needed an extra empty ancestry merge to repair. A cheap probe could not
411
- # reproduce it (MERGE_HEAD survived `bun run lint`, the rule preset and a test-file subset),
411
+ # reproduce it (MERGE_HEAD survived `spur self exec lint` (recorded then as the raw lint script), the rule preset and a test-file subset),
412
412
  # so the cross-command dependency is removed rather than diagnosed.
413
413
  git checkout <base-ref> && git merge --no-ff -m "<prepared message>" <branch>
414
414
 
@@ -443,7 +443,7 @@ git checkout <base-ref> && git merge --no-ff -m "<prepared message>" <branch>
443
443
  # ancestry).
444
444
 
445
445
  # 6. persist evidence out (WT-4a), then WT-4b/4c cleanup, and set the marker to merged
446
- spur workflow inline persist-out --from <worktree> --task-file …
446
+ spur workflow persist-out --from <worktree> --task-file …
447
447
  ```
448
448
 
449
449
  The report reuses the [`--next` chain contract](flag-glossary.md#--next-chain-contract) halt-report
@@ -79,8 +79,8 @@ inherits no cwd from the previous call, so "the loop runs with the worktree as p
79
79
  bootstrap convenience, never a carried guarantee. Every host command boundary in this lifecycle —
80
80
  corpus reads/writes, the WT-3b commit, WT-4's merge and evidence persistence, the WT-4a
81
81
  persist-out — re-selects its intended tree within the same call via the canonical per-call pin
82
- protocol ([inline-pipeline-driver.md](inline-pipeline-driver.md) § "Per-call execution-tree
83
- pin"): `cd --` to the quoted absolute tree, verify `pwd -P` against the recorded physical tree,
82
+ protocol ([execution-batch.md](execution-batch.md) § "Per-call execution-tree pin"):
83
+ `cd --` to the quoted absolute tree, verify `pwd -P` against the recorded physical tree,
84
84
  verify Git top-level and expected branch, then execute the already-resolved Spur invocation. The
85
85
  identity is consumed, not re-derived: it is the WT-3 marker's confirmed `path` + `branch` (or the
86
86
  resolved worktree's physical path + checked-out branch in reuse mode). The one deliberate tree
@@ -269,8 +269,8 @@ the tree's own source:
269
269
  cd "<worktree>" && bun apps/cli/src/index.ts task check <wbs> --json
270
270
 
271
271
  Run that as a per-call pin subshell (task 1058) — `cd --` plus the `pwd -P` / git-top-level /
272
- branch identity checks of the canonical protocol (inline-pipeline-driver.md § "Per-call
273
- execution-tree pin") — rather than relying on a persistent `cd` between host tool calls.
272
+ branch identity checks of the canonical protocol (execution-batch.md § "Per-call execution-tree
273
+ pin") — rather than relying on a persistent `cd` between host tool calls.
274
274
 
275
275
  Confirm isolation by making a distinctive change in the worktree and checking that
276
276
  the command reflects it.
@@ -17,7 +17,7 @@ catch it (the CLI catches schema violations, not intent errors).
17
17
  Run each checklist as an actual command sequence, not a mental confirmation:
18
18
 
19
19
  1. Read the checklist for the gate you are about to enter.
20
- 2. Run each verification command (grep, `spur task check`, `bun run lint`, etc.).
20
+ 2. Run each verification command (grep, `spur task check`, `spur self exec lint`, etc.).
21
21
  3. If any checkbox fails: stop, fix, re-run. Do not enter the gate.
22
22
  4. Only when every checkbox passes: enter the gate (run the CLI verb or trigger the workflow state).
23
23
 
@@ -89,7 +89,7 @@ Entered before `task-pipeline.yaml` `review` state dispatches `sp:code-verificat
89
89
  - [ ] The implementation matches the task's `## Plan` checklist (every checked item maps to a code/test/doc change).
90
90
  - [ ] `git status` shows only changes traceable to this task's Plan (no drive-by edits).
91
91
  - [ ] Check receipt current: `spur task gate <wbs> status` reports `reuse: true` for
92
- `.spur/run/<wbs>-check-receipt.json` at the current digest; run `bun run spur-check` only
92
+ `.spur/run/<wbs>-check-receipt.json` at the current digest; run `spur self exec check` only
93
93
  when it reports stale or missing (0940 — never re-run the full chain on a reusable receipt).
94
94
  - [ ] New `biome-ignore` / `eslint-disable` suppressions: none, or each is justified inline.
95
95
  - [ ] No new `console.*` in scripts (use a project logger if one exists).
@@ -176,9 +176,9 @@ transition to `done`.
176
176
 
177
177
  > **Finding-rule discipline (ADR-108).** When checker policy changes, run focused tests and one explicit unsuppressed `bun run corpus-check` audit; record/reconcile essential failures without waivers (T10). Ordinary corpus commit prep checks changed tasks/features and their required linked evidence, not the corpus (T11). The baseline and regenerators remain deleted; tests are not a substitute for the explicit policy-change audit.
178
178
  >
179
- > **Transition-shim discipline (`transition-shim-check`, task 0541 / ADR-058).** Wired as an early step of `spur-check` / `spur-check-new` (second, after `link-check` and before `lint`) so a shim violation fails in ~0.3 s rather than after the test run. Two-sided against `config/transition-shims.json`: an `@transition-shim(<id>)` marker with no manifest entry fails as a **new unregistered shim**, **and** a listed entry whose marker is gone from source fails as a **stale entry**. Emptying the manifest is the definition of the agent-role transition being complete. A removal condition must be objectively checkable against the repository. Shapes: `docs/04_DESIGN.md` §2.5.
179
+ > **Transition-shim discipline (`transition-shim-check`, task 0541 / ADR-058).** Wired as an early step of `spur-check-feature` (second, after `link-check`) so a shim violation fails in ~0.3 s rather than after the test run. Two-sided against `config/transition-shims.json`: an `@transition-shim(<id>)` marker with no manifest entry fails as a **new unregistered shim**, **and** a listed entry whose marker is gone from source fails as a **stale entry**. Emptying the manifest is the definition of the agent-role transition being complete. A removal condition must be objectively checkable against the repository. Shapes: `docs/04_DESIGN.md` §2.5.
180
180
 
181
- > **Sandbox test baseline (`bun run test` / `spur-check`).** In the restricted Bash sandbox
181
+ > **Sandbox test baseline (`bun run test` / `spur-check`).** In spur-new's restricted Bash sandbox
182
182
  > `bun run spur-check` exits **1 regardless of code health**: ~24 tests bind real ports and the
183
183
  > sandbox denies `listen`, so they fail environmentally. They cluster in seven suites — `spur
184
184
  > projects CLI`, `startServer`, `createServerContext`, `healthModule`, `rpc client`,
@@ -21,7 +21,7 @@ re-author the report.
21
21
 
22
22
  **Sidecar rule:** The enhanced idea does **not** overwrite `vars.idea`. Feature-create reads both
23
23
  the original idea and this report. The operator's verbatim ask of record is the run's
24
- `.spur/run/<run-id>-idea-input.md` (persisted by the pipeline `start` state / the inline driver
24
+ `.spur/run/<run-id>-idea-input.md` (persisted by the pipeline `start` state on every executor surface
25
25
  before any processing); the `## Requirement inventory` items trace back to it.
26
26
 
27
27
  ## Template
@@ -343,8 +343,26 @@
343
343
  },
344
344
  "builder": {
345
345
  "type": "object",
346
- "description": "Builder noun configuration. Currently hosts the release plumbing knobs for `spur builder bump-ver` / `drop-tags`; every field defaults to the built-in release convention, so an absent builder section keeps default behavior.",
346
+ "description": "Builder noun configuration. Hosts the release plumbing knobs for `spur builder bump-ver` / `drop-tags` and the SDLC action binding (`preset` + `actions`, ADR-139) that binds the reserved action vocabulary to this project's commands. Every field defaults to the built-in behavior, so an absent builder section keeps default behavior.",
347
347
  "properties": {
348
+ "preset": {
349
+ "type": "string",
350
+ "enum": ["bun", "none"],
351
+ "default": "bun",
352
+ "description": "Stack preset for the SDLC action vocabulary. `bun` (default) binds every reserved action to the legacy bun scripts, so a bun project needs no config change; `none` binds only the stack-neutral `spur rule run` presets (rules-pre, rules-post) and leaves every other undeclared action unbound."
353
+ },
354
+ "actions": {
355
+ "type": "object",
356
+ "default": {},
357
+ "propertyNames": { "pattern": "^[a-z][a-z0-9-]*$" },
358
+ "additionalProperties": {
359
+ "oneOf": [
360
+ { "type": "string", "minLength": 1, "pattern": "\\S" },
361
+ { "type": "array", "minItems": 1, "items": { "type": "string", "minLength": 1 } }
362
+ ]
363
+ },
364
+ "description": "Action name -> one shell command, or a list of action names (composite, executed in order, fail-fast). A declared entry replaces the preset binding whole. Reserved names (closed in packages/config): build, dev, clean, format, autofix, lint, typecheck, test, test-full, test-heavy, rules-pre, rules-post, check, check-full, check-feature, lint-changed, typecheck-changed, test-changed; other names are custom (exec-only). Placeholders are allowed only in the scoped actions, each with its own set: lint-changed {files}, typecheck-changed {workspace}, test-changed {workspace} {paths}; and each substituted item is shell-quoted."
365
+ },
348
366
  "bump-ver": {
349
367
  "type": "object",
350
368
  "description": "Release knobs for bump-ver/drop-tags. Defaults: -v separator, publish.yml workflow, chore(release) commit, gh run list limit 5.",