@gobing-ai/spur 0.4.33 → 0.4.35

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 (94) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/config.global.yaml +1 -4
  3. package/config/decisions/task-pipeline.yaml +1 -29
  4. package/config/pipeline-budgets.json +2 -2
  5. package/config/rules/boundary/sp-runtime-path.yaml +0 -2
  6. package/config/rules/strict/runtime-boundaries.yaml +2 -12
  7. package/config/rules/structure/protected-files.yaml +0 -3
  8. package/config/rules/surface/check-cli-surface.yaml +1 -2
  9. package/config/workflow-candidates.json +1 -1
  10. package/config/workflows/idea-pipeline.yaml +1 -1
  11. package/config/workflows/task-pipeline.yaml +53 -185
  12. package/package.json +1 -1
  13. package/plugins/sp/README.md +4 -2
  14. package/plugins/sp/agents/super-reviewer.md +18 -60
  15. package/plugins/sp/commands/dev-fixall.md +0 -7
  16. package/plugins/sp/commands/dev-review.md +1 -1
  17. package/plugins/sp/commands/dev-run.md +8 -3
  18. package/plugins/sp/commands/dev-runall.md +7 -4
  19. package/plugins/sp/commands/dev-verify.md +0 -10
  20. package/plugins/sp/commands/dev-verifyall.md +0 -5
  21. package/plugins/sp/plugin.json +1 -1
  22. package/plugins/sp/skills/code-implementation/SKILL.md +1 -3
  23. package/plugins/sp/skills/code-verification/SKILL.md +14 -51
  24. package/plugins/sp/skills/code-verification/references/verdict-schema.md +18 -119
  25. package/plugins/sp/skills/issue-finding/SKILL.md +1 -1
  26. package/plugins/sp/skills/next-router/references/routing-table.md +0 -7
  27. package/plugins/sp/skills/spec-decomposition/references/decomposition.md +1 -6
  28. package/plugins/sp/skills/spur-cli/references/decision.md +3 -6
  29. package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +2 -27
  30. package/plugins/sp/skills/spur-cli/references/tasks.md +3 -6
  31. package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +6 -13
  32. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +2 -3
  33. package/plugins/sp/skills/spur-dev/references/dev-operations.md +4 -4
  34. package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +4 -5
  35. package/plugins/sp/skills/spur-dev/references/execution-batch-report.md +9 -5
  36. package/plugins/sp/skills/spur-dev/references/execution-batch.md +4 -5
  37. package/plugins/sp/skills/spur-dev/references/execution-workflow.md +1 -1
  38. package/plugins/sp/skills/spur-dev/references/execution-worktree-landing.md +34 -0
  39. package/plugins/sp/skills/spur-dev/references/flag-glossary.md +14 -1
  40. package/plugins/sp/skills/spur-dev/references/migration-guide.md +214 -0
  41. package/spur.js +1487 -4616
  42. package/web/_astro/{BoardApp.CuCuw0lw.js → BoardApp.BzY_krKQ.js} +1 -1
  43. package/web/_astro/{BoardApp.BGGDrfHl.js → BoardApp.CIImQFjG.js} +3 -3
  44. package/web/_astro/{TaskDetail.DWXct9_X.js → TaskDetail.c48Pnba6.js} +1 -1
  45. package/web/_astro/{arc.BxG3NS1o.js → arc.CpU6Cddr.js} +1 -1
  46. package/web/_astro/{architectureDiagram-3BPJPVTR.BxaiM2Hv.js → architectureDiagram-3BPJPVTR.CaXT9ZEz.js} +1 -1
  47. package/web/_astro/{blockDiagram-GPEHLZMM.DJ3r6SdD.js → blockDiagram-GPEHLZMM.Cnv3IsW9.js} +1 -1
  48. package/web/_astro/{c4Diagram-AAUBKEIU.BkzpXBQs.js → c4Diagram-AAUBKEIU.VO_hjv9n.js} +1 -1
  49. package/web/_astro/channel.DrtdR7d_.js +1 -0
  50. package/web/_astro/{chunk-2J33WTMH.DI7UanTc.js → chunk-2J33WTMH.BOunhbrU.js} +1 -1
  51. package/web/_astro/{chunk-4BX2VUAB.C2uLhAlQ.js → chunk-4BX2VUAB.Brg-Gmb2.js} +1 -1
  52. package/web/_astro/{chunk-55IACEB6.KwNI2kxL.js → chunk-55IACEB6.BqF9dxiC.js} +1 -1
  53. package/web/_astro/{chunk-727SXJPM.CHZUthkg.js → chunk-727SXJPM.CEIGJZdc.js} +1 -1
  54. package/web/_astro/{chunk-AQP2D5EJ.DLr4QNJo.js → chunk-AQP2D5EJ.BxXI0bx9.js} +1 -1
  55. package/web/_astro/{chunk-FMBD7UC4.B1G8WrnE.js → chunk-FMBD7UC4.CveXCF83.js} +1 -1
  56. package/web/_astro/{chunk-ND2GUHAM.CzsA-SkD.js → chunk-ND2GUHAM.DwKjp403.js} +1 -1
  57. package/web/_astro/{chunk-QZHKN3VN.DAvBQYli.js → chunk-QZHKN3VN.DgwjHrXx.js} +1 -1
  58. package/web/_astro/{classDiagram-4FO5ZUOK.Cddmz8Ze.js → classDiagram-4FO5ZUOK.BcVv8Qmo.js} +1 -1
  59. package/web/_astro/{classDiagram-v2-Q7XG4LA2.Cddmz8Ze.js → classDiagram-v2-Q7XG4LA2.BcVv8Qmo.js} +1 -1
  60. package/web/_astro/{cose-bilkent-S5V4N54A.CKEu7KRX.js → cose-bilkent-S5V4N54A.28xfMBER.js} +1 -1
  61. package/web/_astro/{cynefin-OW5HDTMX.-B4Cy_Vl.js → cynefin-OW5HDTMX.BAFHBcJj.js} +1 -1
  62. package/web/_astro/{dagre-BM42HDAG.bLxFvI-t.js → dagre-BM42HDAG.DzR6wa9Z.js} +1 -1
  63. package/web/_astro/{diagram-2AECGRRQ.DAHU0t5h.js → diagram-2AECGRRQ.IpFlr4yd.js} +1 -1
  64. package/web/_astro/{diagram-5GNKFQAL.DFciwCNk.js → diagram-5GNKFQAL.DGNU2pOL.js} +1 -1
  65. package/web/_astro/{diagram-KO2AKTUF.BvH0dGId.js → diagram-KO2AKTUF.D_wP6t4w.js} +1 -1
  66. package/web/_astro/{diagram-LMA3HP47.BgVlskRO.js → diagram-LMA3HP47.B0DMC97s.js} +1 -1
  67. package/web/_astro/{diagram-OG6HWLK6.BpurMISo.js → diagram-OG6HWLK6.DQXmNEBs.js} +1 -1
  68. package/web/_astro/{erDiagram-TEJ5UH35.SDj5bUMU.js → erDiagram-TEJ5UH35.BZ0VPjjp.js} +1 -1
  69. package/web/_astro/{flowDiagram-I6XJVG4X.Bm5U58FE.js → flowDiagram-I6XJVG4X.zu5gJs9Z.js} +1 -1
  70. package/web/_astro/{ganttDiagram-6RSMTGT7.CnMnds77.js → ganttDiagram-6RSMTGT7.DYy6LDqD.js} +1 -1
  71. package/web/_astro/{gitGraphDiagram-PVQCEYII.BQUwwyWo.js → gitGraphDiagram-PVQCEYII.C6c_wPdO.js} +1 -1
  72. package/web/_astro/index.C4tUn4AU.css +1 -0
  73. package/web/_astro/{infoDiagram-5YYISTIA.BiSKdORH.js → infoDiagram-5YYISTIA.C3bQPQl8.js} +1 -1
  74. package/web/_astro/{ishikawaDiagram-YF4QCWOH.Br69sBTI.js → ishikawaDiagram-YF4QCWOH.Cc1D58oG.js} +1 -1
  75. package/web/_astro/{journeyDiagram-JHISSGLW.C39WX1W8.js → journeyDiagram-JHISSGLW.CY51-lNM.js} +1 -1
  76. package/web/_astro/{kanban-definition-UN3LZRKU.DppWcbSX.js → kanban-definition-UN3LZRKU.D_3v92y6.js} +1 -1
  77. package/web/_astro/{linear.DeivTDuc.js → linear.C6BrJ38s.js} +1 -1
  78. package/web/_astro/{mermaid.core.Dixrjrnj.js → mermaid.core.DO9lF20B.js} +4 -4
  79. package/web/_astro/{mindmap-definition-RKZ34NQL.BWIQ2MWG.js → mindmap-definition-RKZ34NQL.BMiM91P6.js} +1 -1
  80. package/web/_astro/{pieDiagram-4H26LBE5.vvtHpfT7.js → pieDiagram-4H26LBE5.CcgIgRlR.js} +1 -1
  81. package/web/_astro/{quadrantDiagram-W4KKPZXB.9c-T6qCy.js → quadrantDiagram-W4KKPZXB.CM1CzrHl.js} +1 -1
  82. package/web/_astro/{requirementDiagram-4Y6WPE33.9ZuRw-kn.js → requirementDiagram-4Y6WPE33.CQvQ1E8r.js} +1 -1
  83. package/web/_astro/{sankeyDiagram-5OEKKPKP.CTIWteEl.js → sankeyDiagram-5OEKKPKP.D-b1ONCV.js} +1 -1
  84. package/web/_astro/{sequenceDiagram-3UESZ5HK.DEvu4vLL.js → sequenceDiagram-3UESZ5HK.BQzFGYtH.js} +1 -1
  85. package/web/_astro/{stateDiagram-AJRCARHV.Bxvsgk-_.js → stateDiagram-AJRCARHV.DiCukZ7I.js} +1 -1
  86. package/web/_astro/{stateDiagram-v2-BHNVJYJU.CVuog5yY.js → stateDiagram-v2-BHNVJYJU.4Iut-DMk.js} +1 -1
  87. package/web/_astro/{timeline-definition-PNZ67QCA.CpPItB3E.js → timeline-definition-PNZ67QCA.BKQiLF24.js} +1 -1
  88. package/web/_astro/{vennDiagram-CIIHVFJN.C7eKaLRK.js → vennDiagram-CIIHVFJN.CyeSCofx.js} +1 -1
  89. package/web/_astro/{wardleyDiagram-YWT4CUSO.DWXHT_CW.js → wardleyDiagram-YWT4CUSO.B140ei48.js} +1 -1
  90. package/web/_astro/{xychartDiagram-2RQKCTM6.DOsrNQOF.js → xychartDiagram-2RQKCTM6.DjPyVoO1.js} +1 -1
  91. package/web/index.html +2 -2
  92. package/config/rules/structure/scratch-evidence-pointer.yaml +0 -35
  93. package/web/_astro/channel.CYWRkoDI.js +0 -1
  94. package/web/_astro/index.CKtaGArK.css +0 -1
