@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.
- package/.claude-plugin/marketplace.json +1 -1
- package/config/config.example.yaml +22 -0
- package/config/rules/boundary/config-loading-ownership.yaml +1 -1
- package/config/rules/quality/coverage-gate.yaml +2 -2
- package/config/rules/strict/runtime-boundaries.yaml +2 -2
- package/config/rules/surface/check-cli-surface.yaml +4 -0
- package/config/rules/typescript/output-boundaries.yaml +4 -10
- package/config/workflows/feature-verification.yaml +14 -5
- package/config/workflows/idea-pipeline.yaml +92 -12
- package/config/workflows/task-pipeline.yaml +456 -830
- package/config/workflows/wayfinder-resolution.yaml +20 -3
- package/config/workflows/wrapup-pipeline.yaml +22 -9
- package/package.json +1 -1
- package/plugins/sp/README.md +2 -2
- package/plugins/sp/agents/super-planner.md +2 -2
- package/plugins/sp/agents/super-reviewer.md +17 -8
- package/plugins/sp/bunfig.toml +3 -3
- package/plugins/sp/commands/dev-changelog.md +1 -1
- package/plugins/sp/commands/dev-gitmsg.md +2 -2
- package/plugins/sp/commands/dev-handover.md +1 -1
- package/plugins/sp/commands/dev-idea.md +23 -13
- package/plugins/sp/commands/dev-job-dump.md +1 -1
- package/plugins/sp/commands/dev-plan.md +17 -6
- package/plugins/sp/commands/dev-review.md +1 -1
- package/plugins/sp/commands/dev-run.md +8 -7
- package/plugins/sp/commands/dev-runall.md +1 -1
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/skills/code-implementation/SKILL.md +7 -7
- package/plugins/sp/skills/code-refactoring/SKILL.md +1 -1
- package/plugins/sp/skills/code-verification/SKILL.md +1 -1
- package/plugins/sp/skills/code-verification/references/secu-review.md +1 -1
- package/plugins/sp/skills/code-verification/references/verdict-schema.md +23 -10
- package/plugins/sp/skills/doc-evolve/SKILL.md +1 -1
- package/plugins/sp/skills/next-router/references/routing-table.md +1 -1
- package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +7 -7
- package/plugins/sp/skills/spec-decomposition/references/decomposition.md +4 -4
- package/plugins/sp/skills/spur-check/SKILL.md +9 -8
- package/plugins/sp/skills/spur-cli/SKILL.md +2 -2
- package/plugins/sp/skills/spur-cli/references/self.md +37 -2
- package/plugins/sp/skills/spur-cli/references/tasks/l3-guard-cheatsheet.md +1 -1
- package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +3 -3
- package/plugins/sp/skills/spur-cli/references/tasks.md +1 -1
- package/plugins/sp/skills/spur-cli/references/workflows.md +5 -3
- package/plugins/sp/skills/spur-dev/SKILL.md +3 -3
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +12 -11
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +15 -15
- package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +4 -3
- package/plugins/sp/skills/spur-dev/references/execution-batch-report.md +4 -4
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +13 -11
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +32 -23
- package/plugins/sp/skills/spur-dev/references/execution-worktree-landing.md +5 -5
- package/plugins/sp/skills/spur-dev/references/execution-worktree-setup.md +4 -4
- package/plugins/sp/skills/spur-dev/references/gate-checklists.md +4 -4
- package/plugins/sp/skills/spur-dev/references/idea-evaluation.md +1 -1
- package/schemas/spur-config.schema.json +19 -1
- package/spur.js +31459 -31868
- package/web/_astro/{BoardApp.BMprmPRc.js → BoardApp.Bjdp3XWV.js} +36 -36
- package/web/_astro/{BoardApp.B5rTVNd_.js → BoardApp.DCDZxLlQ.js} +1 -1
- package/web/_astro/{TaskDetail.Ddsur8qd.js → TaskDetail.B3vBxynO.js} +1 -1
- package/web/_astro/{arc.DLqVVBxP.js → arc.DcuHTB_T.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.C-Pk3uAi.js → architectureDiagram-3BPJPVTR.ClOFWBON.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.BRO1i_Nm.js → blockDiagram-GPEHLZMM.otYyr7Zb.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.BU_cWu6e.js → c4Diagram-AAUBKEIU.BCjpc9LP.js} +1 -1
- package/web/_astro/channel.qgOLXjI_.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.D2VXiQ2t.js → chunk-2J33WTMH.D5Wpnpt_.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.BcHT772J.js → chunk-4BX2VUAB.DkQGtWNz.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.DhDtICmo.js → chunk-55IACEB6.B7dqjAip.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.BoKHp7gV.js → chunk-727SXJPM.BDQvnKE2.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.Chu4JRpE.js → chunk-AQP2D5EJ.D92doBX5.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.wHdwKPlq.js → chunk-FMBD7UC4.C968oI5G.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.ffN-M1JB.js → chunk-ND2GUHAM.AkkYC1bY.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.FRubwg4S.js → chunk-QZHKN3VN.sCc-rKKo.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.c22tQsc_.js → classDiagram-4FO5ZUOK.pOQ9u0mY.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.c22tQsc_.js → classDiagram-v2-Q7XG4LA2.pOQ9u0mY.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.B9c6fiSj.js → cose-bilkent-S5V4N54A.CRaeD6FY.js} +1 -1
- package/web/_astro/{cynefin-OW5HDTMX.DrZsrUHl.js → cynefin-OW5HDTMX.BiCPBu54.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.DG1U4b3y.js → dagre-BM42HDAG.C1-q3vkT.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.CH15b-K3.js → diagram-2AECGRRQ.BSVOv30O.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.BH1j7twR.js → diagram-5GNKFQAL.CHMkjJ-V.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.q2zCkbAj.js → diagram-KO2AKTUF.CKY9M564.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.BLaaZnHV.js → diagram-LMA3HP47.B9yNJiTP.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.BcpRdQwI.js → diagram-OG6HWLK6.Dk8AUGsk.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.D7KBlqfM.js → erDiagram-TEJ5UH35.BQHR89TZ.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.D_gmuRqg.js → flowDiagram-I6XJVG4X.oNkWVgoK.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7.DzgWYniD.js → ganttDiagram-6RSMTGT7.Kz2U2nu9.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.576i3hm3.js → gitGraphDiagram-PVQCEYII.DHIZ_wPq.js} +1 -1
- package/web/_astro/{infoDiagram-5YYISTIA.DMCclBiz.js → infoDiagram-5YYISTIA.D0NJLcv9.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.9Kyca4SH.js → ishikawaDiagram-YF4QCWOH.CFEfTWRG.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.chbdG-8q.js → journeyDiagram-JHISSGLW.Dc7IE7I4.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.Bds54-e0.js → kanban-definition-UN3LZRKU.D5v0xO9k.js} +1 -1
- package/web/_astro/{linear.D5ND9GN_.js → linear.wR5KzXnE.js} +1 -1
- package/web/_astro/{mermaid.core.D9N_PGbj.js → mermaid.core.BDQ2FoPd.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.t0xop5vp.js → mindmap-definition-RKZ34NQL.W6_INsia.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.DqgKh6hM.js → pieDiagram-4H26LBE5.61ihbgkK.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.DeuHVi2t.js → quadrantDiagram-W4KKPZXB.B5lEpFLo.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.BdYFSG4W.js → requirementDiagram-4Y6WPE33.CmhVBVX0.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.k1LPPETJ.js → sankeyDiagram-5OEKKPKP.D7Vvj9Wf.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.DdyfpzoG.js → sequenceDiagram-3UESZ5HK.B1vPLixM.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.DSEI8il0.js → stateDiagram-AJRCARHV.BnACmrGi.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.CoMnQRKo.js → stateDiagram-v2-BHNVJYJU.CW4pnmc3.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.DM1AHNm-.js → timeline-definition-PNZ67QCA.CkzMCPnC.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.C-cJmVtl.js → vennDiagram-CIIHVFJN.CY4aNdAR.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.D0xMzKPb.js → wardleyDiagram-YWT4CUSO.BtoU9UFk.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.BH5xJcEq.js → xychartDiagram-2RQKCTM6._9ijUUAs.js} +1 -1
- package/web/index.html +1 -1
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +0 -997
- package/plugins/sp/skills/spur-dev/references/structured-trace-emission.md +0 -178
- package/web/_astro/channel.Bs3Illhy.js +0 -1
|
@@ -102,13 +102,13 @@ non-sandboxed shell, or a workspace that owns the storage path). The upstream fi
|
|
|
102
102
|
pi-coding-agent's storage-path resolution; it is out of scope here and recorded as motivating
|
|
103
103
|
evidence only.
|
|
104
104
|
|
|
105
|
-
## Composition with the
|
|
105
|
+
## Composition with the host executor (task 0508)
|
|
106
106
|
|
|
107
|
-
The interactive
|
|
107
|
+
The interactive host executor (`cross-cutting.md` § Inline-default execution surface) applies this
|
|
108
108
|
reference's default — native subagent first — to sequential `task-pipeline.yaml` `agent.run`
|
|
109
109
|
stages. Eligibility there is the same observable test (pure-slash action, non-interactive state,
|
|
110
|
-
native subagent with shared-worktree capability); the
|
|
111
|
-
|
|
110
|
+
native subagent with shared-worktree capability); the engine remains the authority for provenance,
|
|
111
|
+
artifact validation, and no-replay guarantees. This reference stays the authority for
|
|
112
112
|
the native-subagent versus `spur agent run` choice everywhere else.
|
|
113
113
|
|
|
114
114
|
## Fork dispatch on hosts that support it (2026-09-15 subagent-dispatch evaluation)
|
|
@@ -131,9 +131,9 @@ Three constraints keep fork honest:
|
|
|
131
131
|
adversarial panels — must NOT fork; a worker that inherits the author's reasoning grades its own
|
|
132
132
|
homework. Fork is for continuity, cold dispatch is for independence.
|
|
133
133
|
|
|
134
|
-
The
|
|
135
|
-
|
|
136
|
-
|
|
134
|
+
The engine's resume-over-re-dispatch rule (a paused run resumes with
|
|
135
|
+
`spur workflow continue` instead of re-dispatching its stage) is the same instinct one level down:
|
|
136
|
+
reuse a warm worker for continuation, dispatch fresh for judgment.
|
|
137
137
|
|
|
138
138
|
## Role propagation across fan-out (task 0551, feature I4)
|
|
139
139
|
|
|
@@ -53,10 +53,10 @@ Every batch item's hour estimate MUST also travel into the batch JSON as the ite
|
|
|
53
53
|
frontmatter, and it can be corrected later with `spur task update <wbs> --estimate-hours <n>`. The
|
|
54
54
|
estimate already exists at this point (the hour knobs were just applied above); writing it down
|
|
55
55
|
costs nothing and makes the size decision visible to later stages instead of re-derived. Its
|
|
56
|
-
primary consumer is the
|
|
57
|
-
([
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
primary consumer is the host session's dispatch floor
|
|
57
|
+
([execution-batch.md](../../spur-dev/references/execution-batch.md)): a task at or below 1 hour
|
|
58
|
+
executes its stages in the host rather than paying a subagent dispatch. An estimate left unwritten
|
|
59
|
+
forgoes that gate — the task dispatches like any large one.
|
|
60
60
|
|
|
61
61
|
### Worked example: H8's own first decomposition
|
|
62
62
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: spur-check
|
|
3
|
-
description: 'Two-tier check primitive for the sp pipeline: light (changed-scope biome, per-workspace typecheck, related tests) during development; full (
|
|
3
|
+
description: 'Two-tier check primitive for the sp pipeline: light (changed-scope biome, per-workspace typecheck, related tests) during development; full (`spur self exec check`) once at the quality boundary. Reads/writes fingerprint-bound check receipts (.spur/run/<wbs>-check-receipt.json) and reuses a PASS full receipt only at the same proof digest.'
|
|
4
4
|
license: Apache-2.0
|
|
5
5
|
version: 1.0.0
|
|
6
6
|
metadata:
|
|
@@ -34,7 +34,7 @@ gate writes a fingerprint-bound receipt that downstream stages read instead of r
|
|
|
34
34
|
| Tier | Mode | When | Scope |
|
|
35
35
|
| --- | --- | --- | --- |
|
|
36
36
|
| `light` | `spur task gate <wbs> light` | after each implement/fix edit | `bunx biome check` on the changed files (`git diff --name-only HEAD` + untracked), `bun run typecheck` per touched workspace, and related tests (`<ws>/src/**/x.ts` → `<ws>/tests/**/x.test.ts` filename mapping) run via `cd <ws> && bun test …` — never from the repo root, whose bunfig preload does not apply inside the workspace |
|
|
37
|
-
| `full` | `spur task gate <wbs> run` | once at the task quality boundary (`test`) | today's chain: `
|
|
37
|
+
| `full` | `spur task gate <wbs> run` | once at the task quality boundary (`test`) | today's chain: `spur self exec lint` + `spur self exec rules-pre` + `spur self exec test` + `spur self exec rules-post` (=`spur self exec check`), with bounded findings, SQLite-busy retry, and the `recheck` probe |
|
|
38
38
|
|
|
39
39
|
Exit contract: `run` and `recheck` return 0 on PASS and 1 on FAIL; `deferred` returns 0 on
|
|
40
40
|
DEFERRED and 1 on FAIL. `light` and `status` return 0; invalid usage returns 2. The pipeline
|
|
@@ -58,10 +58,10 @@ that soft shell wrapper does not change the standalone CLI contract.
|
|
|
58
58
|
}
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
- `inputDigest` is the
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
- `inputDigest` is the git tree the gate computes for itself (`captureGateGitTree`: `git read-tree
|
|
62
|
+
HEAD`, `git add -A` excluding `docs/tasks*` and `docs/features*`, `git write-tree` on a throwaway
|
|
63
|
+
index). The plugin never computes it and no caller supplies it — ADR-140 retired the
|
|
64
|
+
`proofDigest`/`--proof-digest` chain, so a corpus edit cannot invalidate a code PASS.
|
|
65
65
|
- `run` and `recheck` write full-tier receipts; only a PASS at the current digest is reusable. Without a digest, `run` writes no receipt and says
|
|
66
66
|
so in the gate log. The gate executes `qualityGateCmd` as one unit, so the full receipt carries a
|
|
67
67
|
single `test` row for the whole chain; `lint`, `typecheck`, `test-pre-check`,
|
|
@@ -76,7 +76,7 @@ Check `status` mode before re-running a gate. The gate ships inside the CLI (no
|
|
|
76
76
|
resolve):
|
|
77
77
|
|
|
78
78
|
```bash
|
|
79
|
-
spur task gate <wbs> status --
|
|
79
|
+
spur task gate <wbs> status --no-logo # final stdout line: {"reuse":…,"reason":…}
|
|
80
80
|
```
|
|
81
81
|
|
|
82
82
|
`reuse: true` only when the receipt is `status: PASS`, `tier: full`, and `inputDigest` equals the
|
|
@@ -105,7 +105,8 @@ preserved by construction. `recheck` stays the no-progress probe path for fix lo
|
|
|
105
105
|
## Gotchas
|
|
106
106
|
|
|
107
107
|
1. **Keep gate logic in the CLI/application owner** — plugin skills invoke `spur task gate`;
|
|
108
|
-
they do not restore a script or bundle. The
|
|
108
|
+
they do not restore a script or bundle. The gate computes its own tree identity; there is no
|
|
109
|
+
`--proof-digest` flag and no `env.proofDigest` input to supply.
|
|
109
110
|
2. **Never run light tests from the repo root** — the workspace `bunfig.toml` preload (coverage,
|
|
110
111
|
thresholds) only applies inside the workspace; `cd <ws> && bun test …` is the contract.
|
|
111
112
|
3. **Light is a filter, not a boundary** — unmapped files (root-level scripts, non-src layouts)
|
|
@@ -47,7 +47,7 @@ Pick the noun, read its reference. Each Tier A and Tier B reference owns that no
|
|
|
47
47
|
| **Tier A** | **builder** | Release/PR plumbing: `bump-ver` (including read-only `--check`), `drop-tags`, `publish`, the four flat PR verbs (`pr-status`, `pr-check`, `pr-open`, `pr-review`), and the read-only `show-branches` topology report | [references/builder.md](references/builder.md) |
|
|
48
48
|
| **Tier B** | **agent** | Coding-agent execution surface: run prompts via detected/named agents, list agent specs (incl. `agent.fleet` members), start/stop supervised processes, fleet `report`/`join`/`leave`/`wait`/`trace`, readiness check | [references/agent.md](references/agent.md) |
|
|
49
49
|
| **Tier B** | **message** | Durable inter-agent messaging: send, inbox, reply, watch | [references/message.md](references/message.md) |
|
|
50
|
-
| **Tier B** | **self** | Self-management verbs: scaffold (`init`), database maintenance (`maintain`), schema migrations (`migrate`), local web server (`serve`), status overview (`status`); `self init` runs post-scaffold validation probes & layout classification | [references/self.md](references/self.md) |
|
|
50
|
+
| **Tier B** | **self** | Self-management verbs: scaffold (`init`), project SDLC actions (`exec`), database maintenance (`maintain`), schema migrations (`migrate`), local web server (`serve`), status overview (`status`); `self init` runs post-scaffold validation probes & layout classification | [references/self.md](references/self.md) |
|
|
51
51
|
| **Tier B** | **history** | Import agent histories, aggregate forensic artifacts, render reports, and run the checkpoint-resumed daily pipeline | [references/history.md](references/history.md) |
|
|
52
52
|
| **Tier B** | **projects** | Manage the local multi-project registry and start/stop project servers | [references/projects.md](references/projects.md) |
|
|
53
53
|
| **Tier B** | **decision** | Decision-catalog transport: list visible decisions, show a served contract, run a decision to a served outcome, audit catalog health | [references/decision.md](references/decision.md) |
|
|
@@ -145,7 +145,7 @@ and spreading it; full contract in `docs/04_DESIGN.md` §1.0.1.
|
|
|
145
145
|
`inbox`, `reply`, `watch`).
|
|
146
146
|
- **[references/decision.md](references/decision.md)** - decision catalog (`list`, `show`, `run`,
|
|
147
147
|
`status`); offline by default via the built-in `typesafe` maker.
|
|
148
|
-
- **[references/self.md](references/self.md)** - `spur self init|maintain|migrate|serve|status` CLI verbs
|
|
148
|
+
- **[references/self.md](references/self.md)** - `spur self init|exec|maintain|migrate|serve|status` CLI verbs
|
|
149
149
|
(the five legacy top-level nouns remain hidden aliases). `self init` runs post-scaffold init
|
|
150
150
|
validation (Phase 1.5/1.6 probes).
|
|
151
151
|
- **[references/history.md](references/history.md)** - history import, forensic artifact analysis,
|
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: spur-cli-self
|
|
3
|
-
description: "spur-cli noun reference for `spur self`: self-management verbs — scaffold (`init`), database maintenance (`maintain`), schema migrations (`migrate`), local web server (`serve`), and status overview (`status`).
|
|
3
|
+
description: "spur-cli noun reference for `spur self`: self-management verbs — SDLC action runner (`exec`), scaffold (`init`), database maintenance (`maintain`), schema migrations (`migrate`), local web server (`serve`), and status overview (`status`). The five legacy verbs (`init`, `maintain`, `migrate`, `serve`, `status`) each mount the same command builder as their legacy top-level noun, which remains a hidden alias; `exec` has no top-level alias."
|
|
4
4
|
see_also:
|
|
5
5
|
- spur-cli
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# spur self - self-management verbs
|
|
9
9
|
|
|
10
|
-
`spur self` hosts the self-management verbs.
|
|
10
|
+
`spur self` hosts the self-management verbs. Five of them are the canonical path for a command
|
|
11
11
|
that also remains registered as a legacy top-level **hidden alias** (`spur init`, `spur maintain`, `spur migrate`,
|
|
12
12
|
`spur serve`, `spur status`) so existing scripts, workflow YAML, and habits keep working unchanged.
|
|
13
13
|
Both paths share the same command builder: identical flags, output, and exit codes. The legacy
|
|
14
14
|
top-level forms are omitted from `spur --help`, leaving `self` as the visible surface.
|
|
15
15
|
|
|
16
|
+
`exec` is the exception: it exists only as `spur self exec` — there is no `spur exec` top-level
|
|
17
|
+
alias (`spur exec <action>` is an unknown command), so nothing depends on a legacy path.
|
|
18
|
+
|
|
16
19
|
## Verb map
|
|
17
20
|
|
|
18
21
|
| Verb | Purpose | Key flags |
|
|
19
22
|
| ---- | ------- | --------- |
|
|
23
|
+
| `exec` | Run (or list) a project SDLC action bound in `builder.actions` / `builder.preset` | `--list` `--dry-run` `--json` |
|
|
20
24
|
| `init` | Scaffold a new Spur project in the current directory | `--name <name>` `--force` `--minimal` `--adopt-global-config` `--json` |
|
|
21
25
|
| `maintain` | Run database maintenance: PRAGMA optimize, WAL truncation, optional VACUUM | `--vacuum` `--json` |
|
|
22
26
|
| `migrate` | Apply CLI-owned schema migrations (or `--check` the importer schema) | `--check` `--json` |
|
|
@@ -28,6 +32,37 @@ top-level forms are omitted from `spur --help`, leaving `self` as the visible su
|
|
|
28
32
|
**[serve.md](serve.md)** owns the `serve` verb (server flags and dry-probe semantics). `migrate`
|
|
29
33
|
has no reference of its own and is documented inline below.
|
|
30
34
|
|
|
35
|
+
## `self exec` - run a project SDLC action
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
spur self exec build # run the resolved command in the project root
|
|
39
|
+
spur self exec lint -- --fix # extra args: shell-quoted and appended to a string action
|
|
40
|
+
spur self exec --list # every reserved + declared action, its source and command
|
|
41
|
+
spur self exec --list --json # machine-readable action inventory
|
|
42
|
+
spur self exec test --dry-run # print the resolved command(s), run nothing
|
|
43
|
+
spur self exec check -- --fail-on error # trailing args reach the command (composites refuse them: exit 2)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Runs one action resolved from the project's `builder` config in `.spur/config.yaml`:
|
|
47
|
+
`builder.actions.<action>` first, then the active `builder.preset` (`bun` or `none`), then the
|
|
48
|
+
stack-neutral default. The command runs through `sh -c` **in the project root** with
|
|
49
|
+
stdout/stderr inherited (stdin is not forwarded) and `SPUR_ACTION=<action>` exported to the child;
|
|
50
|
+
spur exits with the child's exit code.
|
|
51
|
+
A composite action runs its steps in order, echoes `▶ <step>` per step on stderr, and stops at the
|
|
52
|
+
first non-zero exit.
|
|
53
|
+
|
|
54
|
+
| Exit | When |
|
|
55
|
+
| ---- | ---- |
|
|
56
|
+
| child's code | the action (or the failing composite step) exited non-zero |
|
|
57
|
+
| `2` | action unbound, composite given arguments, or no action and no `--list` |
|
|
58
|
+
| `1` | unknown option (commander usage error, before the verb runs) |
|
|
59
|
+
|
|
60
|
+
`--list --json` rows are `{ name, reserved, source: config|preset|default|unbound, command | steps }`; an
|
|
61
|
+
`unbound` row carries neither `command` nor `steps`, so branch on `source`;
|
|
62
|
+
`--dry-run --json` prints `[{ name, command }]`, one object per resolved step, and runs nothing.
|
|
63
|
+
`--json` without `--list` or `--dry-run` prints a final `{ action, steps: [{ name, exitCode, durationMs }], exitCode }`
|
|
64
|
+
after the streaming output. Full surface: `docs/design/sdlc-actions.md` §3.3.
|
|
65
|
+
|
|
31
66
|
## `self init` - scaffold a Spur project
|
|
32
67
|
|
|
33
68
|
```bash
|
|
@@ -81,7 +81,7 @@ Prose-only reviews and rows containing only empty/placeholder cells do not pass.
|
|
|
81
81
|
}
|
|
82
82
|
],
|
|
83
83
|
"checks": [
|
|
84
|
-
{ "name": "lint-clean", "status": "pass", "evidence": "
|
|
84
|
+
{ "name": "lint-clean", "status": "pass", "evidence": "spur self exec lint: exit 0" }
|
|
85
85
|
],
|
|
86
86
|
"source": "spur-task-verdict"
|
|
87
87
|
}
|
|
@@ -79,7 +79,7 @@ frontmatter scalar.
|
|
|
79
79
|
- **Frontmatter** (`--feature <id>`, `--priority <p>`): sets the scalar frontmatter field on an
|
|
80
80
|
existing task — the only post-create path, allow-listed to `feature_id` / `parent_wbs` / `priority`.
|
|
81
81
|
- **Estimate** (`--estimate-hours <n>`): sets the `estimate_hours` frontmatter field (positive number) —
|
|
82
|
-
the decomposition size estimate the
|
|
82
|
+
the decomposition size estimate the host-session dispatch floor reads.
|
|
83
83
|
- **`--provenance-bypass`** (pair with `--force-done` and `--reason`): records an audited
|
|
84
84
|
provenance-bypass link when no pipeline run exists. Replaces the `SPUR_PROVENANCE_OVERRIDE` env var.
|
|
85
85
|
- **AC controls** (`--ac-altitude <graduating|task-local>`, `--ac-numbering task-local`) — independent
|
|
@@ -356,7 +356,7 @@ column to distinguish AC rows from requirement rows:
|
|
|
356
356
|
| AC | Status | Evidence Type | Evidence |
|
|
357
357
|
|----|--------|---------------|----------|
|
|
358
358
|
| AC-1 | MET | test | `tests/foo.test.ts:12` |
|
|
359
|
-
| AC-2 | MET | command | `
|
|
359
|
+
| AC-2 | MET | command | `spur self exec lint` exit 0 |
|
|
360
360
|
| AC-3 | N/A | n/a | non-behavioral — doc-only |
|
|
361
361
|
```
|
|
362
362
|
|
|
@@ -465,7 +465,7 @@ spur task resolve <file-path> [--strict] [--folder] [--json]
|
|
|
465
465
|
spur task path <wbs> [--folder] [--json]
|
|
466
466
|
spur task run-link <wbs> [--source <src>] [--run-id <id>] [--json]
|
|
467
467
|
spur task scaffold-tests <wbs> [--file <path>] [--folder] [--json]
|
|
468
|
-
spur task gate <wbs> <run|recheck|light|deferred|status> [--cmd <c>] [--probe-cmd <c>] [--
|
|
468
|
+
spur task gate <wbs> <run|recheck|light|deferred|status> [--cmd <c>] [--probe-cmd <c>] [--run-id <id>]
|
|
469
469
|
spur task residual <wbs> <scan|review-gate|fold|settle|report> [--root <dir>] [--tmp-dir <dir>] [--folder]
|
|
470
470
|
spur task diffstat <wbs>
|
|
471
471
|
```
|
|
@@ -60,7 +60,7 @@ re-reading or re-tokenizing the task.
|
|
|
60
60
|
| `run-link <wbs>` | Record pipeline run provenance link for task | `--source <src>` `--run-id <id>` `--json` |
|
|
61
61
|
| `verifyall-aggregate` | Aggregate per-task verify outcomes into a batch verdict (NOT-STARTED excluded) | `--from-file <path>` `--json` |
|
|
62
62
|
| `scaffold-tests <wbs>` | Generate BDD test stubs from task Acceptance Criteria | `--file <path>` `--folder` `--json` |
|
|
63
|
-
| `gate <wbs> <mode>` | Task-pipeline quality gate (`run`, `recheck`, `light`, `deferred`, `status`); mode-specific exits and
|
|
63
|
+
| `gate <wbs> <mode>` | Task-pipeline quality gate (`run`, `recheck`, `light`, `deferred`, `status`); mode-specific exits and git-tree-keyed receipts (see `sp:spur-check`) | `--cmd <c>` `--probe-cmd <c>` `--run-id <id>` |
|
|
64
64
|
| `residual <wbs> <step>` | F96 residual sweep step (`scan`, `review-gate`, `fold`, `settle`, `report`) | `--root <dir>` `--tmp-dir <dir>` `--folder` |
|
|
65
65
|
| `diffstat <wbs>` | Write the triage diffstat artifact against the run base (fails safe to `sensitive: true`) | — |
|
|
66
66
|
|
|
@@ -119,7 +119,8 @@ The skill's logic divides by **whether the LLM adds value**:
|
|
|
119
119
|
| `summary` | `spur workflow summary` (CLI) | `--progress <[label=]file>`… \| `--rollup <[label=]file>`… `[--transcript] [--since] [--markdown]` | Measured execution summary (per-stage time, wait, tool calls, tokens, actor split) or the batch roll-up `/sp:dev-runall` prints. `n/a` exit 0 without a transcript; exit 2 on usage or unreadable input |
|
|
120
120
|
| `profile` | `spur workflow profile` (CLI) | `<workflow> [--last n] [--window sec] [--spur-bin cmd] [--json]` | Read-only per-node step profile from `spur workflow trace` with the ADR-115 cache-window flags, for `sp:spur-doctor`. Exit 1 when a trace read fails |
|
|
121
121
|
| `cost` | `spur workflow cost` (CLI) | `[--workflow <name>]… [--by-state] [--include-bookkeeping] [--since <date>] [--budget <file>] [--measured-file <json>] [--json]` | Real terminal non-dry run measurements, or a budget result; unknown measurements stay null. Budget failures exit 1 |
|
|
122
|
-
| `
|
|
122
|
+
| `persist-out` | `spur workflow persist-out` (CLI) | `--from <worktree> [--task-file <path>]…` | WT-4 landing: copy a worktree's run rows, two-file records and cited/owned evidence into the invoking tree before teardown; exit 1 fail closed (retain the worktree) |
|
|
123
|
+
| `persist-check` | `spur workflow persist-check` (CLI) | `--from <worktree> [--task-file <path>]… [--run-id <id>]… [--root <tree>] [--success-json <path>]` | WT-4 pre-removal assertion that the worktree owns no unpersisted durable evidence; exit 0 ok / 1 blocked or divergent / 2 usage |
|
|
123
124
|
| `commit-guard` | `spur workflow commit-guard <op>` (CLI) | `start\|stage\|check --run <id> [--base <sha>] [-- <paths…>]` | Stages only paths this run wrote; exit 2 when a listed path is refused, 3 on unmerged/conflict-marked targets |
|
|
124
125
|
| `add` | agent procedure | `"<nl-description>" [--kind <state-machine\|transition-flow>] [--file <path>]` | **Mode chosen (confirmed)** → first reconciled against existing workflows (extend an existing flow rather than duplicate) → YAML authored in real schema shape → **validated AND dry-run** (reaches the expected terminal state) → [add](workflows/operations.md#add) |
|
|
125
126
|
| `refine` | agent procedure | `<workflow-file> [--intent "<goal>"] [--dry-run]` | Smallest change meeting the intent, re-validated and re-dry-run; `--dry-run` emits a diff only → [refine](workflows/operations.md#refine) |
|
|
@@ -255,7 +256,7 @@ suppression snapshot, so every finding is reported — none are suppressed.
|
|
|
255
256
|
|
|
256
257
|
**Advisory-only posture (binding):** findings never justify blocking a run, failing a gate, or
|
|
257
258
|
editing a pipeline that is currently executing. The advisory never changes `validate`'s exit status,
|
|
258
|
-
never blocks `workflow run`, and is not part of `spur-check
|
|
259
|
+
never blocks `workflow run`, and is not part of `spur-check`. Treat a finding as
|
|
259
260
|
a to-be-enhanced note for the workflow's owner — surface it in your report, apply the fix only when
|
|
260
261
|
the operator accepts it, and never hot-edit a running workflow's shell in place.
|
|
261
262
|
|
|
@@ -274,7 +275,8 @@ spur workflow progress <run-id> [--json]
|
|
|
274
275
|
spur workflow summary (--progress <[label=]file>... | --rollup <[label=]file>...) [--transcript <path>] [--since <iso>] [--markdown]
|
|
275
276
|
spur workflow profile <workflow> [--last <n>] [--window <sec>] [--spur-bin <cmd>] [--json]
|
|
276
277
|
spur workflow cost [--workflow <name>]... [--by-state] [--include-bookkeeping] [--since <YYYY-MM-DD>] [--budget <file>] [--measured-file <json>] [--json]
|
|
277
|
-
spur workflow
|
|
278
|
+
spur workflow persist-out --from <worktree> [--task-file <path>]...
|
|
279
|
+
spur workflow persist-check --from <worktree> [--task-file <path>]... [--run-id <id>]... [--root <tree>]
|
|
278
280
|
spur workflow commit-guard <op> [options]
|
|
279
281
|
```
|
|
280
282
|
|
|
@@ -98,12 +98,12 @@ run. Resume with `spur workflow continue --answer-text <answer>` — the guard a
|
|
|
98
98
|
`maxEscalations` (default 2) bounds the loop; exhausted or empty answer → `failed`. Implement only.
|
|
99
99
|
|
|
100
100
|
Full procedure: **[references/execution-workflow.md](references/execution-workflow.md)**.
|
|
101
|
-
Host
|
|
101
|
+
Host executor: `spur workflow run` with `executor=host` → work item → `spur workflow continue`.
|
|
102
102
|
|
|
103
103
|
## Bootstrap reads
|
|
104
104
|
|
|
105
105
|
Read this `SKILL.md` plus your mode's files below before the first dispatch; everything else under
|
|
106
|
-
`references/` is on demand
|
|
106
|
+
`references/` is on demand; the per-task procedure lives in `execution-workflow.md`/`execution-batch.md`
|
|
107
107
|
(budgets: `plugins/sp/tests/bootstrap-budget.test.ts`, task 1128).
|
|
108
108
|
|
|
109
109
|
- sequential-inline: `references/execution-batch.md`
|
|
@@ -131,7 +131,7 @@ reference for the half you're operating; do not duplicate its content here.
|
|
|
131
131
|
| Refine | planning | `spur task update --section` | [planning-workflow.md](references/planning-workflow.md) |
|
|
132
132
|
| Batch refine | planning | `sp:dev-refineall` → per-task `refine` | [dev-operations.md](references/dev-operations.md) § refineall · [planning-workflow.md](references/planning-workflow.md) |
|
|
133
133
|
| Task selection | execution | `spur task list` | [execution-workflow.md](references/execution-workflow.md) |
|
|
134
|
-
| Pipeline run | execution |
|
|
134
|
+
| Pipeline run | execution | `spur workflow run` / `spur workflow continue` | [execution-workflow.md](references/execution-workflow.md) |
|
|
135
135
|
| Implement (dispatch) | execution | `sp:code-implementation` | competency skill — the spine dispatches, does not inline |
|
|
136
136
|
| Test (dispatch) | execution | `sp:code-testing` | competency skill — the spine dispatches, does not inline |
|
|
137
137
|
| Review / verify (dispatch) | execution | `sp:dev-review` → `sp:code-verification` + `sp:functional-review` + `sp:code-improvement` | competency skills — the spine dispatches, does not inline |
|
|
@@ -110,9 +110,10 @@ inside that subprocess boundary runs its backing skill in that process; it must
|
|
|
110
110
|
|
|
111
111
|
**Pipeline wrappers (`dev-run`, `dev-runall`, `dev-idea`, `dev-plan`)** — the orchestrator is a loop; its *stages* do the
|
|
112
112
|
model-bearing work. Interactive omit/`inline` therefore uses the
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
113
|
+
engine loop: `spur workflow run <file> --vars '{"executor":"host",…}'` executes every guard and
|
|
114
|
+
deterministic action on the engine and pauses with one work item per model stage, which this session
|
|
115
|
+
performs through the backing skill before `spur workflow continue <run-id> --answer-text <receipt>`
|
|
116
|
+
advances the run. `auto` or a named executor is merged into per-task `vars.agent` and
|
|
116
117
|
`vars.implementAgent`, and the workflow's `agent.run` steps run under that subprocess executor (see
|
|
117
118
|
`execution-batch.md` § 3.2). The loop itself continues in the current session.
|
|
118
119
|
|
|
@@ -139,8 +140,8 @@ native subagent with shared-worktree read/write/shell capability, and a task abo
|
|
|
139
140
|
(`.spur/run/<wbs>-diffstat.json`, verify only) keeps that stage host-inline (2026-09-15
|
|
140
141
|
subagent-dispatch evaluation; the floor and the
|
|
141
142
|
resume-over-re-dispatch rule for worker-role continuation stages are owned by
|
|
142
|
-
[
|
|
143
|
-
native subagent and joins before the
|
|
143
|
+
[cross-cutting.md](#inline-default-execution-surface)) — dispatches **once** to that
|
|
144
|
+
native subagent and joins before the host reports the work-item receipt; any pre-dispatch eligibility failure falls
|
|
144
145
|
back to one host execution, and a failure after dispatch follows the stage's error policy with no
|
|
145
146
|
automatic host replay. Inline resolution (omitted or explicit, 0687 R1/R2) keeps the native-subagent
|
|
146
147
|
leg for eligible stages. Operator
|
|
@@ -238,13 +239,13 @@ Inline avoids process startup and preserves the host session's context and tools
|
|
|
238
239
|
subprocess dispatch it provides **no isolated workspace**, **no per-stage subprocess action
|
|
239
240
|
record**, **no independent timeout or abort boundary**, and **no tier-selected executor**: the
|
|
240
241
|
executor is the current coding agent. Interactive pipelines retain a run log and session provenance
|
|
241
|
-
through the
|
|
242
|
+
through the host executor; task pipelines additionally record a task run-link. If process isolation or an independently killable
|
|
242
243
|
stage is required, select the subprocess path (`--agent auto` or `--agent <name>`).
|
|
243
244
|
|
|
244
245
|
## Shared startup contract (task 0814 R1/R3/R4/R6/R7/R8)
|
|
245
246
|
|
|
246
247
|
The workflow-backed dev commands (`dev-run`, `dev-runall`, `dev-refineall`, `dev-verifyall`) share one
|
|
247
|
-
startup order. The order is load-bearing and applies on both the
|
|
248
|
+
startup order. The order is load-bearing and applies on both the host executor and the subprocess
|
|
248
249
|
path. Runs that resolve a workflow definition publish the generated plan as their first action
|
|
249
250
|
(1105 R1); skill-only operations (refine/verify batches with no nested workflow) display their owned
|
|
250
251
|
procedure and do not fabricate a workflow YAML.
|
|
@@ -495,8 +496,8 @@ them; they live here because they cross every phase boundary.
|
|
|
495
496
|
skill, no `/sp:prd-*` commands, no `sp:super-pm` agent — unless a later task proves a stable,
|
|
496
497
|
distinct routing value (ADR-022).
|
|
497
498
|
7. **NEVER claim completion without fresh verification evidence.** "Tests pass" must be backed by
|
|
498
|
-
the actual `
|
|
499
|
-
`
|
|
499
|
+
the actual `spur self exec test` tail pasted into the record. "Lint clean" must be backed by
|
|
500
|
+
`spur self exec lint` output. Stale evidence from a prior run is not evidence — re-run the gate and
|
|
500
501
|
paste the current output.
|
|
501
502
|
|
|
502
503
|
## Verification Before Completion
|
|
@@ -570,7 +571,7 @@ does not earn another full-gate run:
|
|
|
570
571
|
final gate.
|
|
571
572
|
3. **Red alone**, or a failure that is not a timeout → it is a real failure. Fix it.
|
|
572
573
|
4. Give the test an explicit per-test timeout and a WHY comment (see
|
|
573
|
-
`plugins/sp/tests/
|
|
574
|
+
`plugins/sp/tests/helpers/cli-surface.test.ts:81`) as soon as EITHER (a) the same test
|
|
574
575
|
load-flakes in two separate runs, OR (b) it times out once **outside the change scope** and then
|
|
575
576
|
passes green alone on three consecutive isolated reruns. **Prefer making the test cheap or
|
|
576
577
|
hermetic first** — a test that hashes the live checkout transitively, or writes a probe file into
|
|
@@ -594,7 +595,7 @@ principles determine which gates route around HITL and which still pause.
|
|
|
594
595
|
pausing. The schema is the contract; schema-valid means structurally sound.
|
|
595
596
|
2. **Gate-passed → auto-continue.** If `spur task check`, `spur feature check`, or
|
|
596
597
|
`spur workflow validate` exits 0, the run continues to the next state without surfacing.
|
|
597
|
-
3. **Tests-green → auto-continue.** If `
|
|
598
|
+
3. **Tests-green → auto-continue.** If `spur self exec lint` and `spur self exec test` exit 0, the verify step
|
|
598
599
|
continues. A red test suite is a hard stop, not an auto-retry.
|
|
599
600
|
4. **Verdict-PASS → auto-continue.** If the verify step produces a PASS verdict, the run advances
|
|
600
601
|
to `record` and `done`. PARTIAL or FAIL verdicts surface to the operator regardless of `--auto`.
|
|
@@ -76,7 +76,7 @@ each would be scope creep for one-liner procedures.
|
|
|
76
76
|
| 4 | run | `dev-run` | `Skill()` | `sp:spur-dev` (`run` / `implement`) | `<wbs> [--mode <full\|implement>] [--agent <inline\|auto\|name>] [--auto] [--next] [--wrap] [--continue] [--worktree [<name>]] [--no-summary]` |
|
|
77
77
|
| 5 | refine | `dev-refine` | `Skill()` | `sp:spur-dev` (`refine`) | `<wbs> [--focus <mode>] [--description <text>] [--depth <standard\|ready>] [--agent <inline\|auto\|name>] [--auto] [--next]` |
|
|
78
78
|
| 5a | refineall | `dev-refineall` | `Skill()` | `sp:spur-dev` (`refineall`) | `--feature <id> \| --tasks <selector> [--focus <mode>] [--description <text>] [--depth <standard\|ready>] [--agent <inline\|auto\|name>] [--auto] [--keep-going] [--status <s>] [--json] [--worktree [<name>]]` |
|
|
79
|
-
| 6 | plan | `dev-plan` | `Skill()` |
|
|
79
|
+
| 6 | plan | `dev-plan` | `Skill()` | host executor (`idea-pipeline`) or async workflow | `"<description>" [--feature <id>] [--parent <feature-id>] [--skip-design] [--agent <inline\|auto\|name>] [--auto]` |
|
|
80
80
|
| 7 | docs | _(no thin wrapper)_ | `Skill()` | `sp:doc-evolve` | `"<change description>"` |
|
|
81
81
|
| 8 | changelog | `dev-changelog` | `inline` | git log + conventional-commit grouping | `[<file>] [--since <ref>] [--until <ref>] [--version <ver>]` |
|
|
82
82
|
| 9 | gitmsg | `dev-gitmsg` | `inline` | bounded diff capture → concern grouping → conventional commit | `[--commit] [--squash] [--all] [--scope <path>] [--check <cmd>]` |
|
|
@@ -89,7 +89,7 @@ each would be scope creep for one-liner procedures.
|
|
|
89
89
|
| 13 | runall | `dev-runall` | `Skill()` → agent | `sp:spur-dev` (`runall`) → `sp:super-planner` | `--tasks <selector> [--feature <id>] [--mode <sequential\|parallel\|auto>] [--concurrency <n>] [--keep-going] [--auto] [--agent <inline\|auto\|name>] [--json] [--wrap] [--next] [--continue] [--worktree [<name>]] [--no-summary] [--defer-gate]` |
|
|
90
90
|
| 14 | wrap | `dev-wrap` | `Skill()` | `spur workflow run` (wrapup-pipeline) | `<wbs> [--agent <inline\|auto\|name>] [--auto] [--merge] [--dry-run]` |
|
|
91
91
|
| 15 | wrapall | `dev-wrapall` | `Skill()` | `spur workflow run` (wrapup-pipeline) | `[--since <iso>] [--feature <id>] [--status <s>] [--agent <inline\|auto\|name>] [--auto] [--merge] [--dry-run]` |
|
|
92
|
-
| 16 | idea | `dev-idea` | `Skill()` |
|
|
92
|
+
| 16 | idea | `dev-idea` | `Skill()` | host executor (`idea-pipeline`) or async workflow | `"<idea>" \| --from-file <path> [--skip-design] [--agent <inline\|auto\|name>] [--auto]` |
|
|
93
93
|
| 17 | refactor | `dev-refactor` | `Skill()` | `sp:code-refactoring` skill (thin wrapper, ADR-032) | `[<description>] [--scope <path>] [--focus <api\|architect\|tests\|ui\|auto>] [--fix <none\|blockers-first\|all>] [--check <cmd>] [--agent <inline\|auto\|name>] [--auto]` |
|
|
94
94
|
|
|
95
95
|
## Skill-backed operations
|
|
@@ -159,13 +159,13 @@ must not be changed without updating the backing skill.
|
|
|
159
159
|
- **Inputs:** `<wbs>` (required). `--mode <full|implement>` selects the execution mode. `implement` invokes `sp:code-implementation` inline by default. Interactive `full` resolves the selector uniformly (task 0687): omit ≡ explicit `--agent inline`; full mode reads `task-pipeline.yaml` and drives its actions/guards in the host session — host-controlled and non-subprocess, with 0508 eligibility applying to the resolved-inline selector (eligible `agent.run` stages dispatch once to a native subagent, host fallback)). `--agent auto`, a name, or headless invocation launches the workflow subprocess. `--agent <inline|auto|name>` selects the execution surface (see [SSOT](cross-cutting.md#inline-default-execution-surface)). `--auto` skips the HITL approve gate / confirmations and propagates down the `--next` chain. `--next` controls chaining only and never changes the mode; a pipeline implement stage must invoke `/sp:dev-run <wbs> --mode implement`. On implement success with `--next`, transition `todo → wip → testing` through the FSM (guards honored — no `--no-lifecycle`) + chain to `/sp:dev-verify <wbs> --auto --next`. On a guard failure, stop as review-pending. **Partial-deliverable rule:** if the task ships only part of its requirements (e.g. an R1/R2 split with the rest in a follow-up task), the `## Solution` section must state that explicitly and the verify verdict will record the scope. `--worktree [<name>]` runs the full pipeline inside an isolated git worktree (create or reuse; FF-merge on success, retain on failure) — the batch lifecycle in [execution-batch.md § Worktree isolation](execution-batch.md#worktree-isolation---worktree-name) applied to a batch of one; rejected with `--mode implement`. `--no-summary` skips the [execution summary](#execution-summary) printed after a full-mode run. `--wrap` hands off to `/sp:dev-wrap <wbs>` after the main step; the `--agent` selector is preserved into that handoff when supplied (omission remains omission), and the wrap hop reports its own trigger-3 subprocess override per the wrap contract.
|
|
160
160
|
- **Backing:** `sp:spur-dev` skill — `run` operation for the full pipeline (the spine drives it); `sp:code-implementation` competency skill for the implement step (the spine dispatches to it).
|
|
161
161
|
- **Modes:**
|
|
162
|
-
- **`full`** (default): Drive the full pipeline — precheck → implement → test → review → approve(HITL) → verify → record → done. Interactive omit/inline
|
|
162
|
+
- **`full`** (default): Drive the full pipeline — precheck → implement → test → review → approve(HITL) → verify → record → done. Interactive omit/inline runs `spur workflow run task-pipeline.yaml --vars '{"wbs":"<wbs>","executor":"host"}'` and performs each returned work item (eligible stages may use a native subagent); explicit/headless executor selection runs the same definition without the `executor` var (with `profile: auto` when `--auto`). Both monitor/surface HITL and preserve the YAML gates. `--next` never changes this mode.
|
|
163
163
|
- **`implement`** (explicit `--mode implement` only): Execute only the implement step. Read the task's `## Requirements` / `## Design` / `## Plan`, write the code that satisfies them, author the `## Solution` change-map section (file:line + what/why per changed file) via `spur task update <wbs> --section Solution --from-file`. This is the implement step the pipeline calls — it is NOT the pipeline driver. With `--next`: on success, transition `todo → wip → testing` through the FSM (guards honored — no `--no-lifecycle`) + chain to `/sp:dev-verify <wbs> --auto --next`; on a guard failure, stop as review-pending. **Partial-deliverable rule:** if the task ships only part of its requirements (e.g. an R1/R2 split with the rest in a follow-up task), the `## Solution` and `## Review` sections MUST carry a `⚠️ PARTIAL` marker naming the deferred part and the follow-up WBS — see `plugins/sp/commands/dev-run.md` → "Section ownership".
|
|
164
|
-
- **Delegation:** `Skill(skill="sp:spur-dev", args="run
|
|
164
|
+
- **Delegation:** `Skill(skill="sp:spur-dev", args="run $ARGUMENTS")` for both full-mode paths (the `executor` var picks host session vs child process); `Skill(skill="sp:code-implementation", args="$ARGUMENTS")` for implement mode.
|
|
165
165
|
|
|
166
166
|
#### Execution summary
|
|
167
167
|
|
|
168
|
-
Produced by the run's own close (1146 R1), not by a trailing step:
|
|
168
|
+
Produced by the run's own terminal close (1146 R1), not by a trailing step: the close writes
|
|
169
169
|
`.spur/run/<runId>-summary.md` + `.json` and reports `summaryFile` in its stdout JSON. The driver's only
|
|
170
170
|
job is to print that file's contents under an `### Execution summary` heading, and to pass `--no-summary`
|
|
171
171
|
through to `inline close`. `--no-summary` is an `inline close` flag: anywhere else it is a usage error.
|
|
@@ -537,9 +537,9 @@ gate commands, pending questions and approval requirements.>
|
|
|
537
537
|
`--from-file` contents) unmodified to `.spur/run/<run-id>-idea-input.md` (0887 R1); the precheck
|
|
538
538
|
fails the run when that file is empty or missing, and every model-bearing stage prompt treats
|
|
539
539
|
it as the authoritative ask (R2).
|
|
540
|
-
- **Backing:** `idea-pipeline.yaml`
|
|
540
|
+
- **Backing:** `idea-pipeline.yaml` on the host executor (`vars.executor: host`, advanced by `spur workflow continue`) for omitted/`inline`, or `spur workflow run idea-pipeline.yaml --async` for `auto`/name.
|
|
541
541
|
- **Behavior:** Builds vars from the table above and drives the idea pipeline. Flow: discovery → **idea-eval** (taste; reject → cancelled) → feature-create → ac-generate → feature-check → system-design (conditional) → design-approval (taste) → decompose → batch-create (`--skip-ready`) → ready-prepare (ready checklist per created task + ready-evidence sidecar, 0788) → handoff. STOPS at handoff — no task execution, no pipeline nesting. Headless runs use one `trace --follow`; cancellation is reported stopped only when `workflow cancel --json` returns `killed: true`.
|
|
542
|
-
- **Delegation:** Host
|
|
542
|
+
- **Delegation:** Host executor (this session answers each work item) by default; explicit executor selection uses the async workflow worker.
|
|
543
543
|
- **Idea-evaluation gate:** After discovery, operator reviews `.spur/run/idea-eval-report.md` ([idea-evaluation.md](idea-evaluation.md)). Approve continues; reject/cancel → no feature. Under `--auto`, follows the report's recommendation (`drop` → cancelled; missing recommendation → pauses). Enhanced idea is a sidecar — `vars.idea` is not overwritten.
|
|
544
544
|
- **Design package (`--skip-design` only):**
|
|
545
545
|
|
|
@@ -551,7 +551,7 @@ gate commands, pending questions and approval requirements.>
|
|
|
551
551
|
Ties lean design — when the signal is ambiguous, `system-design` runs. Task Design defaults on
|
|
552
552
|
unless `--skip-design`. Plan path uses the same package contract (no `--design` force flag).
|
|
553
553
|
|
|
554
|
-
- **Operator gates:** every pause is one `AskUserQuestion` [decision brief](decision-brief.md) — recommended option first; see the gate table in `commands/dev-idea.md` and the `hitl.confirm` rule in [
|
|
554
|
+
- **Operator gates:** every pause is one `AskUserQuestion` [decision brief](decision-brief.md) — recommended option first; see the gate table in `commands/dev-idea.md` and the `hitl.confirm` rule in [execution-workflow.md](execution-workflow.md).
|
|
555
555
|
|
|
556
556
|
### 17. refactor
|
|
557
557
|
|
|
@@ -568,7 +568,7 @@ gate commands, pending questions and approval requirements.>
|
|
|
568
568
|
These define their procedure directly in the command file. No `Skill()` delegation — the command
|
|
569
569
|
is the procedure. The backing is a combination of git CLI, `spur` CLI, and agent reasoning.
|
|
570
570
|
|
|
571
|
-
**Gate ownership.** A project quality gate (`
|
|
571
|
+
**Gate ownership.** A project quality gate (`spur self exec autofix|check|lint`, typecheck, tests,
|
|
572
572
|
rule runs) runs only where an operation's own contract names it: the pipeline `test` hop
|
|
573
573
|
(`run`/`runall`), `fixall`, `gtd`, `fixgha`, `unit`, and the `--check <cmd>` loops. The scribe
|
|
574
574
|
operations — `changelog`, `gitmsg`, `handover`, `job-dump` — produce text or a commit, not code, so
|
|
@@ -595,7 +595,7 @@ host instructions does not add one. An opt-in gate is explicit: `gitmsg --check
|
|
|
595
595
|
- **Defect precision decides what must be fixed.** The check is precise once a bullet is classified as a claim: an annotation missing its anchor is unambiguously wrong and blocks emitting. A summary broader than its evidence is reworded to what the anchor shows. Which bullets *are* claims is the heuristic half — resolve it by this step's rule, and for a genuinely borderline bullet say so in the bullet's body rather than annotating or skipping it silently.
|
|
596
596
|
8. Self-check before emitting: every short hash in `<since>..<until>` appears exactly once, and every claim bullet carries exactly one `<!-- src: … -->` comment holding exactly one anchor — no unannotated claim bullets, no duplicate annotations. Fix any miss or duplicate; do not report a verdict.
|
|
597
597
|
9. Reply in at most three lines: the range, bullet counts per category plus the verified-claim count, and the output target.
|
|
598
|
-
- **Invariants:** Bullets are derived from `git log` only; the claim-verification pass (step 7) adds evidence from commit diffs, the working tree, and official docs. No quality gates — no `
|
|
598
|
+
- **Invariants:** Bullets are derived from `git log` only; the claim-verification pass (step 7) adds evidence from commit diffs, the working tree, and official docs. No quality gates — no `spur self exec autofix|check|lint` and no typecheck, test or rule run, and no edits beyond the one inserted section (its verification comments included). The file is left uncommitted.
|
|
599
599
|
|
|
600
600
|
### 9. gitmsg
|
|
601
601
|
|
|
@@ -678,7 +678,7 @@ host instructions does not add one. An opt-in gate is explicit: `gitmsg --check
|
|
|
678
678
|
|
|
679
679
|
Hooks stay enabled; a failing hook stops the run with its output — never `--no-verify`.
|
|
680
680
|
|
|
681
|
-
- **Invariants:** Git and POSIX shell only — no helper script, no temp file. At most two Bash calls: gather, then (only when committing) commit — three with `--check`. No quality gate (`
|
|
681
|
+
- **Invariants:** Git and POSIX shell only — no helper script, no temp file. At most two Bash calls: gather, then (only when committing) commit — three with `--check`. No quality gate (`spur self exec autofix|check|lint`, typecheck, tests) unless `--check` names one. With neither `--commit` nor `--squash`, never runs `git commit` — message only. Neither flag commits across a secret hit, and `--commit` never splits across a partial staging. Without `--all` the change set is the index, so plain `/sp:dev-gitmsg` keeps pre-commit semantics; only `--all` reaches unstaged and untracked files, and only a committing run stages them. The empty-index widen is read-only and always announced — a committing run never widens its own scope. An explicit `--scope <path>` always bounds the change set, with or without `--all`. One bounded, context-free capture per run — never a second, wider read.
|
|
682
682
|
|
|
683
683
|
### 10. fixall
|
|
684
684
|
|
|
@@ -686,16 +686,16 @@ host instructions does not add one. An opt-in gate is explicit: `gitmsg --check
|
|
|
686
686
|
- **Inputs:** `--scope <path>` (default: entire working tree) — limits fixes to a file or directory. `--gate-log <path>` (R3, task 0482) — before fixing, read this captured validation-run log and start at the `file:line` anchors its findings name, rather than re-deriving the failure from a fresh gate run. `--findings <anchors>` (R3, task 0482) — space-separated `file:line` anchors already extracted from that log by the `test` hop; when present these ARE the failing set, so fix them in order and do not run the gate to discover what broke.
|
|
687
687
|
- **Backing:** `inline` — lint + test fix loop.
|
|
688
688
|
- **Behavior:** 0. **Start at the anchors, never at a discovery run.** If `--findings <anchors>` is given, that space-separated `file:line` list IS the failing set — open those locations first, in order, and fix them; do not run the gate to find out what broke. If only `--gate-log <path>` is given, read that log first and identify the failing findings (lint/test errors with their `file:line` anchors) before running the loop — the captured log is the authoritative source. Either way the first action of this hop is a read, not a gate run (R3, task 0482).
|
|
689
|
-
1. Inspect the project's formatter command, then settle formatter-only diffs. Without `--scope`, use the project formatter (here `
|
|
690
|
-
2. Run the project's read-only lint/type check (here `
|
|
689
|
+
1. Inspect the project's formatter command, then settle formatter-only diffs. Without `--scope`, use the project formatter (here `spur self exec format`). With `--scope`, use a formatter invocation whose only path operands are inside the selected scope — for Biome, `bunx biome check --write "$SCOPE"`. Never append a path to a script already containing `.`: `biome check . --write <path>` still writes across the repository. Preserve quoted paths and apply the same scope to every later formatting pass. If no scoped formatter is available, report that limitation and leave out-of-scope files untouched. Here `spur self exec lint` checks formatting without rewriting it and also runs typecheck; formatting errors fail that check.
|
|
690
|
+
2. Run the project's read-only lint/type check (here `spur self exec lint`). Collect all errors. A repository-wide check may report outside-scope errors; report them without widening the authorized fix scope.
|
|
691
691
|
3. **Surface-change sweep (before any fix).** If the failing set is a **surface/parity** change — CLI noun/verb/flag surface, reference-file structure, or a renamed/moved symbol — do one upfront `rg` sweep across ALL test dirs + docs for stale references to the changed symbols (e.g. `rg -l "<old-noun>|<old-file>.md|Tier C" apps/*/tests plugins/sp/tests plugins/sp/skills docs`), and fix every in-scope pinned test/docs file in that sweep; report outside-scope matches without editing them. A surface change is pinned in **multiple independent test files** (each with its own hardcoded noun→reference map); discovering them one-by-one via full-suite probes is the dominant waste — each wave costs a suite run and a fresh edit loop (task 0436 R2 lesson). One sweep produces the complete edit set upfront.
|
|
692
692
|
4. If lint is clean, skip to step 6.
|
|
693
693
|
5. **Lint fix loop:** for each in-scope error, diagnose the root cause and apply the smallest fix. **Use targeted probes to verify each fix** (`bunx tsc --noEmit` on the affected package, `bunx biome check <file>`) — do NOT re-run the full gate after every batch. Loop until lint is green, or report outside-scope blockers without editing them.
|
|
694
694
|
6. For standalone execution, run `bun run test` and collect all failures. With `--gate-log`, use its failing set and targeted tests instead of running the full suite here.
|
|
695
695
|
7. If tests are green, proceed to the applicable standalone confirmation or pipeline handoff below.
|
|
696
696
|
8. **Test fix loop:** for each in-scope failure, diagnose (test bug vs implementation bug), apply the fix, re-run the **failing test only** (`bun test <file> --test-name-pattern "<test>"`). Report outside-scope blockers without editing them. Do NOT re-run the full suite per fix — it is the dominant loop cost (task 0436 R2).
|
|
697
|
-
9. **Confirming run — standalone invocation only (at most once).** After all fixes, repeat the scope-safe formatting invocation from step 1, then run the selected validation command **at most once** to confirm (here the default project gate is `
|
|
698
|
-
10. **Pipeline-awareness (R4, task 0483; confirming run dropped 2026-08-31).** `--gate-log` is set only by the pipeline's `test-fix` hop, so treat it as the pipeline signal. There, `test-recheck` runs the full `${vars.qualityGateCmd}` gate immediately after this hop returns — that is the **deciding** run, the only one that writes PASS to `.spur/run/<wbs>-test-gate.status`. A confirming run inside this hop decides nothing and costs a second full gate (~105 s here) to answer a question `test-recheck` is about to answer anyway. So under `--gate-log`: **run no full gate at all.** Your self-check is what step 8 already gives you — the failing tests you re-ran individually — plus **one `
|
|
697
|
+
9. **Confirming run — standalone invocation only (at most once).** After all fixes, repeat the scope-safe formatting invocation from step 1, then run the selected validation command **at most once** to confirm (here the default project gate is `spur self exec check`). If it passes, the hop is done. **Skip this step entirely when `--gate-log` is set** (see step 10) — under the pipeline nothing consumes its verdict.
|
|
698
|
+
10. **Pipeline-awareness (R4, task 0483; confirming run dropped 2026-08-31).** `--gate-log` is set only by the pipeline's `test-fix` hop, so treat it as the pipeline signal. There, `test-recheck` runs the full `${vars.qualityGateCmd}` gate immediately after this hop returns — that is the **deciding** run, the only one that writes PASS to `.spur/run/<wbs>-test-gate.status`. A confirming run inside this hop decides nothing and costs a second full gate (~105 s here) to answer a question `test-recheck` is about to answer anyway. So under `--gate-log`: **run no full gate at all.** Your self-check is what step 8 already gives you — the failing tests you re-ran individually — plus **one `spur self exec lint`** (~7 s: Biome + typecheck) to catch type or lint breakage your fixes introduced. Then return and let `test-recheck` judge. `test-recheck` opens with the same cheap `${vars.gateProbeCmd}` probe, so a still-red tree is caught in seconds rather than by a full suite. Historical anti-pattern this replaces: 0482 ran the gate 3× plus a standalone `bun run test`, and `test-recheck` then ran it a 5th time.
|
|
699
699
|
11. Report: list what was fixed (file + one-line summary per fix). If any error could not be resolved, report it explicitly — do not suppress.
|
|
700
700
|
- **Invariants:** Never bypass with `--no-verify`, `--force`, or new `biome-ignore`/`eslint-disable` suppressions. Never skip or `.skip` a test to make the suite green. Fix the root cause, not the symptom. Here lint checks formatting and types; it does not prove that the full test gate passed. Keep every write inside `--scope`. **Never re-run the full gate more than once per confirming pass** (R4) — use targeted probes during the fix loops and let the pipeline's `test-recheck` state be the deciding run.
|
|
701
701
|
- **MANDATORY Exit Condition — standalone only.** At step 9, execute the following once; do not add another confirming run:
|
|
@@ -45,7 +45,8 @@ run-id) or you walked it manually (name the gate you checked).
|
|
|
45
45
|
Threshold is by **change type**, not priority: a task is high-stakes if it touches code, tests, or
|
|
46
46
|
shared infrastructure. Priority (P1/P2) is advisory - it does not by itself force raw paste on a
|
|
47
47
|
pure doc/markdown edit. For high-stakes tasks, paste the **raw tail output** of every verification
|
|
48
|
-
gate that applies - not a one-line "green" summary. Include
|
|
48
|
+
gate that applies - not a one-line "green" summary. Include the tails of spur-new's own gate
|
|
49
|
+
scripts (any other project: the same actions through `spur self exec lint` / `test`):
|
|
49
50
|
|
|
50
51
|
- `bun run lint` tail (last 20 lines minimum)
|
|
51
52
|
- `bun run test` tail (last 20 lines minimum)
|
|
@@ -92,8 +93,8 @@ spur workflow trace <run-id> # confirm the terminal state
|
|
|
92
93
|
has verified the tree. You must:
|
|
93
94
|
|
|
94
95
|
```bash
|
|
95
|
-
|
|
96
|
-
|
|
96
|
+
spur self exec lint
|
|
97
|
+
spur self exec test
|
|
97
98
|
```
|
|
98
99
|
|
|
99
100
|
Both must pass before you go further. Establish the environmental baseline first if you are in a
|
|
@@ -85,14 +85,14 @@ batch can never destroy its own evidence. Reuse mode retains its operator-owned
|
|
|
85
85
|
persists the Step 5 report under the invoking tree; the reused tree's `.spur/run/` remains the live
|
|
86
86
|
copy while that tree lives on. The per-run provenance — the worktree DB's run/action rows and the
|
|
87
87
|
`.spur/memory/runs/<runId>.md` + `.state.json` records — is persisted mechanically by WT-4a's
|
|
88
|
-
`spur workflow
|
|
88
|
+
`spur workflow persist-out --from <worktree> [--task-file <merged-task>]...` call,
|
|
89
89
|
not by hand.
|
|
90
90
|
|
|
91
91
|
**Stage records are worktree-local too (0948 R9, E7 Finding 5; persisted by 0975 R1).** Each task's
|
|
92
92
|
own per-stage run record (`.spur/memory/runs/<runId>.md` + `.state.json`) and the worktree DB's run rows are
|
|
93
93
|
written inside the worktree and **are removed with it** in create mode — the E7 batch lost exactly
|
|
94
94
|
this evidence. Copying them out is no longer a manual audit-time duty: WT-4a (create-mode block
|
|
95
|
-
below) runs `spur workflow
|
|
95
|
+
below) runs `spur workflow persist-out --from "$WT_PATH"` **before** WT-4b holder cleanup,
|
|
96
96
|
which copies the run/action/phase/transition/workflow-state rows and both record files into the
|
|
97
97
|
invoking tree.
|
|
98
98
|
|
|
@@ -106,7 +106,7 @@ obligation; neither do root-qualified paths (`knowledge-kit/.spur/run/…`, `/ab
|
|
|
106
106
|
which cite another project's evidence — cite foreign run artifacts that way, never bare. A citation missing in BOTH trees, a divergent cited file (never overwritten — reconcile
|
|
107
107
|
by hand), an unreadable task file, or more than 64 distinct cited files fails the pass → WT-5.
|
|
108
108
|
|
|
109
|
-
**Durable planes ride it too (E71).** Persist-out copies canonical task verdicts, feature run/latest receipts, nested run artifacts and owned sessions before teardown. Artifact and task-run-link rows are exported with run rows, and stored path references are redirected to the invoking tree. Conflicting or unreadable **owned** retained evidence refuses teardown. A divergent copy of evidence a forwarded task does **not** own (its WBS is not a forwarded task's and its receipt `runId` is not a worktree run row) is `foreign-divergent` (1139 R5): it is skipped, reported as `evidenceSkipped[{name, reason:'foreign-divergent', newer:'invoking'|'worktree'}]`, and the invoking-tree copy is never overwritten — another task's newer verdict can no longer block this batch's teardown. A divergent **owned** file still fails with `durable evidence conflicts`. `spur workflow
|
|
109
|
+
**Durable planes ride it too (E71).** Persist-out copies canonical task verdicts, feature run/latest receipts, nested run artifacts and owned sessions before teardown. Artifact and task-run-link rows are exported with run rows, and stored path references are redirected to the invoking tree. Conflicting or unreadable **owned** retained evidence refuses teardown. A divergent copy of evidence a forwarded task does **not** own (its WBS is not a forwarded task's and its receipt `runId` is not a worktree run row) is `foreign-divergent` (1139 R5): it is skipped, reported as `evidenceSkipped[{name, reason:'foreign-divergent', newer:'invoking'|'worktree'}]`, and the invoking-tree copy is never overwritten — another task's newer verdict can no longer block this batch's teardown. A divergent **owned** file still fails with `durable evidence conflicts`. `spur workflow persist-check` accepts the same foreign-divergent set from the success JSON and does not recompute it.
|
|
110
110
|
|
|
111
111
|
**Owned evidence rides it too (1012).** With at least one `--task-file`, persist-out also treats as
|
|
112
112
|
copy obligations the worktree's `.spur/run/` direct children named `<wbs>-…` (the WBS is each
|
|
@@ -124,7 +124,7 @@ pass before the invoking tree is written → WT-5. Without `--task-file` nothing
|
|
|
124
124
|
The shapes are pinned (task 0975 R1; `record-missing`, citation behavior per 0984; `evidenceSkipped` per 1139 R5): idempotent on re-persist;
|
|
125
125
|
success exits 0 printing
|
|
126
126
|
`{"ok":true,"persisted":<n>,"skipped":[{"id":<run-id>,"reason":"id-exists"|"external-key-conflict"|"record-conflict:<file>"|"record-missing:<file>"|"cited-directory:<name>"|"cited-symlink:<name>"|"cited-non-file:<name>"}],"evidenceSkipped":[{"name":<file>,"reason":"foreign-divergent","newer":"invoking"|"worktree"}]}`
|
|
127
|
-
(`evidenceSkipped` is omitted when empty; the same object is written to `<invoking-tree>/.spur/run/persist-out.json` for `spur workflow
|
|
127
|
+
(`evidenceSkipped` is omitted when empty; the same object is written to `<invoking-tree>/.spur/run/persist-out.json` for `spur workflow persist-check` to read)
|
|
128
128
|
— an `external-key-conflict` skip leaves the target run unchanged **and fails the pass (1049)**: the delegate exits 1 printing `{"ok":false,"error":…}` naming the skipped source run ids, because that (workflow, external key) identity already belongs to a different receiving run — the batch was not persisted, so reconcile the source worktree by hand (it stays the provenance owner of record) before any teardown: auditable reconciliation names the original archived DB snapshot and the skipped source run identities, verifies the archive by file hash and by merged-commit ancestry of the source branch, and treats any residual deletion as explicit operator-authorized cleanup under the strict canonical evidence rules above. Task 1149 R1 grades a terminal duplicate lifecycle row (`task-lifecycle`/`feature-lifecycle`) as `external-key-conflict-bookkeeping` (non-fatal), so guarded transitions driven inside the worktree do not block teardown; the receiving lifecycle row is reconciled automatically during persist-out. An `id-exists` replay repairs missing owned artifacts and task links without duplicating them. A
|
|
129
129
|
`record-conflict:<file>` never overwrites a divergent invoking-tree record and causes the delegate to exit 1, retaining the worktree. Before reconciling one by hand, check **what** the invoking record is: when the run closed `done` inside a linked worktree the owning tree holds that run's **WT-0 landing obligation** (`landing: required branch=… path=… base=…`, see [execution-worktree-landing.md § WT-0](execution-worktree-landing.md#wt-0--markerless-worktree-runs)) — a 3-line record that is *not* a stub of the worktree's stage narrative, so copying the worktree record over it destroys the very obligation a later merge must rewrite. The reconciliation is therefore: discharge the obligation in place (`landing: merged <sha>` or `landing: retained`), and preserve the worktree narrative beside it (e.g. `<runId>.worktree-provenance.md`) rather than in place of it. A
|
|
130
130
|
`record-missing:<file>` skip is a known `task-lifecycle`/`feature-lifecycle` row with no record file
|