@gobing-ai/spur 0.4.0 → 0.4.2

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 (172) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/config/config.global.yaml +4 -2
  3. package/config/decisions/gates.yaml +36 -0
  4. package/config/decisions/history-anatomy.yaml +35 -0
  5. package/config/decisions/idea-pipeline.yaml +38 -0
  6. package/config/plugin-scripts.json +15 -0
  7. package/config/rules/docs/sourced-api-claims.yaml +60 -0
  8. package/config/rules/recommended-pre-check.yaml +8 -3
  9. package/config/rules/structure/scratch-evidence-pointer.yaml +35 -0
  10. package/config/script-placement-baseline.json +2 -2
  11. package/config/templates/AGENTS.md +1 -1
  12. package/config/workflows/feature-lifecycle.yaml +9 -2
  13. package/config/workflows/history-anatomy.yaml +22 -0
  14. package/config/workflows/idea-pipeline.yaml +75 -0
  15. package/config/workflows/task-pipeline.yaml +216 -57
  16. package/config/workflows/wrapup-pipeline.yaml +107 -14
  17. package/package.json +10 -10
  18. package/plugins/sp/README.md +12 -3
  19. package/plugins/sp/agents/super-planner.md +16 -6
  20. package/plugins/sp/agents/super-reviewer.md +14 -0
  21. package/plugins/sp/bunfig.toml +8 -0
  22. package/plugins/sp/commands/dev-brainstorm.md +29 -16
  23. package/plugins/sp/commands/dev-find-way.md +80 -0
  24. package/plugins/sp/commands/dev-idea.md +6 -0
  25. package/plugins/sp/commands/dev-plan.md +6 -0
  26. package/plugins/sp/commands/dev-review-session.md +4 -1
  27. package/plugins/sp/commands/dev-run.md +12 -2
  28. package/plugins/sp/commands/dev-runall.md +32 -15
  29. package/plugins/sp/hooks/context-owner.ts +56 -0
  30. package/plugins/sp/hooks/context-post-tool.ts +23 -0
  31. package/plugins/sp/hooks/context-session-start.ts +49 -27
  32. package/plugins/sp/hooks/context-session-stop.ts +131 -30
  33. package/plugins/sp/hooks/pi/guard-extension.ts +21 -8
  34. package/plugins/sp/lib/idea-handoff.generated.mjs +43 -5
  35. package/plugins/sp/lib/inline-run-app.ts +28 -0
  36. package/plugins/sp/lib/inline-run.generated.d.mts +5 -0
  37. package/plugins/sp/lib/inline-run.generated.mjs +351 -46
  38. package/plugins/sp/lib/plan-projection.generated.d.mts +47 -0
  39. package/plugins/sp/lib/plan-projection.generated.mjs +368 -0
  40. package/plugins/sp/lib/quality-gate.generated.d.mts +35 -1
  41. package/plugins/sp/lib/quality-gate.generated.mjs +30296 -71
  42. package/plugins/sp/lib/residual-scan.generated.d.mts +19 -0
  43. package/plugins/sp/lib/residual-scan.generated.mjs +66 -0
  44. package/plugins/sp/lib/run-summary-core.ts +561 -0
  45. package/plugins/sp/lib/transcript.ts +150 -7
  46. package/plugins/sp/plugin.json +1 -1
  47. package/plugins/sp/references/roles.md +1 -1
  48. package/plugins/sp/scripts/batch-plan.mjs +488 -0
  49. package/plugins/sp/scripts/batch-plan.ts +145 -0
  50. package/plugins/sp/scripts/batch-preflight.mjs +51 -3
  51. package/plugins/sp/scripts/batch-preflight.ts +72 -1
  52. package/plugins/sp/scripts/commit-guard.mjs +216 -0
  53. package/plugins/sp/scripts/commit-guard.ts +249 -0
  54. package/plugins/sp/scripts/inline-run-dispatch.mjs +130 -0
  55. package/plugins/sp/scripts/inline-run-dispatch.ts +135 -0
  56. package/plugins/sp/scripts/inline-run-setup.mjs +562 -80
  57. package/plugins/sp/scripts/inline-run-setup.ts +52 -78
  58. package/plugins/sp/scripts/persist-out-check.mjs +90 -41
  59. package/plugins/sp/scripts/persist-out-check.ts +112 -57
  60. package/plugins/sp/scripts/pr-reviewing.mjs +19 -5
  61. package/plugins/sp/scripts/pr-reviewing.ts +34 -9
  62. package/plugins/sp/scripts/quality-gate.mjs +30213 -61
  63. package/plugins/sp/scripts/quality-gate.ts +21 -5
  64. package/plugins/sp/scripts/residual-scan.mjs +86 -31
  65. package/plugins/sp/scripts/residual-scan.ts +28 -30
  66. package/plugins/sp/scripts/run-summary.mjs +432 -14
  67. package/plugins/sp/scripts/run-summary.ts +41 -177
  68. package/plugins/sp/scripts/session-timeline.mjs +109 -11
  69. package/plugins/sp/scripts/session-timeline.ts +57 -19
  70. package/plugins/sp/scripts/task-diffstat.mjs +32 -29
  71. package/plugins/sp/scripts/task-diffstat.ts +34 -34
  72. package/plugins/sp/scripts/wrapup-steps.mjs +150 -2
  73. package/plugins/sp/scripts/wrapup-steps.ts +203 -1
  74. package/plugins/sp/skills/brainstorm/SKILL.md +9 -47
  75. package/plugins/sp/skills/branch-workflow/SKILL.md +1 -0
  76. package/plugins/sp/skills/branch-workflow/references/worktree-patterns.md +1 -0
  77. package/plugins/sp/skills/code-implementation/SKILL.md +48 -1
  78. package/plugins/sp/skills/code-verification/SKILL.md +3 -4
  79. package/plugins/sp/skills/code-verification/references/secu-review.md +3 -0
  80. package/plugins/sp/skills/code-verification/references/verdict-schema.md +68 -0
  81. package/plugins/sp/skills/fleet-join/SKILL.md +1 -1
  82. package/plugins/sp/skills/indexed-context/SKILL.md +14 -7
  83. package/plugins/sp/skills/parallel-execution/SKILL.md +2 -2
  84. package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +1 -1
  85. package/plugins/sp/skills/parallel-execution/references/fan-out-patterns.md +2 -2
  86. package/plugins/sp/skills/pr-reviewing/SKILL.md +7 -3
  87. package/plugins/sp/skills/session-review/SKILL.md +40 -7
  88. package/plugins/sp/skills/source-driven-development/SKILL.md +5 -0
  89. package/plugins/sp/skills/spec-decomposition/references/decomposition.md +5 -3
  90. package/plugins/sp/skills/spur-cli/SKILL.md +5 -2
  91. package/plugins/sp/skills/spur-cli/references/agent.md +20 -15
  92. package/plugins/sp/skills/spur-cli/references/decision.md +16 -8
  93. package/plugins/sp/skills/spur-cli/references/message.md +7 -7
  94. package/plugins/sp/skills/spur-cli/references/projects.md +7 -5
  95. package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +19 -3
  96. package/plugins/sp/skills/spur-cli/references/tasks.md +10 -7
  97. package/plugins/sp/skills/spur-cli/references/workflows/authoring-workflows.md +7 -0
  98. package/plugins/sp/skills/spur-cli/references/workflows.md +7 -2
  99. package/plugins/sp/skills/spur-composer/SKILL.md +1 -1
  100. package/plugins/sp/skills/spur-dev/SKILL.md +20 -14
  101. package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +33 -3
  102. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +49 -14
  103. package/plugins/sp/skills/spur-dev/references/dev-operations.md +37 -17
  104. package/plugins/sp/skills/spur-dev/references/execution-batch-continuation.md +68 -0
  105. package/plugins/sp/skills/spur-dev/references/execution-batch-report.md +199 -0
  106. package/plugins/sp/skills/spur-dev/references/execution-batch.md +156 -1024
  107. package/plugins/sp/skills/spur-dev/references/execution-parallel-isolation.md +133 -0
  108. package/plugins/sp/skills/spur-dev/references/execution-workflow.md +6 -0
  109. package/plugins/sp/skills/spur-dev/references/execution-worktree-landing.md +471 -0
  110. package/plugins/sp/skills/spur-dev/references/execution-worktree-setup.md +379 -0
  111. package/plugins/sp/skills/spur-dev/references/flag-glossary.md +44 -12
  112. package/plugins/sp/skills/spur-dev/references/glossary.md +2 -2
  113. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +340 -165
  114. package/plugins/sp/skills/spur-dev/references/structured-trace-emission.md +178 -0
  115. package/plugins/sp/skills/wayfinder/SKILL.md +10 -14
  116. package/schemas/state-machine-workflow.schema.json +23 -0
  117. package/spur.js +42402 -26889
  118. package/web/_astro/{BoardApp.VeoxxLBy.js → BoardApp.B3GQZvj8.js} +1 -1
  119. package/web/_astro/BoardApp.BT7L2kSb.js +324 -0
  120. package/web/_astro/TaskDetail.Cxov1_N_.js +1 -0
  121. package/web/_astro/{arc.f4e0OYLg.js → arc.vaT7tPOB.js} +1 -1
  122. package/web/_astro/{architectureDiagram-3BPJPVTR.SSIvxi-Z.js → architectureDiagram-3BPJPVTR.DRMmTjkN.js} +1 -1
  123. package/web/_astro/{blockDiagram-GPEHLZMM.DSXIHOFf.js → blockDiagram-GPEHLZMM.cla0LO_q.js} +1 -1
  124. package/web/_astro/{c4Diagram-AAUBKEIU.DG9Ubu85.js → c4Diagram-AAUBKEIU.D4YAIBKn.js} +1 -1
  125. package/web/_astro/channel.D4nG9YLf.js +1 -0
  126. package/web/_astro/{chunk-2J33WTMH.C7QU88Qh.js → chunk-2J33WTMH.BrSJbMRZ.js} +1 -1
  127. package/web/_astro/{chunk-4BX2VUAB.26Z94xBj.js → chunk-4BX2VUAB.CuLMgKF5.js} +1 -1
  128. package/web/_astro/{chunk-55IACEB6.DYRiBkqw.js → chunk-55IACEB6.zkvgu54F.js} +1 -1
  129. package/web/_astro/{chunk-727SXJPM.D5Vfv5pe.js → chunk-727SXJPM.DxWkACh8.js} +1 -1
  130. package/web/_astro/{chunk-AQP2D5EJ.DXHV47bN.js → chunk-AQP2D5EJ.42XrmIlH.js} +1 -1
  131. package/web/_astro/{chunk-FMBD7UC4.D1suAfOs.js → chunk-FMBD7UC4.Bao2wMK9.js} +1 -1
  132. package/web/_astro/{chunk-ND2GUHAM.D6BmdHEY.js → chunk-ND2GUHAM.BhydojD1.js} +1 -1
  133. package/web/_astro/{chunk-QZHKN3VN.rnPU-Ak-.js → chunk-QZHKN3VN.CmZ82g-H.js} +1 -1
  134. package/web/_astro/{classDiagram-4FO5ZUOK.CvEfXIo1.js → classDiagram-4FO5ZUOK.Blr83Gt_.js} +1 -1
  135. package/web/_astro/{classDiagram-v2-Q7XG4LA2.CvEfXIo1.js → classDiagram-v2-Q7XG4LA2.Blr83Gt_.js} +1 -1
  136. package/web/_astro/{cose-bilkent-S5V4N54A.DkMisLSm.js → cose-bilkent-S5V4N54A.qmfv0SPn.js} +1 -1
  137. package/web/_astro/{cynefin-OW5HDTMX.C77Q-pF6.js → cynefin-OW5HDTMX.BtELhXPR.js} +1 -1
  138. package/web/_astro/{dagre-BM42HDAG.YaV8ce27.js → dagre-BM42HDAG.AWmaAvXo.js} +1 -1
  139. package/web/_astro/{diagram-2AECGRRQ.CUyGEKge.js → diagram-2AECGRRQ.DdH34KDi.js} +1 -1
  140. package/web/_astro/{diagram-5GNKFQAL.CRgd8dgj.js → diagram-5GNKFQAL.BmNPix1k.js} +1 -1
  141. package/web/_astro/{diagram-KO2AKTUF.Bmzys9hq.js → diagram-KO2AKTUF.BNQd_Ppo.js} +1 -1
  142. package/web/_astro/{diagram-LMA3HP47.BvmJY4Lw.js → diagram-LMA3HP47.BAPgDi0e.js} +1 -1
  143. package/web/_astro/{diagram-OG6HWLK6.0hEhD30d.js → diagram-OG6HWLK6.DZ4zyLdC.js} +1 -1
  144. package/web/_astro/{erDiagram-TEJ5UH35.Bjt8lrnm.js → erDiagram-TEJ5UH35.Q1TySMmw.js} +1 -1
  145. package/web/_astro/{flowDiagram-I6XJVG4X.CJZTjRDV.js → flowDiagram-I6XJVG4X.BXhFBicG.js} +1 -1
  146. package/web/_astro/{ganttDiagram-6RSMTGT7._VqoVafc.js → ganttDiagram-6RSMTGT7.vHSgcuo2.js} +1 -1
  147. package/web/_astro/{gitGraphDiagram-PVQCEYII.CEDb7tVo.js → gitGraphDiagram-PVQCEYII.Bi1f73C7.js} +1 -1
  148. package/web/_astro/index.BhSwN8yY.css +1 -0
  149. package/web/_astro/{infoDiagram-5YYISTIA.CgwifPpK.js → infoDiagram-5YYISTIA.DPvXZEWm.js} +1 -1
  150. package/web/_astro/{ishikawaDiagram-YF4QCWOH.B99wx2J1.js → ishikawaDiagram-YF4QCWOH.Cz829fsV.js} +1 -1
  151. package/web/_astro/{journeyDiagram-JHISSGLW.2hRwJbEo.js → journeyDiagram-JHISSGLW.enRnB9Me.js} +1 -1
  152. package/web/_astro/{kanban-definition-UN3LZRKU.BahJkKNC.js → kanban-definition-UN3LZRKU.DnTNk6d2.js} +1 -1
  153. package/web/_astro/{linear.DguUUe6V.js → linear.BzGnBwNL.js} +1 -1
  154. package/web/_astro/{mermaid.core.CvgfmqVr.js → mermaid.core.CSbTpIVz.js} +4 -4
  155. package/web/_astro/{mindmap-definition-RKZ34NQL.B3qEA3x9.js → mindmap-definition-RKZ34NQL.DGJDy8zT.js} +1 -1
  156. package/web/_astro/{pieDiagram-4H26LBE5.FlWA-_ru.js → pieDiagram-4H26LBE5.HSPdi5_8.js} +1 -1
  157. package/web/_astro/{quadrantDiagram-W4KKPZXB.9bVn35X7.js → quadrantDiagram-W4KKPZXB.6Gv8mz2Y.js} +1 -1
  158. package/web/_astro/{requirementDiagram-4Y6WPE33.ChykIhct.js → requirementDiagram-4Y6WPE33.CnBCtFwa.js} +1 -1
  159. package/web/_astro/{sankeyDiagram-5OEKKPKP.Z2Y3hkYb.js → sankeyDiagram-5OEKKPKP.5M8VWAu8.js} +1 -1
  160. package/web/_astro/{sequenceDiagram-3UESZ5HK.J7JsHWDt.js → sequenceDiagram-3UESZ5HK.DN41XN-U.js} +1 -1
  161. package/web/_astro/{stateDiagram-AJRCARHV.DAPbiCSS.js → stateDiagram-AJRCARHV.ErOO3W8j.js} +1 -1
  162. package/web/_astro/{stateDiagram-v2-BHNVJYJU.D2jvSi0q.js → stateDiagram-v2-BHNVJYJU.B_ZHICM-.js} +1 -1
  163. package/web/_astro/{timeline-definition-PNZ67QCA.psW2ci29.js → timeline-definition-PNZ67QCA.CWdosr07.js} +1 -1
  164. package/web/_astro/{vennDiagram-CIIHVFJN.DlILYVmg.js → vennDiagram-CIIHVFJN.BHzYjNV5.js} +1 -1
  165. package/web/_astro/{wardleyDiagram-YWT4CUSO.xNWwLJnn.js → wardleyDiagram-YWT4CUSO.h8x4IwPX.js} +1 -1
  166. package/web/_astro/{xychartDiagram-2RQKCTM6.EU_BuH7V.js → xychartDiagram-2RQKCTM6.RTapW2X8.js} +1 -1
  167. package/web/index.html +2 -2
  168. package/plugins/sp/commands/dev-parallel.md +0 -31
  169. package/web/_astro/BoardApp.Bzr4OXrW.js +0 -324
  170. package/web/_astro/TaskDetail.LAyR_Pvn.js +0 -1
  171. package/web/_astro/channel.CUFdtWhm.js +0 -1
  172. package/web/_astro/index.Dg_3bOaJ.css +0 -1