@@ -89,7 +89,6 @@ content up front — not to accumulate more into one oversized task.
89
89
  | `list` | List tasks, filtered | `--status <s>` `--phase <p>` `--parent <wbs>` `--feature <id>` `--folder` `--json` |
90
90
  | `refresh` | Re-scan the corpus and report counts (**`kanban.md` retired** — web Task Kanban is SSOT) | `--folder` `--json` |
91
91
  | `migrate` | One-time A17 corpus normalization pass | `--dry-run` `--folder` `--json` |
92
- | `migrate-anchors` | Qualify in-repo evidence anchors to repo-relative paths (0583 R1–R3); `--wbs` scopes to one task file (1109 R1); retargets scratch `done_reason` verdict pointers (1140) | `--wbs` `--dry-run` `--json` |
93
92
  | `refresh-roster <wbs>` | Regenerate a parent task's sub-task roster block in `## Plan` | `--folder` `--json` |
94
93
  | `batch-create` | Create many tasks from a validated JSON array | `--file <path>` `--skip-ready` `--agent <selector>` `--folder` `--json` |
95
94
  | `batch-plan <mode>` | Batch plan projection: `waves` / `order` (JSON on stdout; the batch driver's visible plan) | `--tasks <file>` `--concurrency <n>` |
@@ -105,13 +104,11 @@ content up front — not to accumulate more into one oversized task.
105
104
  | `verifyall-aggregate` | Aggregate per-task verify outcomes into a batch verdict (NOT-STARTED excluded) | `--from-file <path>` `--json` |
106
105
  | `scaffold-tests <wbs>` | Generate BDD test stubs from task Acceptance Criteria | `--file <path>` `--folder` `--json` |
107
106
  | `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>` |
108
- | `residual <wbs> <step>` | F96 residual sweep step (`scan`, `review-gate`, `fold`, `settle`, `report`) | `--root <dir>` `--tmp-dir <dir>` `--folder` |
109
107
  | `diffstat <wbs>` | Write the triage diffstat artifact against the run base (fails safe to `sensitive: true`) | — |
110
108
 
111
109
  Use only the flags listed for the selected verb. `batch-plan` emits JSON without `--json`;
112
- `wrapup`, `gate`, `residual` and `diffstat` use their operation-specific stdout/artifact contracts.
113
- `run-link`, `verifyall-aggregate` and `migrate-anchors` accept `--json` but no `--folder`;
114
- `residual` accepts `--folder` but no `--json`. Do not append shared flags to every command.
110
+ `wrapup`, `gate` and `diffstat` use their operation-specific stdout/artifact contracts.
111
+ `run-link` and `verifyall-aggregate` accept `--json` but no `--folder`. Do not append shared flags to every command.
115
112
  General exit codes are `0` success, `1` error, `2` invalid usage; consult the operation contract
116
113
  for soft gate modes and specialized refusal codes.
117
114
 
@@ -203,7 +200,7 @@ refused (ready-set resolver and pipeline preflight), and a live dependent is rep
203
200
  reported, never rewritten.
204
201
 
205
202
  Writes that stay **permitted** on a `deprecated` task (each edits the record rather than declaring
206
- the work resumable): `spur task record`, `migrate-anchors` and verdict writes, and
203
+ the work resumable): `spur task record` and verdict writes, and
207
204
  `spur task update <wbs> --section <any>` — the section write lands and returns a freeze warning.
