@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.
- package/.claude-plugin/marketplace.json +1 -1
- package/config/config.global.yaml +4 -2
- package/config/decisions/gates.yaml +36 -0
- package/config/decisions/history-anatomy.yaml +35 -0
- package/config/decisions/idea-pipeline.yaml +38 -0
- package/config/plugin-scripts.json +15 -0
- package/config/rules/docs/sourced-api-claims.yaml +60 -0
- package/config/rules/recommended-pre-check.yaml +8 -3
- package/config/rules/structure/scratch-evidence-pointer.yaml +35 -0
- package/config/script-placement-baseline.json +2 -2
- package/config/templates/AGENTS.md +1 -1
- package/config/workflows/feature-lifecycle.yaml +9 -2
- package/config/workflows/history-anatomy.yaml +22 -0
- package/config/workflows/idea-pipeline.yaml +75 -0
- package/config/workflows/task-pipeline.yaml +216 -57
- package/config/workflows/wrapup-pipeline.yaml +107 -14
- package/package.json +10 -10
- package/plugins/sp/README.md +12 -3
- package/plugins/sp/agents/super-planner.md +16 -6
- package/plugins/sp/agents/super-reviewer.md +14 -0
- package/plugins/sp/bunfig.toml +8 -0
- package/plugins/sp/commands/dev-brainstorm.md +29 -16
- package/plugins/sp/commands/dev-find-way.md +80 -0
- package/plugins/sp/commands/dev-idea.md +6 -0
- package/plugins/sp/commands/dev-plan.md +6 -0
- package/plugins/sp/commands/dev-review-session.md +4 -1
- package/plugins/sp/commands/dev-run.md +12 -2
- package/plugins/sp/commands/dev-runall.md +32 -15
- package/plugins/sp/hooks/context-owner.ts +56 -0
- package/plugins/sp/hooks/context-post-tool.ts +23 -0
- package/plugins/sp/hooks/context-session-start.ts +49 -27
- package/plugins/sp/hooks/context-session-stop.ts +131 -30
- package/plugins/sp/hooks/pi/guard-extension.ts +21 -8
- package/plugins/sp/lib/idea-handoff.generated.mjs +43 -5
- package/plugins/sp/lib/inline-run-app.ts +28 -0
- package/plugins/sp/lib/inline-run.generated.d.mts +5 -0
- package/plugins/sp/lib/inline-run.generated.mjs +351 -46
- package/plugins/sp/lib/plan-projection.generated.d.mts +47 -0
- package/plugins/sp/lib/plan-projection.generated.mjs +368 -0
- package/plugins/sp/lib/quality-gate.generated.d.mts +35 -1
- package/plugins/sp/lib/quality-gate.generated.mjs +30296 -71
- package/plugins/sp/lib/residual-scan.generated.d.mts +19 -0
- package/plugins/sp/lib/residual-scan.generated.mjs +66 -0
- package/plugins/sp/lib/run-summary-core.ts +561 -0
- package/plugins/sp/lib/transcript.ts +150 -7
- package/plugins/sp/plugin.json +1 -1
- package/plugins/sp/references/roles.md +1 -1
- package/plugins/sp/scripts/batch-plan.mjs +488 -0
- package/plugins/sp/scripts/batch-plan.ts +145 -0
- package/plugins/sp/scripts/batch-preflight.mjs +51 -3
- package/plugins/sp/scripts/batch-preflight.ts +72 -1
- package/plugins/sp/scripts/commit-guard.mjs +216 -0
- package/plugins/sp/scripts/commit-guard.ts +249 -0
- package/plugins/sp/scripts/inline-run-dispatch.mjs +130 -0
- package/plugins/sp/scripts/inline-run-dispatch.ts +135 -0
- package/plugins/sp/scripts/inline-run-setup.mjs +562 -80
- package/plugins/sp/scripts/inline-run-setup.ts +52 -78
- package/plugins/sp/scripts/persist-out-check.mjs +90 -41
- package/plugins/sp/scripts/persist-out-check.ts +112 -57
- package/plugins/sp/scripts/pr-reviewing.mjs +19 -5
- package/plugins/sp/scripts/pr-reviewing.ts +34 -9
- package/plugins/sp/scripts/quality-gate.mjs +30213 -61
- package/plugins/sp/scripts/quality-gate.ts +21 -5
- package/plugins/sp/scripts/residual-scan.mjs +86 -31
- package/plugins/sp/scripts/residual-scan.ts +28 -30
- package/plugins/sp/scripts/run-summary.mjs +432 -14
- package/plugins/sp/scripts/run-summary.ts +41 -177
- package/plugins/sp/scripts/session-timeline.mjs +109 -11
- package/plugins/sp/scripts/session-timeline.ts +57 -19
- package/plugins/sp/scripts/task-diffstat.mjs +32 -29
- package/plugins/sp/scripts/task-diffstat.ts +34 -34
- package/plugins/sp/scripts/wrapup-steps.mjs +150 -2
- package/plugins/sp/scripts/wrapup-steps.ts +203 -1
- package/plugins/sp/skills/brainstorm/SKILL.md +9 -47
- package/plugins/sp/skills/branch-workflow/SKILL.md +1 -0
- package/plugins/sp/skills/branch-workflow/references/worktree-patterns.md +1 -0
- package/plugins/sp/skills/code-implementation/SKILL.md +48 -1
- package/plugins/sp/skills/code-verification/SKILL.md +3 -4
- package/plugins/sp/skills/code-verification/references/secu-review.md +3 -0
- package/plugins/sp/skills/code-verification/references/verdict-schema.md +68 -0
- package/plugins/sp/skills/fleet-join/SKILL.md +1 -1
- package/plugins/sp/skills/indexed-context/SKILL.md +14 -7
- package/plugins/sp/skills/parallel-execution/SKILL.md +2 -2
- package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +1 -1
- package/plugins/sp/skills/parallel-execution/references/fan-out-patterns.md +2 -2
- package/plugins/sp/skills/pr-reviewing/SKILL.md +7 -3
- package/plugins/sp/skills/session-review/SKILL.md +40 -7
- package/plugins/sp/skills/source-driven-development/SKILL.md +5 -0
- package/plugins/sp/skills/spec-decomposition/references/decomposition.md +5 -3
- package/plugins/sp/skills/spur-cli/SKILL.md +5 -2
- package/plugins/sp/skills/spur-cli/references/agent.md +20 -15
- package/plugins/sp/skills/spur-cli/references/decision.md +16 -8
- package/plugins/sp/skills/spur-cli/references/message.md +7 -7
- package/plugins/sp/skills/spur-cli/references/projects.md +7 -5
- package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +19 -3
- package/plugins/sp/skills/spur-cli/references/tasks.md +10 -7
- package/plugins/sp/skills/spur-cli/references/workflows/authoring-workflows.md +7 -0
- package/plugins/sp/skills/spur-cli/references/workflows.md +7 -2
- package/plugins/sp/skills/spur-composer/SKILL.md +1 -1
- package/plugins/sp/skills/spur-dev/SKILL.md +20 -14
- package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +33 -3
- package/plugins/sp/skills/spur-dev/references/cross-cutting.md +49 -14
- package/plugins/sp/skills/spur-dev/references/dev-operations.md +37 -17
- package/plugins/sp/skills/spur-dev/references/execution-batch-continuation.md +68 -0
- package/plugins/sp/skills/spur-dev/references/execution-batch-report.md +199 -0
- package/plugins/sp/skills/spur-dev/references/execution-batch.md +156 -1024
- package/plugins/sp/skills/spur-dev/references/execution-parallel-isolation.md +133 -0
- package/plugins/sp/skills/spur-dev/references/execution-workflow.md +6 -0
- package/plugins/sp/skills/spur-dev/references/execution-worktree-landing.md +471 -0
- package/plugins/sp/skills/spur-dev/references/execution-worktree-setup.md +379 -0
- package/plugins/sp/skills/spur-dev/references/flag-glossary.md +44 -12
- package/plugins/sp/skills/spur-dev/references/glossary.md +2 -2
- package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +340 -165
- package/plugins/sp/skills/spur-dev/references/structured-trace-emission.md +178 -0
- package/plugins/sp/skills/wayfinder/SKILL.md +10 -14
- package/schemas/state-machine-workflow.schema.json +23 -0
- package/spur.js +42402 -26889
- package/web/_astro/{BoardApp.VeoxxLBy.js → BoardApp.B3GQZvj8.js} +1 -1
- package/web/_astro/BoardApp.BT7L2kSb.js +324 -0
- package/web/_astro/TaskDetail.Cxov1_N_.js +1 -0
- package/web/_astro/{arc.f4e0OYLg.js → arc.vaT7tPOB.js} +1 -1
- package/web/_astro/{architectureDiagram-3BPJPVTR.SSIvxi-Z.js → architectureDiagram-3BPJPVTR.DRMmTjkN.js} +1 -1
- package/web/_astro/{blockDiagram-GPEHLZMM.DSXIHOFf.js → blockDiagram-GPEHLZMM.cla0LO_q.js} +1 -1
- package/web/_astro/{c4Diagram-AAUBKEIU.DG9Ubu85.js → c4Diagram-AAUBKEIU.D4YAIBKn.js} +1 -1
- package/web/_astro/channel.D4nG9YLf.js +1 -0
- package/web/_astro/{chunk-2J33WTMH.C7QU88Qh.js → chunk-2J33WTMH.BrSJbMRZ.js} +1 -1
- package/web/_astro/{chunk-4BX2VUAB.26Z94xBj.js → chunk-4BX2VUAB.CuLMgKF5.js} +1 -1
- package/web/_astro/{chunk-55IACEB6.DYRiBkqw.js → chunk-55IACEB6.zkvgu54F.js} +1 -1
- package/web/_astro/{chunk-727SXJPM.D5Vfv5pe.js → chunk-727SXJPM.DxWkACh8.js} +1 -1
- package/web/_astro/{chunk-AQP2D5EJ.DXHV47bN.js → chunk-AQP2D5EJ.42XrmIlH.js} +1 -1
- package/web/_astro/{chunk-FMBD7UC4.D1suAfOs.js → chunk-FMBD7UC4.Bao2wMK9.js} +1 -1
- package/web/_astro/{chunk-ND2GUHAM.D6BmdHEY.js → chunk-ND2GUHAM.BhydojD1.js} +1 -1
- package/web/_astro/{chunk-QZHKN3VN.rnPU-Ak-.js → chunk-QZHKN3VN.CmZ82g-H.js} +1 -1
- package/web/_astro/{classDiagram-4FO5ZUOK.CvEfXIo1.js → classDiagram-4FO5ZUOK.Blr83Gt_.js} +1 -1
- package/web/_astro/{classDiagram-v2-Q7XG4LA2.CvEfXIo1.js → classDiagram-v2-Q7XG4LA2.Blr83Gt_.js} +1 -1
- package/web/_astro/{cose-bilkent-S5V4N54A.DkMisLSm.js → cose-bilkent-S5V4N54A.qmfv0SPn.js} +1 -1
- package/web/_astro/{cynefin-OW5HDTMX.C77Q-pF6.js → cynefin-OW5HDTMX.BtELhXPR.js} +1 -1
- package/web/_astro/{dagre-BM42HDAG.YaV8ce27.js → dagre-BM42HDAG.AWmaAvXo.js} +1 -1
- package/web/_astro/{diagram-2AECGRRQ.CUyGEKge.js → diagram-2AECGRRQ.DdH34KDi.js} +1 -1
- package/web/_astro/{diagram-5GNKFQAL.CRgd8dgj.js → diagram-5GNKFQAL.BmNPix1k.js} +1 -1
- package/web/_astro/{diagram-KO2AKTUF.Bmzys9hq.js → diagram-KO2AKTUF.BNQd_Ppo.js} +1 -1
- package/web/_astro/{diagram-LMA3HP47.BvmJY4Lw.js → diagram-LMA3HP47.BAPgDi0e.js} +1 -1
- package/web/_astro/{diagram-OG6HWLK6.0hEhD30d.js → diagram-OG6HWLK6.DZ4zyLdC.js} +1 -1
- package/web/_astro/{erDiagram-TEJ5UH35.Bjt8lrnm.js → erDiagram-TEJ5UH35.Q1TySMmw.js} +1 -1
- package/web/_astro/{flowDiagram-I6XJVG4X.CJZTjRDV.js → flowDiagram-I6XJVG4X.BXhFBicG.js} +1 -1
- package/web/_astro/{ganttDiagram-6RSMTGT7._VqoVafc.js → ganttDiagram-6RSMTGT7.vHSgcuo2.js} +1 -1
- package/web/_astro/{gitGraphDiagram-PVQCEYII.CEDb7tVo.js → gitGraphDiagram-PVQCEYII.Bi1f73C7.js} +1 -1
- package/web/_astro/index.BhSwN8yY.css +1 -0
- package/web/_astro/{infoDiagram-5YYISTIA.CgwifPpK.js → infoDiagram-5YYISTIA.DPvXZEWm.js} +1 -1
- package/web/_astro/{ishikawaDiagram-YF4QCWOH.B99wx2J1.js → ishikawaDiagram-YF4QCWOH.Cz829fsV.js} +1 -1
- package/web/_astro/{journeyDiagram-JHISSGLW.2hRwJbEo.js → journeyDiagram-JHISSGLW.enRnB9Me.js} +1 -1
- package/web/_astro/{kanban-definition-UN3LZRKU.BahJkKNC.js → kanban-definition-UN3LZRKU.DnTNk6d2.js} +1 -1
- package/web/_astro/{linear.DguUUe6V.js → linear.BzGnBwNL.js} +1 -1
- package/web/_astro/{mermaid.core.CvgfmqVr.js → mermaid.core.CSbTpIVz.js} +4 -4
- package/web/_astro/{mindmap-definition-RKZ34NQL.B3qEA3x9.js → mindmap-definition-RKZ34NQL.DGJDy8zT.js} +1 -1
- package/web/_astro/{pieDiagram-4H26LBE5.FlWA-_ru.js → pieDiagram-4H26LBE5.HSPdi5_8.js} +1 -1
- package/web/_astro/{quadrantDiagram-W4KKPZXB.9bVn35X7.js → quadrantDiagram-W4KKPZXB.6Gv8mz2Y.js} +1 -1
- package/web/_astro/{requirementDiagram-4Y6WPE33.ChykIhct.js → requirementDiagram-4Y6WPE33.CnBCtFwa.js} +1 -1
- package/web/_astro/{sankeyDiagram-5OEKKPKP.Z2Y3hkYb.js → sankeyDiagram-5OEKKPKP.5M8VWAu8.js} +1 -1
- package/web/_astro/{sequenceDiagram-3UESZ5HK.J7JsHWDt.js → sequenceDiagram-3UESZ5HK.DN41XN-U.js} +1 -1
- package/web/_astro/{stateDiagram-AJRCARHV.DAPbiCSS.js → stateDiagram-AJRCARHV.ErOO3W8j.js} +1 -1
- package/web/_astro/{stateDiagram-v2-BHNVJYJU.D2jvSi0q.js → stateDiagram-v2-BHNVJYJU.B_ZHICM-.js} +1 -1
- package/web/_astro/{timeline-definition-PNZ67QCA.psW2ci29.js → timeline-definition-PNZ67QCA.CWdosr07.js} +1 -1
- package/web/_astro/{vennDiagram-CIIHVFJN.DlILYVmg.js → vennDiagram-CIIHVFJN.BHzYjNV5.js} +1 -1
- package/web/_astro/{wardleyDiagram-YWT4CUSO.xNWwLJnn.js → wardleyDiagram-YWT4CUSO.h8x4IwPX.js} +1 -1
- package/web/_astro/{xychartDiagram-2RQKCTM6.EU_BuH7V.js → xychartDiagram-2RQKCTM6.RTapW2X8.js} +1 -1
- package/web/index.html +2 -2
- package/plugins/sp/commands/dev-parallel.md +0 -31
- package/web/_astro/BoardApp.Bzr4OXrW.js +0 -324
- package/web/_astro/TaskDetail.LAyR_Pvn.js +0 -1
- package/web/_astro/channel.CUFdtWhm.js +0 -1
- 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-
|
|
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-
|
|
251
|
-
|
|
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
|
|
260
|
-
|
|
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
|
|
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)).
|
|
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-
|
|
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 `
|
|
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 `
|
|
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
|
|