@@ -0,0 +1,379 @@
1
+ ---
2
+ name: execution-worktree-setup
3
+ description: "Worktree batch start (task 1128 split): --worktree creation or adoption — WT-1 dirty-tree precheck, WT-2 create/reuse/evidence-staging/name resolution, WT-3 crash-safe marker and WT-3b the batch commit on the branch. Read it with --worktree at batch start; landing stays in execution-worktree-landing.md."
4
+ see_also:
5
+ - execution-batch
6
+ - execution-workflow
7
+ ---
8
+
9
+ # Worktree setup (WT-1…WT-3b)
10
+
11
+ Read with `--worktree` at batch start (task 1128 R1).
12
+
13
+ ## Worktree isolation (`--worktree [<name>]`)
14
+
15
+ When a batch command (`dev-runall`, `dev-refineall`, `dev-verifyall`) is invoked with
16
+ [`--worktree [<name>]`](flag-glossary.md#flag-worktree), the entire driver loop runs inside an
17
+ isolated git worktree instead of the operator's working directory. This section owns the worktree
18
+ lifecycle for the sequential batch loop. `--mode parallel` has its own per-task isolation — see
19
+ [§ Parallel isolation](execution-parallel-isolation.md#parallel-isolation---mode-parallel); `--worktree --mode parallel` is
20
+ rejected there (parallel mode already isolates each task in its own worktree).
21
+
22
+ **Startup ordering (task 0814 R3).** Resolve the selector/status filter and run the quick
23
+ command-aware readiness (the `quickReadiness` contract in `batch-preflight.ts`) **before** creating
24
+ or adopting the tree. The admission decision is what determines whether a tree should be cut at all;
25
+ all subsequent tools, agents, task/feature writes, and run artifacts use the confirmed execution
26
+ tree's cwd. A stale or empty selector, an unsupported mode, or an invalid target creates no tree and
27
+ no marker (WT-2/WT-7), and the required Git safety checks (WT-1) still precede creation.
28
+
29
+ > **Command wiring (task 0814 R3).** The four task-set worktree commands (`dev-run`, `dev-runall`,
30
+ > `dev-refineall`, `dev-verifyall`) each call `quickReadiness` with their operation (`run`/`refine`/
31
+ > `verify`), the resolved selector/status, and the filtered-set size **before** WT-1/WT-2. The
32
+ > admission outcome gates the tree: an invalid/empty selector, unsupported mode, or a target that
33
+ > quickReadiness marks `blocked`/`invalid` creates no tree and no marker (WT-2/WT-7); a
34
+ > `needs-refinement` refine batch is still work to do (the tree is created, the gaps are the work).
35
+ > The required Git safety checks (WT-1) still precede creation, and ownership/identity is confirmed
36
+ > before any tool, agent, corpus write, or run artifact. A later failure retains the tree with
37
+ > recovery information (WT-5).
38
+
39
+ **Single-task `dev-run` (batch of one).** `/sp:dev-run <wbs> --worktree [<name>]` runs this same
40
+ lifecycle with a one-task loop: WT-1…WT-6 apply unchanged, the marker's `command` is `dev-run` and
41
+ its `selector` is the `<wbs>` (so WT-6's command+selector fallback resolves the resume), and the
42
+ derived branch/directory slug is the WBS — `sp/run-<wbs>-<short-id>`. The WT-4 success condition
43
+ "no failed task" reads as "the task reached terminal `done` with no failed stage"; a failing gate, a
44
+ non-PASS verify verdict, or a HITL pause that ends the run take the WT-5 retention path. Only the
45
+ full pipeline is eligible — `--worktree --mode implement` is rejected (WT-7), because that mode is
46
+ the pipeline's implement stage and already runs in the driver's tree.
47
+
48
+ **Review triage `dev-review` (run of one).** `/sp:dev-review [--tasks <selector> | --feature <id>[,<id>] | --scope <path>[,<path>]] --triage --worktree [<name>]`
49
+ runs this lifecycle around one review-plus-triage pass: WT-1…WT-6 apply unchanged, the marker's
50
+ `command` is `dev-review` and its `selector` records the full normalized target list, and the slug
51
+ is `sp/review-<first>-and-<N>-<short-id>` for a multi-target run (N = target count) or
52
+ `sp/review-<slug>-<short-id>` for a single target (the WBS or the path's basename). It skips
53
+ `quickReadiness` (there is no task set; admission is "every target resolves" — each WBS/path must
54
+ resolve before the tree is cut). Under `--triage` the findings are bucketed across all targets once
55
+ (identical `file:line` findings deduped). WT-4 success reads as "every direct fix passed its check and the
56
+ project gate is green"; anything else takes WT-5. Contract: [dev-operations.md § 2. review](dev-operations.md#2-review).
57
+
58
+ **Wayfinding `dev-find-way` (run of one, mandatory).** `/sp:dev-find-way` always runs this
59
+ lifecycle — an omitted flag is create mode, never in-place. Marker `command` is `dev-find-way`,
60
+ `selector` is `chart:<destination-slug>` or `<feature-id>:<wbs>`, branch is
61
+ `sp/wayfind-<slug|wbs>-<short-id>`. It skips `quickReadiness` (admission is "the feature/ticket
62
+ resolves and no other `dev-find-way` marker holds the ticket"). WT-4 success reads as "the map
63
+ checks clean (chart) or the one ticket reached `done` (work)"; anything else takes WT-5. Contract:
64
+ [dev-operations.md § 12a. find-way](dev-operations.md#12a-find-way).
65
+
66
+ One flag, two modes (see the glossary entry for the ownership rule). Bare `--worktree` is **create
67
+ mode** (cut a fresh branch + sibling tree). `--worktree <name>` is **reuse mode** (attach to a tree
68
+ that already exists); name resolution (§ WT-2 below) runs before WT-1. The deltas each mode applies
69
+ are stated inline in WT-1…WT-4. `--continue` re-entry (WT-6) resolves by explicit name first, then
70
+ falls back to the command+selector marker scan.
71
+
72
+ The lifecycle wraps Steps 1–5 unchanged: a precheck creates or adopts the worktree before selector
73
+ resolution runs, the loop executes with the worktree as process cwd, and a terminal action merges or
74
+ retains after the batch report is emitted. Steps 1–5 themselves are not modified — only their cwd
75
+ differs.
76
+
77
+ **Per-call tree pinning (task 1058).** A host shell call starts in an arbitrary directory and
78
+ inherits no cwd from the previous call, so "the loop runs with the worktree as process cwd" is a
79
+ bootstrap convenience, never a carried guarantee. Every host command boundary in this lifecycle —
80
+ corpus reads/writes, the WT-3b commit, WT-4's merge and evidence persistence, the WT-4a
81
+ persist-out — re-selects its intended tree within the same call via the canonical per-call pin
82
+ protocol ([inline-pipeline-driver.md](inline-pipeline-driver.md) § "Per-call execution-tree
83
+ pin"): `cd --` to the quoted absolute tree, verify `pwd -P` against the recorded physical tree,
84
+ verify Git top-level and expected branch, then execute the already-resolved Spur invocation. The
85
+ identity is consumed, not re-derived: it is the WT-3 marker's confirmed `path` + `branch` (or the
86
+ resolved worktree's physical path + checked-out branch in reuse mode). The one deliberate tree
87
+ change is WT-4: the terminal merge actions select the **invoking** tree, not the execution tree —
88
+ and pin it explicitly the same way. FF ancestry, marker and cleanup sequencing remain owned by
89
+ 1059.
90
+
91
+ **Portability (R10).** Use portable `git worktree` commands only. Do **not** depend on the Claude
92
+ Code `EnterWorktree`/`ExitWorktree` tools — the `sp` plugin ships to Codex, Gemini CLI, pi, omp, and
93
+ OpenCode. The underlying git mechanics (create / list / remove / prune, sibling-directory naming,
94
+ disk-space awareness) are reused from [worktree-patterns.md](../../branch-workflow/references/worktree-patterns.md);
95
+ this section does not re-author them.
96
+
97
+ ### WT-1 — Dirty-tree precheck (R3)
98
+
99
+ `git worktree add` branches from a ref, so uncommitted changes in the main tree do **not** carry
100
+ into the worktree — a batch would silently run against different tree state than the operator sees.
101
+ Before creating the worktree, check the main tree:
102
+
103
+ ```bash
104
+ git status --porcelain
105
+ ```
106
+
107
+ - **Clean tree** → proceed to WT-2.
108
+ - **Dirty tree** → **abort** before any worktree is created. Name the offending files (from
109
+ `git status --porcelain`) and instruct the operator to commit or stash. No task work has run.
110
+ - **`--force`** → proceed past a dirty tree with a divergence warning that names the uncommitted
111
+ files. The worktree is created and the batch proceeds against the committed base ref, not the
112
+ operator's working-directory state.
113
+
114
+ **Reuse-mode delta.** The main-tree precheck is unchanged — the divergence hazard is identical (the
115
+ batch still runs somewhere the operator is not standing). The *target* worktree being dirty is
116
+ **expected** (it holds retained partial work from a prior halt) and must **not** abort: report the
117
+ file list once and proceed. The batch runs against the target worktree's working-directory state, not
118
+ a clean checkout — which is exactly the point of reuse mode.
119
+
120
+ ### WT-2 — Worktree creation or adoption
121
+
122
+ **Name resolution runs first** for both modes — bare `--worktree` skips it (no name to resolve);
123
+ `--worktree <name>` must resolve before WT-1's precheck touches anything. Resolution is specified
124
+ in [§ Name resolution](#name-resolution---worktree-name) below; this section covers creation
125
+ (create mode) and adoption (reuse mode).
126
+
127
+ #### Create mode (bare `--worktree`)
128
+
129
+ Create one worktree on a new branch cut from the current HEAD's ref (the **base ref** — often a
130
+ `feat/…` branch, not literally `main`). Location follows the sibling-directory convention in
131
+ [worktree-patterns.md](../../branch-workflow/references/worktree-patterns.md):
132
+
133
+ **Location rule (0948 R9) — never under `.spur/`.** The default root is the **sibling** directory
134
+ (`../<repo>-<command>-<selector-slug>-<short-id>`). A worktree nested under `.spur/` breaks Biome's
135
+ vcs-root detection: `bunx biome check .` inside it reports `Checked 0 files`, so lint/format silently
136
+ no-op for the whole run. Verified in both directions — a sibling worktree reports a non-zero file
137
+ count (`Checked 1076 files` at the time of the fix) while a `.spur/`-nested one reports
138
+ `Checked 0 files`. If a project's tooling needs a custom root, keep it **outside** any path that a
139
+ VCS-root-detecting tool treats as ignorable.
140
+
141
+ ```bash
142
+ BASE_REF=$(git rev-parse --abbrev-ref HEAD)
143
+ BASE_SHA=$(git rev-parse HEAD)
144
+ BRANCH="sp/<command>-<selector-slug>-<short-id>" # e.g. sp/runall-h1-a3f2
145
+ # `git worktree add -b` creates the branch BEFORE the directory, so a failed create leaves a
146
+ # dangling branch and the natural retry dies on "a branch named ... already exists"
147
+ # (task 0701 R2b). Wrap the create: on failure, delete the branch — or derive a fresh
148
+ # short-id per attempt — before surfacing the error.
149
+ git worktree add "../<repo>-<command>-<selector-slug>-<short-id>" -b "$BRANCH" "$BASE_REF" \
150
+ || { git branch -D "$BRANCH"; false; }
151
+ # WT-2r — register the worktree in ~/.config/spur/projects.json so the Board project switcher
152
+ # lists it; WT-4c deregisters it. Best-effort: a registry failure never blocks the run.
153
+ spur projects add "../<repo>-<command>-<selector-slug>-<short-id>" --json >/dev/null 2>&1 || true
154
+ ```
155
+
156
+ Reuse mode does not re-register: `projects add` rewrites `port` to `0`, which would clobber the
157
+ port of a live serve in an adopted tree. A served tree is already registered by `spur serve`.
158
+
159
+ **Worktree root is outside `.spur/` (0948 R9).** The default create path is that
160
+ sibling directory, which sits next to the repository and not under it. Do not
161
+ put the default root at `.spur/worktrees` or any other gitignored path: Biome's
162
+ `vcs.useIgnoreFile` then treats the checkout as empty ("Checked 0 files") and
163
+ the quality gate cannot see the tree. Same class as the eval-pipeline worktree
164
+ move off `.spur/tmp/` (task 0610).
165
+
166
+ Branch and directory names are derived (command + selector slug + short id); the create path never
167
+ takes an operator-supplied name (R8.3 — no create-with-name; `--worktree <name>` where `<name>` does
168
+ not resolve is an error, not a create).
169
+
170
+ A fresh worktree has no `node_modules` (gitignored), so the first `bun test` or
171
+ typecheck fails on the first workspace import. Install before any task work:
172
+
173
+ cd "../<worktree-dir>" && bun install --frozen-lockfile --ignore-scripts
174
+
175
+ `--frozen-lockfile` pins the worktree to `bun.lock` rather than re-resolving,
176
+ so the worktree's dependency tree matches the base ref's. `--ignore-scripts` is required, not
177
+ stylistic (task 0701 R2a): worktrees share the main tree's `.git`, and this repo's `prepare`
178
+ script is `lefthook install` (`package.json`) — a bare install rewrites the operator's
179
+ main-repo hooks from inside the "isolated" tree. Scripts are skipped only at this call site;
180
+ a normal clone keeps `prepare`. The worktree still gets a usable dependency tree — the install
181
+ exists so the first `bun test` resolves workspace imports.
182
+
183
+ #### Reuse mode (`--worktree <name>`)
184
+
185
+ Creation is **skipped entirely**. `$BRANCH` is the resolved worktree's already-checked-out branch; a
186
+ detached HEAD aborts (no branch can serve as `$BRANCH` for WT-4's FF-merge). `BASE_REF` is the
187
+ invoking tree's current HEAD ref (not the worktree's branch) and `BASE_SHA` is
188
+ `git merge-base <BASE_REF> <BRANCH>` — so WT-4's FF-merge lands the worktree's accumulated commits
189
+ onto the invoking tree's base ref, exactly as create mode does.
190
+
191
+ `bun install --frozen-lockfile --ignore-scripts` runs **only when `node_modules` is absent** in
192
+ the resolved worktree (same `--ignore-scripts` rationale as create mode — task 0701 R2a). A warm reused tree does not re-pay the install; a cold one (hand-made, or a retained tree
193
+ whose deps were removed) installs exactly once before the first task. This is the R3 conditional
194
+ install rule (source: task 0481) — create mode always installs because a fresh tree is always cold.
195
+
196
+ After creation or adoption, immediately write/adopt the state marker (WT-3), then run the
197
+ existing batch loop (Steps 1–5) with the worktree as process cwd. `spur workflow run` resolves cwd
198
+ from the process (`apps/cli/src/commands/workflow.ts:124`), so no CLI change is needed — `cd` into
199
+ the worktree directory before launching the loop.
200
+
201
+ #### Evidence staging before the first task (create and reuse mode)
202
+
203
+ `.spur/memory/evidence/` and `.spur/run/` are **untracked per-tree** planes, so a fresh worktree
204
+ starts with neither while the invoking tree holds every earlier task's verdict. Both
205
+ `preflightFeature` (`plugins/sp/scripts/wrapup-steps.ts` → `spur feature check --strict --as done`
206
+ with cwd = the worktree) and `runMetrics` resolve verdict artifacts relative to the tree they run
207
+ in, so without this step an already-`done` linked task reads as missing evidence
208
+ (`L4.evidence-not-recoverable`, `L4.scenario-unverified`) and its metrics row degrades to
209
+ `UNKNOWN`.
210
+
211
+ Stage the invoking tree's verdict artifacts into the worktree **before the first task runs** —
212
+ from the invoking tree (cwd), with `$WT` the resolved absolute worktree path. `cp -n` is
213
+ load-bearing: reuse mode may be re-entering a tree that already owns divergence-checked evidence,
214
+ and this step must never clobber it. Only `*-verdict.json` travels in each direction; receipts and
215
+ other scratch artifacts are not staged, so WT-4a's identity classification is unaffected.
216
+
217
+ ```bash
218
+ # Run from the INVOKING tree; $WT is the worktree (create- or reuse-mode) absolute path.
219
+ for d in .spur/memory/evidence .spur/run; do
220
+ mkdir -p "$WT/$d"
221
+ for f in "$d"/*-verdict.json; do [ -f "$f" ] && cp -n "$f" "$WT/$d/"; done
222
+ done
223
+ ```
224
+
225
+ The position relative to the dependency install is immaterial (this is a plain copy into an
226
+ untracked plane); the position relative to the **first task** is not — a preflight or metrics read
227
+ that runs before this step sees an empty evidence plane.
228
+
229
+ #### Name resolution (`--worktree <name>`)
230
+
231
+ <a id="name-resolution---worktree-name"></a>
232
+
233
+ Authority: **git**, not the marker store — a marker may be stale, git is not. A foreign worktree
234
+ with no marker is a valid target (R3 synthesizes one). Resolve `<name>` against
235
+ `git worktree list --porcelain`, matching in this order and stopping at the first tier that yields
236
+ ≥1 hit:
237
+
238
+ 1. **exact `worktree <path>`** (after path normalization against the invoking tree)
239
+ 2. **`basename(<path>)`**
240
+ 3. **checked-out branch** — accept both `<name>` and the full `refs/heads/<name>` form
241
+
242
+ Then require exactly one survivor across the tiers:
243
+
244
+ - **0 hits** → abort before any task work. Print each candidate worktree as
245
+ `<basename> <branch> <path>`, and the line: *"`--worktree <name>` selects an existing worktree;
246
+ it never creates one. Use bare `--worktree` to create."*
247
+ - **≥2 hits** → abort naming the candidates and require the path form (tier 1).
248
+ - **1 hit, but** the worktree is `locked`, `prunable`, or belongs to a different repo → abort naming
249
+ the condition.
250
+
251
+ ### `spur` on PATH is not this checkout
252
+
253
+ `spur` (`~/.bun/bin/spur`) resolves to a *published* bundle in `~/node_modules/`,
254
+ not to the repo you are standing in and not to the worktree. `resolveSpurBin()`
255
+ propagates whichever binary you entered through into `vars.spurBin`, which the
256
+ `task-lifecycle.yaml` guards run as `$spurBin task check` — so one wrong entry
257
+ point silently gate-checks against the published bundle.
258
+
259
+ Inside a worktree, and in the monorepo whenever CLI behavior is under test, invoke
260
+ the tree's own source:
261
+
262
+ cd "<worktree>" && bun apps/cli/src/index.ts task check <wbs> --json
263
+
264
+ Run that as a per-call pin subshell (task 1058) — `cd --` plus the `pwd -P` / git-top-level /
265
+ branch identity checks of the canonical protocol (inline-pipeline-driver.md § "Per-call
266
+ execution-tree pin") — rather than relying on a persistent `cd` between host tool calls.
267
+
268
+ Confirm isolation by making a distinctive change in the worktree and checking that
269
+ the command reflects it.
270
+
271
+ **General rule — every path-resolving tool, not just `spur`.** The same failure class is not
272
+ limited to the CLI on PATH. A host-agent file-edit or hash/`hashline` tool may resolve main-repo
273
+ paths while the shell `cwd` is the worktree, silently acting on the wrong tree. Before relying on any
274
+ path-resolving tool inside a `--worktree` batch, verify it is acting on the worktree — for example
275
+ by making a distinctive change and confirming the path the tool reports matches the worktree. When a
276
+ tool cannot be pointed at the worktree, fall back to `perl -i` in-place edits (or the agent's `write`
277
+ verb) whose path argument you control.
278
+
279
+ ### WT-3 — Crash-safe state marker (R6)
280
+
281
+ Worktree identity lives on disk under `.spur/run/`, not only in the orchestrator's memory, so a
282
+ session that dies mid-batch is recoverable. Write the marker at creation and update it at the
283
+ terminal transition (merged / retained). The marker is written to the **invoking** tree's
284
+ `.spur/run/` (task 0701 R2c) — the tree where the driver process started, not the worktree's own
285
+ `.spur/run/` — so WT-6's resume scan finds it regardless of where the operator stands. Schema:
286
+
287
+ ```json
288
+ {
289
+ "id": "<marker-id>",
290
+ "path": "../<repo>-<command>-<selector-slug>-<short-id>",
291
+ "branch": "sp/<command>-<selector-slug>-<short-id>",
292
+ "baseRef": "feat/example",
293
+ "baseSha": "<sha-at-creation>",
294
+ "command": "dev-runall",
295
+ "selector": "feature:H1",
296
+ "createdAt": "<iso-8601>",
297
+ "status": "active"
298
+ }
299
+ ```
300
+
301
+ `status` transitions: `active` → `merged` (WT-4 success) | `retained` (WT-5 failure/halt/non-FF),
302
+ and `retained` → `active` on a reuse re-entry (WT-6). The marker file is named
303
+ `.spur/run/worktree-<marker-id>.json`. It is the authority for WT-6 resume and for operator recovery
304
+ after a crash: a killed session leaves the marker at `status: active`, which the operator reads to
305
+ find the worktree path, branch, and base ref.
306
+
307
+ **Reuse-mode marker adoption.** Two new optional fields record when a run did not create the tree:
308
+
309
+ ```json
310
+ {
311
+ "adopted": true,
312
+ "adoptedAt": "<iso-8601>"
313
+ }
314
+ ```
315
+
316
+ `adopted` is what WT-4 reads to decide retain-vs-remove, so it is set whenever the current run did
317
+ not create the tree — including when reuse mode adopts a marker that create mode originally wrote.
318
+ It records "this run did not create this tree", not "this tree was never created by the flag".
319
+
320
+ Reuse mode resolves the marker by the resolved worktree's `path` (not by `command`+`selector`):
321
+
322
+ - **Existing marker for that path** → adopt it in place: update `command`/`selector` to the current
323
+ invocation, set `status` to `active`, set `adopted: true` + `adoptedAt`, **preserve `baseRef` and
324
+ `baseSha`**. This makes cross-command resume — `dev-runall` halted, now `dev-verifyall` over the
325
+ same tree — a supported path (R5.2).
326
+ - **No marker** (hand-made or foreign worktree) → synthesize one with `baseRef` = the invoking
327
+ tree's current HEAD ref, `baseSha` = `git merge-base <baseRef> <BRANCH>`, `adopted: true`.
328
+ - **Marker already at `status: active`** → **abort** — another session may own that tree
329
+ (AGENTS.md one-writer-per-tree; task 0487 R5). Overridable with `--force` (the operator can tell
330
+ a crashed-session marker from a live-session one; the harness cannot).
331
+
332
+ **Commit fingerprint (1129 R1).** As soon as the run's identity exists — before the first task
333
+ writes — fingerprint **the tree that will be committed** under the batch's run id (`$RUN_ID`: the
334
+ WT-3 marker's `id`, i.e. `<command>-<selector-slug>-<short-id>`), so the WT-3b/integration commit
335
+ has a start point to compare against. The artifact is cwd-relative under `.spur/run/` (gitignored
336
+ per tree), so the fingerprint and the commit that consumes it must select the SAME tree: in create
337
+ and reuse mode that is the worktree, because WT-3b commits there; a batch without `--worktree`
338
+ fingerprints the invoking tree, which is also where its commit lands. The conflict recipe
339
+ fingerprints the invoking tree for the same reason (its own step 1b).
340
+
341
+ ```bash
342
+ GUARD=plugins/sp/scripts/commit-guard.ts; [ -f config/plugin-scripts.json -a -f "$GUARD" ] || GUARD="$(superskill script path sp commit-guard.mjs 2>/dev/null)"
343
+ # Pinned subshell, same discipline as WT-3b: select the execution tree for this one call.
344
+ (
345
+ cd -- "../<worktree-dir>" || { echo "tree missing: expected ../<worktree-dir>" >&2; exit 1; }
346
+ [ "$(git branch --show-current)" = "$BRANCH" ] \
347
+ || { echo "branch mismatch: expected $BRANCH, got $(git branch --show-current)" >&2; exit 1; }
348
+ RUN_ID="<marker-id>" # the WT-3 marker's id — the same id WT-3b's stage call uses
349
+ bun "$GUARD" start --run "$RUN_ID" # <worktree>/.spur/run/$RUN_ID-tree-start.json = { head, dirty[] }
350
+ )
351
+ ```
352
+
353
+ ### WT-3b — Commit the batch's writes on `$BRANCH` (task 0701 R1)
354
+ Before any terminal action, commit the batch's corpus writes **on `$BRANCH`, inside the
355
+ worktree** — including the generated task files under `docs/tasks*/` and the kanban index. The
356
+ commit runs as a per-call pinned subshell (task 1058): it selects the execution tree inside the
357
+ same call, verifies the WT-3 identity, and never relies on a persistent `cd` or a trailing
358
+ `cd -` to restore the caller's directory:
359
+
360
+ ```bash
361
+ (
362
+ cd -- "../<worktree-dir>" || { echo "tree missing: expected ../<worktree-dir>" >&2; exit 1; }
363
+ [ "$(git branch --show-current)" = "$BRANCH" ] \
364
+ || { echo "branch mismatch: expected $BRANCH, got $(git branch --show-current)" >&2; exit 1; }
365
+ GUARD=plugins/sp/scripts/commit-guard.ts; [ -f config/plugin-scripts.json -a -f "$GUARD" ] || GUARD="$(superskill script path sp commit-guard.mjs 2>/dev/null)"
366
+ bun "$GUARD" check --run "$RUN_ID" # 1129 R3: concurrent foreign writers; a non-empty list goes in the batch report
367
+ bun "$GUARD" stage --run "$RUN_ID" -- <files-the-batch-wrote> \
368
+ || { echo "WT-3b halt: commit-guard refused a path (foreign, unmerged or conflict-marked); nothing committed" >&2; exit 1; }
369
+ git commit -m "<type>(<scope>): <command> <selector> batch writes"
370
+ )
371
+ ```
372
+
373
+ > **Forbidden in every driver commit step:** `git add -A` and `git add .`. They stage whatever a
374
+ > concurrent writer happened to leave in the tree — the two incidents this guard exists for are
375
+ > `a94f9f431` and `36f274590` — so a driver stages only through `commit-guard stage`.
376
+
377
+ The FF-only git merge carries only commits — uncommitted writes in the worktree would be left
378
+ behind by the merge and then destroyed by create mode's `git worktree remove`. WT-3b exists so
379
+ that can never happen.
@@ -146,15 +146,43 @@ Batch operation only (`dev-refineall`, `dev-runall`). When a task in the batch
146
146
  fails, skip its in-batch dependents and continue the independent ones, instead of the default
147
147
  halt-on-first-failure. Never silently retried; the failure is still reported.
148
148
 
149
+ ### `--defer-gate` — opt-in parallel-batch gate policy (task 1111 / H15)
150
+
151
+ **Applies to:** `/sp-dev-runall --mode parallel`, and `--mode auto` when it resolves to parallel.
152
+ **Default:** off — every task pipeline runs its own FULL project gate inside its worktree.
153
+
154
+ With `--defer-gate`, each task's `test` / `test-recheck` hop runs the **light tier** (changed-scope
155
+ format, per-workspace typecheck, related tests) and writes `DEFERRED` — never `PASS` — to
156
+ `.spur/run/<wbs>-test-gate.status`. The orchestrator then owes **one integrated full gate** on the
157
+ base ref over the merged slices, **before** the deferred feature sync; on FAIL the batch verdict is
158
+ FAIL, the feature sync is skipped, and the report lists a per-branch re-gate command for each
159
+ branch newest-first (no automatic bisect). Report rows of deferred tasks carry `gate: deferred`.
160
+
161
+ Two properties are load-bearing and are asserted structurally:
162
+
163
+ - **Early feedback survives.** The light tier still runs per task, so an obviously broken slice
164
+ fails inside its own worktree instead of at the end of the batch (the reason ADR-124 rejected an
165
+ unconditional single end-of-run gate).
166
+ - **The full tier is still the only `PASS` writer.** Only the integrated run can claim a green
167
+ project gate; the per-task token is `DEFERRED`, and the `test → triage` /
168
+ `test-recheck → triage` guards accept it only while `deferQualityGate = "true"`.
169
+
170
+ `--defer-gate` with `--mode sequential` (or omitted `--mode`) is rejected — the flag exists to move
171
+ one full gate from N worktrees to the one place the integrated tree exists. Under `--mode auto` it
172
+ applies only if the batch resolves to parallel; a sequential resolution drops it with a report note.
173
+ Sequential and inline batches never set the var. ADR-124 carries the dated clarification.
174
+
175
+ **Anchor:** `#flag-defer-gate`.
176
+
149
177
  ### `--concurrency <n>` — parallel batch worker bound
150
178
 
151
179
  **Anchor:** `#flag-concurrency`.
152
180
 
153
- `dev-runall` under `--mode parallel` (task 0931): at most `<n>` task pipelines run at once
181
+ `dev-runall` under `--mode parallel` (task 0931), or `--mode auto` resolved to parallel: at most `<n>` task pipelines run at once
154
182
  (default 2, `n ≥ 1`). A dependent task starts only after every in-set dependency has been
155
183
  **integrated** onto the base ref — see
156
184
  [execution-batch.md § Parallel isolation](execution-batch.md#parallel-isolation---mode-parallel).
157
- Ignored in sequential mode. Each worker is one more concurrent quality gate; raise it only when
185
+ Ignored in sequential mode; `--concurrency 1` pins `--mode auto` to sequential. Each worker is one more concurrent quality gate; raise it only when
158
186
  the host has the CPU for it.
159
187
 
160
188
  ### `--continue` — resume an interrupted batch from checkpoint
@@ -173,7 +201,8 @@ offers `--continue` and `--next` as competing options only when the batch was in
173
201
  After the main step completes, run the wrap hop (learnings, metrics, doc-sync). On `dev-runall`
174
202
  with `--next`, wrap runs **once for the batch** after every task reaches terminal status, mirroring
175
203
  the batch-once shippable gate `dev-verifyall` uses. Without `--next`, `--wrap` is wrap-without-
176
- chaining — the single task or batch wraps without advancing the lifecycle.
204
+ chaining — the single task or batch wraps without advancing the lifecycle. On `dev-find-way` it
205
+ wraps the one resolved ticket inside the worktree before the merge, and is skipped in chart mode.
177
206
 
178
207
  ### `--force` — bypass a named guard
179
208
 
@@ -243,12 +272,12 @@ is the contract; divergence between `--dry-run` and the real run is a bug.
243
272
 
244
273
  **Anchor:** `#flag-tasks`.
245
274
 
246
- Batch operation (`dev-parallel`, `dev-refineall`, `dev-review`, `dev-runall`, `dev-verifyall`). An
275
+ Batch operation (`dev-refineall`, `dev-review`, `dev-runall`, `dev-verifyall`). An
247
276
  explicit selector — WBS list, status pseudo-list (`todo`, `wip`), `feature:<id>`, or `ready` —
248
277
  resolving to the set the batch runs over. On `dev-review` the selector is restricted to the
249
278
  review-safe forms: comma WBS list and `feature:<id>` — status pseudo-lists and `ready` are
250
- rejected (they select work to do, not work to review). Required on `dev-parallel`, `dev-runall`,
251
- and `dev-verifyall`, where `--feature` is an optional restrictor. On `dev-refineall` it is instead
279
+ rejected (they select work to do, not work to review). Required on `dev-runall` and
280
+ `dev-verifyall`, where `--feature` is an optional restrictor. On `dev-refineall` it is instead
252
281
  one of a required pair — supply exactly one of `--feature` or `--tasks`.
253
282
 
254
283
  ### `--mode <kind>` — select an execution mode
@@ -256,8 +285,9 @@ one of a required pair — supply exactly one of `--feature` or `--tasks`.
256
285
  **Anchor:** `#flag-mode`.
257
286
 
258
287
  Select an execution mode: `full|implement` on `dev-run` (full pipeline vs implement-only),
259
- `sequential|parallel` on `dev-runall` (serial vs fanned-out-independent-subset),
260
- `fan-out|review-panel|investigation` on `dev-parallel`, the reconstruction depth
288
+ `sequential|parallel|auto` on `dev-runall` (serial, fanned-out independent subset, or chosen from the
289
+ frozen batch's dependency waves — see [execution-batch.md § 2.4](execution-batch.md#24-topological-sort)),
290
+ the reconstruction depth
261
291
  `briefing|structure|architecture|design|full` on `dev-reverse`, and `daily|ad-hoc` on
262
292
  `dev-find-issue` (the history-anatomy report mode). Mode selection is explicit and orthogonal
263
293
  to `--next`.
@@ -463,11 +493,13 @@ of `--fix auto` ([`--fix`](#flag-fix)).
463
493
 
464
494
  **Anchor:** `#flag-worktree`.
465
495
 
466
- Batch commands plus single-task `dev-run` and review triage (`dev-refineall`, `dev-runall`,
467
- `dev-verifyall`, `dev-run`, `dev-review`): run the entire driver loop inside an isolated git
496
+ Batch commands plus single-task `dev-run`, review triage and wayfinding (`dev-refineall`, `dev-runall`,
497
+ `dev-verifyall`, `dev-run`, `dev-review`, `dev-find-way`): run the entire driver loop inside an isolated git
468
498
  worktree instead of the operator's working directory. On `dev-review` the flag requires `--triage`
469
499
  and wraps the review-plus-triage pass
470
- ([dev-operations.md § 2. review](dev-operations.md#2-review)). One flag, two modes:
500
+ ([dev-operations.md § 2. review](dev-operations.md#2-review)). On `dev-find-way` isolation is
501
+ mandatory: omitting the flag means create mode
502
+ ([dev-operations.md § 12a. find-way](dev-operations.md#12a-find-way)). One flag, two modes:
471
503
 
472
504
  - **Create mode** — bare `--worktree` (no value). Cut a fresh branch from the current HEAD's ref,
473
505
  create a sibling worktree with a derived name, run the batch there. On a fully successful batch
@@ -477,7 +509,7 @@ and wraps the review-plus-triage pass
477
509
  - **Reuse mode** — `--worktree <name>` / `--worktree=<name>`. Attach the batch to a worktree that
478
510
  already exists. `<name>` resolves against `git worktree list --porcelain` (exact path → basename →
479
511
  checked-out branch); exactly one match must survive or the batch aborts **before any task work**
480
- (see [execution-batch.md § Name resolution](execution-batch.md#name-resolution---worktree-name)).
512
+ (see [execution-worktree-setup.md § Name resolution](execution-worktree-setup.md#name-resolution---worktree-name)).
481
513
  Reuse mode **never creates a worktree** — an unresolvable name is an error, not a create. The batch
482
514
  adopts the worktree's checked-out branch (a detached HEAD aborts), adopts or synthesizes the
483
515
  `.spur/run/` state marker, and runs. On a fully successful batch the branch is fast-forward-merged
@@ -75,12 +75,12 @@ can only route *around* one whose objective precondition is already met (see the
75
75
  routing contract in `cross-cutting.md`). A `decision` option (0911) pins that action's policy:
76
76
  `mode: never` forces the human responder, `mode: evidence` lets the optional DecisionMaker answer
77
77
  only from verified prior action evidence (deferring otherwise), and absence keeps the 0910
78
- implicit behavior when `workflow.hitlDecisionMaker` is enabled.
78
+ implicit behavior when `workflows.hitlDecisionMaker` is enabled.
79
79
  Avoid: *prompt* (reserved for LLM input text), *interrupt* (implies an exception, not a planned
80
80
  pause point).
81
81
 
82
82
  **DecisionMaker** — optional provider-backed responder for executed `hitl.confirm`/`hitl.select`
83
- actions (ADR-123), enabled via `workflow.hitlDecisionMaker: true` and `TYPESAFE_API_KEY`.
83
+ actions (ADR-123), enabled via `workflows.hitlDecisionMaker: true` and `TYPESAFE_API_KEY`.
84
84
  Evidence answers clear the answer variable and record `statusVar: accepted/deferred`; unresolved
85
85
  cases defer or delegate to the human. Offline readiness: `spur self status`.
86
86