208
205
 
209
206
  **`--no-lifecycle`** suppresses lifecycle workflow *run record* creation (use during pipeline-driven
@@ -126,14 +126,8 @@ scenario, it matches by title. Rules:
126
126
  Registered user can log in with email and password" is traceable.
127
127
  - **No synonyms in cross-references.** The title in the feature file and the title in the
128
128
  task's AC reference must be byte-identical.
129
- - **Avoid gate vocabulary in titles.** `spur task check` (L4.gate-language) rejects task sections
130
- containing `HITL`, `merge event`, `content-gate`, `GATED`, or `capstone` as standalone words in any
131
- case (dotted action kinds such as `hitl.confirm` are fine);
132
- ambiguous words (`approval`, `approved`, `merged`) warn only when the same sentence also carries
133
- a gating cue (`until`, `after`, `once`, `before`, `pending`, `blocked`, `wait for`, `requires`)
134
- — plain composition prose like "the stages merged back into one step" stays silent. Task AC
135
- bullets copy scenario titles verbatim, so a title using the unconditional tokens fails every
136
- child task. Write "pause for an operator answer" instead of "HITL approval".
129
+ - **Avoid gate vocabulary in titles** (`HITL`, `merge event`, `GATED`, `capstone`): it reads as a
130
+ dependency nothing declares. Convention only — nothing checks it. Write "pause for an operator answer" instead of "HITL approval".
137
131
 
138
132
  ## Verdict AC ↔ feature scenario linkage
139
133
 
@@ -174,7 +168,7 @@ Any of the four may additionally carry a **bracket tag** in any position — `[d
174
168
  `Scenario: [advisory] Foo`. Tags are stripped before matching (0398 R7), so tagging never breaks
175
169
  the linkage.
176
170
 
177
- Task-side, the `spur task verdict` answer lint additionally accepts a fifth declared id source — a **bold-trajectory
171
+ Task-side, a fifth declared id source is accepted — a **bold-trajectory
178
172
  paragraph**: a whole-line `**AC id…**` paragraph inside the task's `### Acceptance Criteria`
179
173
  block (task 0817 R3). The id up to its first `:` and the paragraph's full spelling are both
180
174
  declared; two bold spans on one line are not a declaration (an interpolated bold id stays
@@ -190,13 +184,12 @@ unmatchable):
190
184
 
191
185
  ### A bullet's bold head is its id
192
186
 
193
- The `spur task verdict` answer lint declares the bold span of a single-line criterion bullet
187
+ `spur task verdict` treats the bold span of a single-line criterion bullet
194
188
  (`- **AC2 — The roster runtime is gone (R3).** Given …, when …, then …`) and its head before the
195
189
  first ` — ` or `:` — so answer rows may key `AC2` or `AC2 — The roster runtime is gone (R3).`. Keep
196
190
  at least one answer row keyed to the verbatim feature scenario title the task graduates, and keep
197
191
  requirement ids in the template-taught corpus form, `- [ ] R1. <text>`: that (or an unbolded `R1.`
198
- variant) is what the task-local binding loop parses — bold wrapping (`**R1**`) passes the
199
- `L3.requirements-format` ratio but binds nothing — and a colon after the bold span still silently
192
+ variant) is what the task-local binding loop parses — bold wrapping (`**R1**`) binds nothing — and a colon after the bold span still silently
200
193
  drops the whole section to a warning. Bold AC heads are likewise a verdict-table id form, not the AC
201
194
  authoring form: author new AC rows in the plain `- [ ] AC1 —` / `Scenario: AC1 —` shapes.
202
195
 
@@ -340,5 +333,5 @@ truly does not apply (do not silently default new tasks to it).
340
333
  | Legacy raw bullets | `- AC1 …` (no checkbox, no `Scenario:`) | n/a | unparsed: invisible to subset, binding, and box checks — preserve in place, never author new |
341
334
 
342
335
  `task-local` altitude skips only the feature-subset check. It does not waive the unchecked-box check,
343
- required sections, the proof-bound verdict, line anchors, or any other done check — AC syntax alone,
336
+ required sections, the proof-bound verdict, or any other done check — AC syntax alone,
344
337
  at any altitude, never makes a task done.
@@ -412,9 +412,8 @@ loop?**
412
412
 
413
413
  - **External evidence** — evidence that lives outside `spur`'s working tree uses the frozen non-anchor
414
414
  form `origin`path`line N` (line OUTSIDE the backticks), e.g.
415
- `@gobing-ai/ts-llm-jsonl-importer`src/mappers.ts`line 481`. It is classified external, never
416
- `L4.stale-line-anchor`. In-repo evidence MUST use the repo-relative backtick form `path:line` —
417
- citing an in-repo file in the external form still reports (R1/R2). See `ac-style-guide.md` and the
415
+ `@gobing-ai/ts-llm-jsonl-importer`src/mappers.ts`line 481`. In-repo evidence uses the repo-relative backtick form `path:line`. Reviewer-facing convention —
416
+ nothing resolves anchors mechanically. See `ac-style-guide.md` and the
418
417
  `code-verification` skill for when each applies.
419
418
 
420
419
  **Why this is a rule and not a preference.** A decision filed as a task sits in `spur task list` and
@@ -73,7 +73,7 @@ each would be scope creep for one-liner procedures.
73
73
  | 2 | review | `dev-review` | `Skill()` | `sp:code-verification` (`review`) + `sp:functional-review` + `sp:code-improvement` | `[--tasks <selector> \| --feature <id>[,<id>] \| --scope <path>[,<path>]] [--agent <inline\|auto\|name>] [--focus <dims>] [--triage] [--worktree [<name>]] [--auto]` |
74
74
  | 3 | verify | `dev-verify` | `Skill()` | `sp:code-verification` (`verify`) | `<wbs> [--agent <inline\|auto\|name>] [--fix <none\|blockers-first\|all>] [--focus <lens>] [--bdd] [--auto] [--force] [--next] [--skip-shippable]` |
75
75
  | 3a | verifyall | `dev-verifyall` | `Skill()` → agent | `sp:spur-dev` (`verifyall`) | `--tasks <selector> [--feature <id>] [--agent <inline\|auto\|name>] [--fix <none\|blockers-first\|all>] [--focus <lens>] [--bdd] [--auto] [--force] [--next] [--json] [--skip-shippable] [--worktree [<name>]]` |
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]` |
76
+ | 4 | run | `dev-run` | `Skill()` | `sp:spur-dev` (`run` / `implement`) | `<wbs> [--mode <full\|implement>] [--agent <inline\|auto\|name>] [--auto] [--next] [--wrap] [--wrap-pr] [--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
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]` |
@@ -86,7 +86,7 @@ each would be scope creep for one-liner procedures.
86
86
  | 11b | job-resume | `dev-job-resume` | `Skill()` | `sp:spur-dev` (`job-resume`) | `--file <path>` |
87
87
  | 12 | brainstorm | `dev-brainstorm` | `Skill()` | `sp:brainstorm` (`dev-brainstorm`) | `<topic> [--depth <basic\|detailed\|comprehensive>] [--options <n>] [--agent <inline\|auto\|name>] [--skip-discovery] [--task [<feature-id>]] [--feature [<parent-id>]] [--next]` |
88
88
  | 12a | find-way | `dev-find-way` | `Skill()` | `sp:wayfinder` (worktree-isolated) | `<idea> \| <feature-id> [<wbs>] [--agent <inline\|auto\|name>] [--auto] [--worktree [<name>]] [--wrap]` |
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]` |
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] [--wrap-pr] [--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
92
  | 16 | idea | `dev-idea` | `Skill()` | host executor (`idea-pipeline`) or async workflow | `"<idea>" \| --from-file <path> [--skip-design] [--agent <inline\|auto\|name>] [--auto]` |
@@ -156,7 +156,7 @@ must not be changed without updating the backing skill.
156
156
  ### 4. run
157
157
 
158
158
  - **Purpose:** Run a task through the execution pipeline (full) or execute a single pipeline step (implement).
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 runs `task-pipeline.yaml` on the host executor (`spur workflow run … executor=host` → work item → `spur workflow continue`) — 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.
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 runs `task-pipeline.yaml` on the host executor (`spur workflow run … executor=host` → work item → `spur workflow continue`) — 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. `--wrap-pr` runs the wrap hop on `$BRANCH`, commits close-out writes, pushes the branch to `origin`, and opens a Pull Request targeting `$BASE_REF` via `gh pr create` (`WT-PR`); mutually exclusive with `--wrap`.
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
162
  - **`full`** (default): Drive the full pipeline — precheck → implement → gate ⇄ remediate → review → done, with the repair, stop and approval routes taken from decision rows ([decision-points.md](decision-points.md)). 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.
@@ -481,7 +481,7 @@ gate commands, pending questions and approval requirements.>
481
481
  ### 13. runall
482
482
 
483
483
  - **Purpose:** Run a batch of tasks through their pipelines in dependency-correct order — resolve a set, topo-sort, run each via `task-pipeline.yaml`, inspect verdicts, apply the failure policy, emit a batch report.
484
- - **Inputs:** `--tasks <selector>` (required — explicit WBS list, status pseudo-list, `feature:<id>`, or `ready`). `--mode <sequential|parallel>` (default `sequential`; `parallel` fans out a proven-independent subset per `execution-batch.md` § Parallel Execution). `--keep-going` skips a failed task's in-batch dependents and continues independents (default off; `--auto` implies `--keep-going`, so an unattended batch never stops for a human — 1318 R1). `--auto` sets `profile=auto` on each per-task run (skips the HITL approve gate). `--feature <id>` is sugar for `--tasks feature:<id>`; when the effective selector is feature-derived, the batch runs `spur feature check <id> --fix --json` then `spur feature check <id> --strict --json` **once** before task resolution — a non-zero strict check aborts with verdict `aborted`, zero attempted tasks, and the structured findings (task 0510 R2); scoped: `L4.scenario-unverified` and `L4.verifying-incomplete-tasks` (expected pre-run states of a not-yet-run or reopened feature) are reported verbatim but do not abort — the non-aborting set is `NON_ABORTING_PREFLIGHT_CODES` behind `spur task preflight --classify-feature` and `--fix` repairs are listed under `autoRepairs` — any other strict error aborts. Explicit WBS/status/`ready` selectors add no feature check. The orchestrator loop itself continues in this session; interactive sequential omit/`inline` uses the host driver — host-controlled with eligible `agent.run` stages dispatching once to a native subagent and host fallback (task 0508) — while `--agent auto`/a name, parallel mode, and headless invocation keep the isolated per-task workflow subprocess boundary. `--agent <inline|auto|name>` pins the executor for the per-task stages (see [SSOT](cross-cutting.md#inline-default-execution-surface)); the value crosses into per-task `vars.agent`, not the orchestrator. `--json` emits the report as JSON. `--wrap` triggers `wrapup-pipeline.yaml` **once for the batch** over the `done` subset only (execution-batch.md Step 6: `vars.feature` only when every frozen task is `done`/`cancelled`; empty done subset skips with a reason), `--next` chains each task to terminal status then runs the same batch-once wrap, `--continue` resumes from checkpoint. `--no-summary` skips the [execution summary](#execution-summary) printed after the batch report (one row per attempted run).
484
+ - **Inputs:** `--tasks <selector>` (required — explicit WBS list, status pseudo-list, `feature:<id>`, or `ready`). `--mode <sequential|parallel>` (default `sequential`; `parallel` fans out a proven-independent subset per `execution-batch.md` § Parallel Execution). `--keep-going` skips a failed task's in-batch dependents and continues independents (default off; `--auto` implies `--keep-going`, so an unattended batch never stops for a human — 1318 R1). `--auto` sets `profile=auto` on each per-task run (skips the HITL approve gate). `--feature <id>` is sugar for `--tasks feature:<id>`; when the effective selector is feature-derived, the batch runs `spur feature check <id> --fix --json` then `spur feature check <id> --strict --json` **once** before task resolution — a non-zero strict check aborts with verdict `aborted`, zero attempted tasks, and the structured findings (task 0510 R2); scoped: `L4.scenario-unverified` and `L4.verifying-incomplete-tasks` (expected pre-run states of a not-yet-run or reopened feature) are reported verbatim but do not abort — the non-aborting set is `NON_ABORTING_PREFLIGHT_CODES` behind `spur task preflight --classify-feature` and `--fix` repairs are listed under `autoRepairs` — any other strict error aborts. Explicit WBS/status/`ready` selectors add no feature check. The orchestrator loop itself continues in this session; interactive sequential omit/`inline` uses the host driver — host-controlled with eligible `agent.run` stages dispatching once to a native subagent and host fallback (task 0508) — while `--agent auto`/a name, parallel mode, and headless invocation keep the isolated per-task workflow subprocess boundary. `--agent <inline|auto|name>` pins the executor for the per-task stages (see [SSOT](cross-cutting.md#inline-default-execution-surface)); the value crosses into per-task `vars.agent`, not the orchestrator. `--json` emits the report as JSON. `--wrap` triggers `wrapup-pipeline.yaml` **once for the batch** over the `done` subset only (execution-batch.md Step 6: `vars.feature` only when every frozen task is `done`/`cancelled`; empty done subset skips with a reason), `--wrap-pr` runs the batch-once wrap hop, pushes to `origin`, and creates a Pull Request via `gh pr create` (`WT-PR`; mutually exclusive with `--wrap`), `--next` chains each task to terminal status then runs the same batch-once wrap, `--continue` resumes from checkpoint. `--no-summary` skips the [execution summary](#execution-summary) printed after the batch report (one row per attempted run).
485
485
  - **Three orthogonal axes (do not confuse):** `--keep-going` = batch failure policy (halt vs skip dependents); `--continue` = resume from checkpoint against the batch's original frozen identity (execution-batch.md § Batch continuation, task 0919); `--next` = per-task lifecycle chaining (advance status on a verdict — `dev-verify`/`dev-verifyall` only). `routing-table.md` offers `--continue` and `--next` as competing options for the same situation only when the batch was interrupted mid-run; otherwise they address different problems.
486
486
  - **Backing:** `sp:spur-dev` skill, `runall` operation → delegates the driver loop to the **`sp:super-planner`** agent (the batch orchestrator).
487
487
  - **Behavior:** The orchestrator reads [execution-batch.md](execution-batch.md) and drives: resolve selector → freeze set → topo-sort by `dependencies[]` (Kahn, WBS-ascending tie-break; cycle aborts) → resolve out-of-set deps by status (done → allow, else → block subtree) → run each task via `spur workflow run task-pipeline.yaml --async` + `spur workflow trace` polling → inspect terminal state + `.spur/run/<wbs>-verdict.json` → stop-the-batch default or `--keep-going` subtree skip → emit batch report. Per-task pipeline is invoked **verbatim** — no new FSM, no step edits. `--auto`/`--agent` are the only flags that cross the orchestrator→pipeline boundary (both into per-task `--vars`).
@@ -102,8 +102,7 @@ restricted sandbox - port-binding and `ps` denials produce failures that are not
102
102
  project's sandbox notes). Real regressions are *additional* failures.
103
103
 
104
104
  **3. Finish the work the step abandoned.** Write the sections the killed step would have written
105
- (`## Solution`, `## Testing`, and the `## Review` P1-P4 table - the L3 `review-priority-table`
106
- gate will reject the task without it). Use the normal `--section --from-file` contract.
105
+ (`## Solution`, `## Testing`, and the `## Review` P1-P4 table). Use the normal `--section --from-file` contract.
107
106
 
108
107
  **4. Force-done with an honest reason.**
109
108
 
@@ -131,13 +130,13 @@ silently incomplete (H6 shipped at 23/48 that way, with one verdict carrying an
131
130
  `acceptanceCriteria` array and still reading PASS). See `ac-style-guide.md` §
132
131
  "Verdict AC ↔ feature scenario linkage" for the id forms and evidence vocabulary.
133
132
 
134
- **Parser contract (`spur task verdict` answer lint, 0817 re-verify findings):**
133
+ **Parser contract (`spur task verdict --from-answer`; nothing lints — a malformed row is silently dropped):**
135
134
 
136
135
  1. The requirement id cell must be the **bare** id — `| R1 | MET | … |`. Suffixes (`R1 (AC1)`) or
137
- decoration (`**R1**`) fail the exact-match completeness check (`missing requirement row`).
136
+ decoration (`**R1**`) do not match the requirement and the row is dropped.
138
137
  2. The AC table only opens when the header's **third** cell contains the word "evidence" — use
139
138
  `| AC | Status | Evidence Type | Evidence |`. `| AC | Status | Type | Evidence |` silently
140
- parses zero AC rows while lint still reports PASS.
139
+ parses zero AC rows.
141
140
  3. A behavioral AC marked `MET` with a non-executable evidence type (`static-ref`,
142
141
  `manual-review`, `llm-judge`) is **downgraded to PARTIAL** by `task verdict`, making the whole
143
142
  verdict PARTIAL. Use `test`/`command` (grep-based verification counts as `command`). Only the
@@ -51,13 +51,11 @@ runs, which have no executor to pin.
51
51
  ```
52
52
  | WBS | Status | Recovery |
53
53
  |-----|--------|--------|
54
- | 0042 | failed | C6 recovery: /sp:dev-run 0042 (residual report: .spur/run/0042-residual-report.md) |
54
+ | 0042 | failed | /sp:dev-run 0042 |
55
55
  | 0050 | not-attempted | /sp:dev-next 0050 |
56
56
  ```
57
57
 
58
- A task with a residual report (failing `residual-sweep` check in its verdict artifact) uses the
59
- C6 recovery line (re-run the pipeline); every other excluded task uses the next-router A-row
60
- command for its status (F96 task 0952 R2).
58
+ Every excluded task uses the next-router A-row command for its status (task 0952 R2).
61
59
 
62
60
  The per-task outcome vocabulary: `done` | `failed` | `blocked` | `skipped` | `not-attempted`,
63
61
  plus the resume-only `recheck` (stale/mismatched evidence — pipeline re-run), `not-admitted`
@@ -154,10 +152,11 @@ spur workflow summary --rollup <runId>-summary.json --rollup <runId2>-summary.js
154
152
  One row per run carrying that run's own Total, a bold total of the sums, and — when run windows overlap —
155
153
  a wall-span line from the first start to the last end. No run block reuses a batch-wide window.
156
154
 
157
- ## Step 6 — Batch wrap (`--wrap` / `--next`) (F96 task 0952 R1)
155
+ ## Step 6 — Batch wrap (`--wrap` / `--wrap-pr` / `--next`) (F96 task 0952 R1)
158
156
 
159
157
  Run **once for the batch**, after the Step 5 report — never per task (dev-operations.md §runall
160
158
  agrees; the old "per task" flag-row wording in dev-runall.md was a contradiction, now fixed).
159
+ `--wrap` and `--wrap-pr` are mutually exclusive; passing both is rejected.
161
160
 
162
161
  The wrap receives only what it would accept:
163
162
 
@@ -202,5 +201,10 @@ spur workflow commit-guard-stage --run "$RUN_ID" -- <files the wrap wrote> \
202
201
  git commit -m "chore(wrap): <command> <selector> close-out writes"
203
202
  ```
204
203
 
204
+ **PR landing (`--wrap-pr`):** Under `--wrap-pr`, the wrap hop and close-out commit execute identically
205
+ on `$BRANCH`, but instead of fast-forward merging into the base ref (`WT-4`), the branch is pushed to
206
+ remote origin and a Pull Request is opened targeting `$BASE_REF` via `gh pr create` (`WT-PR`,
207
+ `execution-worktree-landing.md`).
208
+
205
209
  > **Forbidden:** `git add -A` and `git add .` — here as in every driver commit step. In the
206
210
  > worktree batch the same rule rides in the WT-3b block above.
@@ -445,8 +445,8 @@ Each pipeline run ends in one of two terminal states:
445
445
  `.spur/run/<wbs>-verify-answer.txt` AC table is exactly four columns:
446
446
  `| AC | Status | Evidence Type | Evidence |`. The evidence-type token
447
447
  (`test`, `command`, `static-ref`, `manual-review`, `llm-judge`, `n/a`, or a `+`
448
- compound) is isolated in cell 3. A token merged into the evidence cell fails the
449
- `spur task verdict` answer lint.
448
+ compound) is isolated in cell 3. A token merged into the evidence cell is not parsed as an
449
+ evidence type.
450
450
 
451
451
  **Driver acceptance (0930 R3).** The trace row and `.spur/run/<wbs>-verdict.json` are accepted as
452
452
  terminal evidence only if BOTH hold:
@@ -661,9 +661,8 @@ Before launching a full `spur-check:full`:
661
661
  `console.*`), spawn processes via `NodeProcessExecutor` (no `Bun.spawnSync`), get a
662
662
  `runtime-boundaries` fs-io exemption for sync reads (mirrors `commands/task/shared.ts`), and a non-command helper
663
663
  must not live in `apps/cli/src/commands/` (the noun scan treats every file there as a noun).
664
- 4. **Doc/TSDoc edits shift `file:line` anchors** cited by other tasks — the per-task gate surfaces
665
- them as `L4.anchor-subject-mismatch` (0775: the corpus sweep retired; run `spur task check <wbs>`
666
- on touched tasks). Repoint the shifted citations (via `spur task update --section`)
664
+ 4. **Doc/TSDoc edits shift `file:line` anchors** cited by other tasks — nothing
665
+ detects the drift mechanically. Repoint the shifted citations (via `spur task update --section`)
667
666
 
668
667
  ## AC traceability
669
668
 
@@ -194,7 +194,7 @@ by this session's judgment:
194
194
  Every decision point, its fallback and its consumer are listed in
195
195
  [decision-points.md](decision-points.md); read the rows it names instead of re-judging them.
196
196
 
197
- 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.
197
+ 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`. No confidence grade is stated or read anywhere, and nothing lints the answer: the reviewer's `Verdict:` line is the only review authority, so a review with an open P1–P3 finding must carry a non-PASS verdict. Nothing grades the *verifier's* opinion: 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.
198
198
 
199
199
  Agentic steps use the pure slash inputs declared by each YAML `agent.run` action (ADR-043). The
200
200
  workflow engine dispatches them; the interactive driver invokes their backing skills in-session.
@@ -352,6 +352,40 @@ merge. One contract, no alternatives:
352
352
  This is a deliberate choice over auto-migrating DB state: the committed corpus files are the durable
353
353
  record and the persisted run artifacts are the evidence record.
354
354
 
355
+ ### WT-PR — Remote PR landing path (`--wrap-pr`)
356
+
357
+ When `--wrap-pr` is supplied instead of `--wrap`:
358
+ The batch/task completes verification with no failed task, and Step 6 wrap completes its close-out commit
359
+ directly on `$BRANCH` in the execution tree.
360
+ Instead of checking out `$BASE_REF` and fast-forward merging locally (`WT-4`), the driver pushes the branch
361
+ to the remote repository and opens a GitHub Pull Request:
362
+
363
+ 1. **Preflight checks (fail-closed):**
364
+ ```bash
365
+ git remote get-url origin >/dev/null 2>&1 \
366
+ || { echo "WT-PR halt: git remote 'origin' is not configured" >&2; exit 1; }
367
+ gh auth status >/dev/null 2>&1 \
368
+ || { echo "WT-PR halt: gh CLI is not authenticated; run 'gh auth login'" >&2; exit 1; }
369
+ ```
370
+ 2. **Push branch to origin:**
371
+ ```bash
372
+ git push -u origin "$BRANCH" \
373
+ || { echo "WT-PR halt: git push origin $BRANCH failed" >&2; exit 1; }
374
+ ```
375
+ 3. **Open Pull Request via `gh pr create`:**
376
+ ```bash
377
+ # Compose PR title and body from task / batch metadata:
378
+ # For single task (dev-run): title="feat(<wbs>): <title>", body cites verification PASS & Solution.
379
+ # For batch (dev-runall): title="feat(<feature-id>): <feature-summary>" or "feat(batch): <selector> (<n> tasks)".
380
+ PR_URL=$(gh pr create --base "$BASE_REF" --head "$BRANCH" --title "$PR_TITLE" --body "$PR_BODY") \
381
+ || { echo "WT-PR halt: gh pr create failed" >&2; exit 1; }
382
+ echo "WT-PR: Pull Request opened at $PR_URL"
383
+ ```
384
+ 4. **Marker transition & worktree disposition:**
385
+ - Record in the worktree marker: `.status = "pr-created" | .prUrl = "$PR_URL"`.
386
+ - Local base branch (`$BASE_REF`) remains untouched.
387
+ - The local worktree and branch are retained (or worktree cleaned up in create mode, while preserving the branch on origin).
388
+
355
389
  ### WT-4r — rebasing a retained branch in a linked worktree
356
390
 
357
391
  When a pre-merge halt is resolved by rebasing the retained branch (rather than landing as-is), two
@@ -174,7 +174,8 @@ Two properties are load-bearing and are asserted structurally:
174
174
  unconditional single end-of-run gate).
175
175
  - **The full tier is still the only `PASS` writer.** Only the integrated run can claim a green
176
176
  project gate; the per-task token is `DEFERRED`, and the deferred `gate → review`
177
- guard accepts it only while `deferQualityGate = "true"`.
177
+ guard accepts it only while `deferQualityGate = "true"` (the pipeline default since the
178
+ incremental gate; pass `"false"` for a full gate on every task).
178
179
 
179
180
  `--defer-gate` with `--mode sequential` (or omitted `--mode`) is rejected — the flag exists to move
180
181
  one full gate from N worktrees to the one place the integrated tree exists. Under `--mode auto` it
@@ -212,6 +213,18 @@ with `--next`, wrap runs **once for the batch** after every task reaches termina
212
213
  the batch-once shippable gate `dev-verifyall` uses. Without `--next`, `--wrap` is wrap-without-
213
214
  chaining — the single task or batch wraps without advancing the lifecycle. On `dev-find-way` it
214
215
  wraps the one resolved ticket inside the worktree before the merge, and is skipped in chart mode.
216
+ Mutually exclusive with `--wrap-pr`.
217
+
218
+ ### `--wrap-pr` — run wrap hop, push branch, and create a Pull Request
219
+
220
+ **Anchor:** `#flag-wrap-pr`.
221
+
222
+ After the main step completes, run the wrap hop (learnings, metrics, doc-sync) and close-out commit,
223
+ then push the worktree or dedicated task branch to `origin` and open a Pull Request targeting the base ref using
224
+ `gh pr create`. Mutually exclusive with `--wrap` (specifying both exits 2). Full mode only; requires
225
+ `--worktree` or execution on a dedicated non-base branch (refuses execution directly on `main`).
226
+ On `dev-runall`, PR creation runs **once for the batch** over the `done` subset. When used with
227
+ `--worktree`, leaves the local base branch unmodified and records the PR URL in the worktree marker.
215
228
 
216
229
  ### `--force` — bypass a named guard
217
230
 
@@ -0,0 +1,214 @@
1
+ ---
2
+ name: downstream-migration
3
+ description: "Migrate an existing Spur project to the current CLI and plugin contract while preserving local config and planning history."
4
+ see_also:
5
+ - spur-dev
6
+ - spur-cli
7
+ ---
8
+
9
+ # Downstream migration guide
10
+
11
+ Use this guide to upgrade an existing project to **Spur 0.4.34** and its matching `sp` plugin.
12
+ For a later release, use the same procedure and read that release's `CHANGELOG.md` entries for
13
+ additional required changes. Do not treat every release as requiring a corpus rewrite.
14
+
15
+ ## 1. Preservation contract
16
+
17
+ - `.spur/config.yaml`, `docs/features/`, and `docs/tasks*/` are project-owned inputs. Never replace
18
+ them with package examples or a fresh checkout.
19
+ - Task and feature Markdown is the planning SSOT. The SQLite database is derived; database
20
+ migrations do not rewrite that Markdown. `docs/features/INDEX.md` and generated task rosters are
21
+ outputs and must only be regenerated through `spur feature`.
22
+ - Do not run `spur self init --force`, bulk-copy the packaged default configuration or its
23
+ workflow definitions, or edit generated feature regions directly. Existing project overrides need
24
+ reconciliation, not replacement.
25
+ - Keep history. Retired commands and old evidence prose can remain in completed task records;
26
+ they are not instructions to re-run. `spur task migrate-anchors` and `spur task residual` are
27
+ removed and must not be called.
28
+ - Use CLI-gated writes. Feature acceptance criteria go through `spur feature update --section`;
29
+ task sections go through `spur task update --section`. No direct corpus edits.
30
+
31
+ ## 2. Preflight and backup
32
+
33
+ Work from the downstream project root, with a clean Git tree and a named backup ref:
34
+
35
+ ```bash
36
+ cd /path/to/project
37
+ git status --short
38
+ git switch -c chore/spur-0.4.34-migration
39
+ spur --version
40
+ spur self status --json
41
+ spur self migrate --check --json
42
+ spur self exec --list --json
43
+ ```
44
+
45
+ `self migrate --check` is read-only: exit 1 means importer-schema drift and requires the apply
46
+ step below; an absent database is allowed. Keep the current checkout or another backup ref so the
47
+ migration can be reverted. If `.spur/spur.db` exists, stop the project server and copy it to a
48
+ backup location before continuing. Do not back up or restore Markdown by deleting it first.
49
+
50
+ ## 3. Install matching CLI and plugin
51
+
52
+ Install the CLI, then install the plugin from that same package rather than mixing versions:
53
+
54
+ ```bash
55
+ bun add -g @gobing-ai/superskill @gobing-ai/spur@0.4.34
56
+ superskill install sp --marketplace $(dirname $(bun pm bin -g))/install/global/node_modules/@gobing-ai/spur
57
+ spur --version
58
+ spur agent doctor --json
59
+ ```
60
+
61
+ Confirm the reported CLI version is the intended release. `agent doctor` checks executor usability;
62
+ it does not prove authentication or provider quota. The Electron shell is retired: use
63
+ `spur self serve` for the Board.
64
+
65
+ ## 4. Migrate `.spur/config.yaml`
66
+
67
+ Preserve project-specific values and make only the applicable edits:
68
+
69
+ | Existing state | Required action |
70
+ | --- | --- |
71
+ | `.spur/config.json` still supplies project config | Move the project-owned values into `.spur/config.yaml`; do not keep a second config authority. |
72
+ | `version` is absent or an integer | Use the YAML string `version: "1.1"`. |
73
+ | `agent.team` or `.spur/fleet.json` declares a roster | Move it to **project-layer** `agent.fleet`. Keep executor profiles in the global layer, not in the fleet. A leftover old carrier fails loading by design. |
74
+ | `workflow.hitlDecisionMaker` | Rename the section to `workflows.hitlDecisionMaker`. |
75
+ | Bun project with no `builder` block | No change: `builder.preset: bun` supplies the existing commands. |
76
+ | Non-Bun project, or custom commands required | Set `builder.preset: none` and bind `builder.actions` (`lint`, `test`, `check`, and any required `*-changed` actions) to the project's real commands. |
77
+ | `tasks.folders` and `tasks.active` | Preserve folder names, labels, `baseCounter`, and the active folder. Archived folders remain readable history, not a bulk-migration target. |
78
+ | `features.dir` | Preserve the existing feature tree and hierarchical IDs; do not renumber features or scenario titles. |
79
+
80
+ Example non-Bun binding only (replace placeholders with real commands):
81
+
82
+ ```yaml
83
+ builder:
84
+ preset: none
85
+ actions:
86
+ lint: <project-lint-command>
87
+ test: <project-test-command>
88
+ check: [lint, test]
89
+ ```
90
+
91
+ Validate resolution without running the actions:
92
+
93
+ ```bash
94
+ spur self exec --list --json
95
+ spur self exec check --dry-run --json
96
+ spur self status --json
97
+ ```
98
+
99
+ Do not copy `config/config.example.yaml` over the project file. That example documents available
100
+ keys; it is not a migration target.
101
+
102
+ ## 5. Reconcile project workflow overrides
103
+
104
+ The bundled definitions are not drop-in replacements for project overrides. Compare with
105
+ `spur workflow list --json` and validate every project-owned definition with
106
+ `spur workflow validate <path>`.
107
+
108
+ For 0.4.34 specifically:
109
+
110
+ - Task execution is D65: `precheck → implement[⇄escalate] → gate[⇄remediate] → review → done`.
111
+ There are no separate `test`/`test-recheck`, `approve`, `verify`, or `record` states. Completion
112
+ evidence is a tree-hash gate receipt plus the reviewer verdict; the old proof-digest chain,
113
+ answer lint, answer-confidence fields, residual sweep, and verdict replay are gone.
114
+ - `deferQualityGate: "true"` makes the incremental gate the per-task default. The full project
115
+ gate runs once per feature or batch; do not remove that integrated-tree check.
116
+ - Feature verification is owned by `feature-lifecycle`: entering `verifying` runs
117
+ `spur feature verify`. The separate `feature-verification.yaml` workflow is removed, and
118
+ `wrapup-pipeline` no longer changes feature status.
119
+ - Planning uses `idea-pipeline`. The legacy planning, docs, feature-development, duplicate task,
120
+ PR-review, and wayfinder workflow definitions are removed. Route former callers to `idea-pipeline`,
121
+ `task-pipeline`, `feature-lifecycle`,
122
+ `spur builder pr-check|pr-open|pr-review|pr-status`, or the wayfinder skill as appropriate.
123
+ - Project-layer `task-lifecycle.yaml` and `feature-lifecycle.yaml` overrides must be re-synced for
124
+ current guards and the non-terminal `deprecated` state. The status addition itself needs no
125
+ corpus migration.
126
+
127
+ ## 6. Migrate and validate the planning corpus
128
+
129
+ Run only the operations that apply to the project's actual state:
130
+
131
+ ```bash
132
+ # A17 normalization only, not a general schema migrator — preview first.
133
+ spur task migrate --dry-run --json
134
+ # If the preview shows wanted A17 changes and no conflicts:
135
+ spur task migrate --json
136
+
137
+ # Structural checks and optional mechanical repairs; review their diffs afterward.
138
+ spur task check --fix --json
139
+ spur feature check --fix --json
140
+
141
+ # Required final validation (warnings are reported separately from errors).
142
+ spur task check --corpus --json
143
+ spur feature check --json
144
+ ```
145
+
146
+ `task migrate` normalizes the active task folder (or an explicit `--folder`). It is not a
147
+ feature-migration or a reason to rewrite archived folders. `task check --fix` and
148
+ `feature check --fix` repair structure, not semantics or Gherkin conversion.
149
+
150
+ Feature acceptance criteria must use valid BDD with a `Feature:` declaration and `Scenario:`
151
+ blocks. Raw legacy bullets need a deliberate conversion through:
152
+
153
+ ```bash
154
+ spur feature update <id> --section 'Acceptance Criteria' --from-file /tmp/<id>-ac.md
155
+ ```
156
+
157
+ Preserve each scenario's R-number and meaning. Use `@deprecated` and a Notes entry for a scenario
158
+ that is historical rather than a current requirement. If validation exposes an old hook or
159
+ lifecycle claim, check the current ADR/design owner instead of editing it blindly.
160
+
161
+ Preview lifecycle derivation before applying it, then regenerate derived projections only after
162
+ the corpus checks are understood:
163
+
164
+ ```bash
165
+ spur feature sync --all --dry-run --json
166
+ spur feature sync --all --json
167
+ spur feature refresh --all --json
168
+ ```
169
+
170
+ A missing, stale, running, or failed feature-verification receipt is unfinished work, not something
171
+ to hide by forcing a transition. Run `spur feature verify <id>` after the applicable full project
172
+ gate passes. Ordinary warnings can remain visible; do not manufacture a clean report by editing
173
+ history or suppressing findings.
174
+
175
+ ## 7. Final acceptance and rollback
176
+
177
+ Run the project gate and inspect the migration diff:
178
+
179
+ ```bash
180
+ spur self exec check
181
+ spur self exec check-feature # when closing a feature; full project gate
182
+ spur workflow list --json
183
+ spur task check --corpus --json
184
+ spur feature check --json
185
+ git diff --check
186
+ git status --short
187
+ ```
188
+
189
+ `check-feature` is the full project gate for feature closure, not a replacement for the default
190
+ incremental task gate. If an action is unbound, fix `builder.actions` instead of substituting a
191
+ command from another repository.
192
+
193
+ Stop on the first material error. Restore from the backup ref rather than running init or
194
+ bulk-deleting files:
195
+
196
+ ```bash
197
+ git diff <backup-ref> -- .spur/config.yaml docs/features docs/tasks*
198
+ git restore --source=<backup-ref> -- .spur/config.yaml docs/features docs/tasks*
199
+ git status --short
200
+ ```
201
+
202
+ Review new untracked files separately; `git restore` does not remove them. Reinstall the previous
203
+ CLI/plugin version and restore the database backup only after stopping the server. Keep failure
204
+ logs and durable evidence under `.spur/memory/`; `.spur/run/` is disposable scratch, not a rollback
205
+ authority.
206
+
207
+ ## Agent handoff
208
+
209
+ Give the downstream agent this boundary verbatim:
210
+
211
+ > Follow `plugins/sp/skills/spur-dev/references/migration-guide.md`. Preserve `.spur/config.yaml`,
212
+ > `docs/features/`, and `docs/tasks*/`. Use dry runs and CLI-gated writes. Do not run `init --force`,
213
+ > replace project workflows wholesale, rewrite historical corpus, or hide verification findings.
214
+ > Stop on the first material error and report it with its evidence.