@delegance/claude-autopilot 7.11.0-pre.3 → 7.11.1

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/CHANGELOG.md CHANGED
@@ -2,6 +2,178 @@
2
2
 
3
3
  - v5.6 Phase 7 (docs reconciliation) — pending.
4
4
 
5
+ ## 7.11.1 — 2026-05-25
6
+
7
+ ### Added
8
+
9
+ - **Concurrent multi-PR dispatch default in `skills/autopilot/SKILL.md`.** When the user describes multiple independent deliverables in one invocation, the autopilot skill now instructs dispatch as parallel Agent subagent invocations (each in its own worktree-isolated branch). Only serializes on explicit user request or genuine cross-PR dependency. Previously this default was only documented in operator-side overrides.
10
+
11
+ ## 7.11.0 — 2026-05-20
12
+
13
+ **v7.11.0 — Concurrent subagent dispatch (GA).** This release closes the
14
+ v7.11.0 stack landed as `v7.11.0-pre.1` through `v7.11.0-pre.5` and ships
15
+ the user-facing skill + schema + release wiring. The implementation was
16
+ split into six PRs for reviewability (see PR links below); the published
17
+ version users install is `7.11.0` on npm `latest`. The five `pre.*` tags
18
+ remain in git history as the implementation breakdown.
19
+
20
+ Spec: [PR #187](https://github.com/axledbetter/claude-autopilot/pull/187)
21
+ ([`docs/superpowers/specs/2026-05-19-v7.11.0-concurrent-subagent-execution-design.md`](docs/superpowers/specs/2026-05-19-v7.11.0-concurrent-subagent-execution-design.md)).
22
+
23
+ Implementation PRs:
24
+ - [#197](https://github.com/axledbetter/claude-autopilot/pull/197) — dep graph foundations (`v7.11.0-pre.1`).
25
+ - [#198](https://github.com/axledbetter/claude-autopilot/pull/198) — locking primitives (`v7.11.0-pre.2`).
26
+ - [#199](https://github.com/axledbetter/claude-autopilot/pull/199) — event + budget atomicity (`v7.11.0-pre.3`).
27
+ - [#200](https://github.com/axledbetter/claude-autopilot/pull/200) — scheduler + worktree lifecycle (`v7.11.0-pre.4`).
28
+ - [#201](https://github.com/axledbetter/claude-autopilot/pull/201) — merge orchestrator (`v7.11.0-pre.5`).
29
+ - This PR (#193) — SKILL integration + release wiring.
30
+
31
+ ### Added
32
+
33
+ - **Concurrent subagent dispatch in autopilot Step 3.** The sequential
34
+ one-task-at-a-time loop is replaced with a tier-based scheduler that
35
+ dispatches independent plan tasks in parallel into isolated per-task
36
+ worktrees under `.claude/worktrees/<run-ulid>/<task-id>/`. A dedicated
37
+ integration worktree at `.claude/worktrees/<run-ulid>/integration/` owns
38
+ the only checkout of `feature/<topic-slug>`; the main repo working tree
39
+ is never touched for the duration of the run.
40
+ - **`depends_on:` annotation in plan files** (documented in
41
+ `skills/writing-plans/SKILL.md`). Tasks declare dependencies by `### Task
42
+ N: <name>` reference; the scheduler builds a DAG, detects cycles, and
43
+ topologically sorts tasks into dispatchable tiers. Multi-commit task
44
+ branches are cherry-picked in `git rev-list --reverse base..tip` order,
45
+ producing a linear feature-branch history.
46
+ - **`concurrency:` config block in `guardrail.config.yaml`** (schema:
47
+ `presets/schemas/guardrail.config.schema.json`). New keys:
48
+ - `maxParallelSubagents` (int, **range 1..8**, default 3) — invalid
49
+ values fail at config-load with a schema validation error.
50
+ - `perSubagentTimeoutMs` (int ms, default 30 minutes).
51
+ - `assumeIndependentWithoutDependsOn` (bool, default false).
52
+ - `useDedicatedMergeWorktree` (bool, default true).
53
+ - `allowMergeCommitsInTasks` (bool, default false).
54
+ - **`budgets.perSubagentUSD`** — HARD cost cap per subagent. Dispatch is
55
+ rejected when `preFlightEstimate > perSubagentUSD`; an in-flight
56
+ subagent is SIGTERMed (process group; SIGKILL after 30s) and emits
57
+ `task.failed` if actual cost exceeds the cap mid-execution. Set to
58
+ `null` to disable.
59
+ - **11 new run-state event types** for concurrent dispatch:
60
+ `task.started`, `task.budget_reserved`,
61
+ `task.budget_increased_reservation`, `task.budget_released`,
62
+ `task.completed`, `task.failed`, `task.merged`,
63
+ `task.merge_conflict`, `task.merge_aborted`, `task.timeout`,
64
+ `task.budget_halt`. All event writes route through a per-run serialized
65
+ writer that holds an exclusive `flock` on `events.ndjson` for the
66
+ `(replay → check → append → release)` critical section. **The
67
+ append is a single `O_APPEND` write (atomic at the byte level) but
68
+ is NOT followed by `fsync` per event** — see "Audit-log durability"
69
+ below for the rationale and the no-fsync limitation.
70
+ - **Cross-process repo lock** at `.claude/run-state/repo.lock`, acquired
71
+ by every CLI command that mutates repo state (autopilot, run resume,
72
+ runs gc, runs cleanup). Uses `flock(LOCK_EX|LOCK_NB)` — NOT
73
+ check-then-create. Stale-lock detection (PID not running on host AND
74
+ acquired > 1 hour ago) surfaces an explicit
75
+ `claude-autopilot runs cleanup --force-unlock` recovery command — no
76
+ auto-clear.
77
+ - **In-process git operation queue** serializing all repo-level git
78
+ operations (worktree add/remove, branch create/delete, cherry-pick,
79
+ abort, GC) so concurrent scheduler callers cannot corrupt
80
+ `.git/refs/` or pack files.
81
+ - **Public package subpath export** `./concurrent-dispatch` — consumers
82
+ can `import { runScheduler, computeEffectiveConcurrency }` from
83
+ `@delegance/claude-autopilot/concurrent-dispatch` without deep-importing
84
+ into compiled paths.
85
+ - **Skill integration:** `skills/autopilot/SKILL.md` Step 2 now creates
86
+ `feature/<topic-slug>` as a ref-only (no checkout in main worktree),
87
+ and Step 3 invokes the concurrent dispatcher with the fallback rule
88
+ enforced by `src/core/concurrent-dispatch/dep-graph.ts`. New skill
89
+ `skills/writing-plans/SKILL.md` documents the `depends_on:` annotation,
90
+ the three-clause fallback policy, and walks through a mixed
91
+ annotated/unannotated plan example.
92
+
93
+ ### Changed — new failure modes (operator-visible)
94
+
95
+ These are **new behaviors v7.10.0 did not have**. Read carefully before
96
+ upgrading:
97
+
98
+ - **Cherry-pick conflict halts the run.** The merge orchestrator does NOT
99
+ auto-resolve, even for trivial conflicts. Diagnostics
100
+ (`git diff --name-only --diff-filter=U`, `git ls-files -u`, full
101
+ porcelain) are persisted to
102
+ `.claude/run-state/<run-ulid>/conflicts/<task-id>.md` BEFORE
103
+ `cherry-pick --abort` clears the working tree. The user resolves by
104
+ (a) adding an explicit `depends_on:` to the plan and rerunning,
105
+ (b) manually resolving in the preserved worktree, or
106
+ (c) marking the offending pair as sequential in
107
+ `guardrail.config.yaml`.
108
+ - **Interrupted tasks require explicit confirmation on resume.** A task
109
+ in state `started` with NO terminal event (no `task.completed`,
110
+ `task.failed`, `task.timeout`) is classified `interrupted` by
111
+ `claude-autopilot run resume <ulid>`. The CLI refuses to auto-merge
112
+ any partial commits — the user must pass
113
+ `--confirm-interrupted-tasks <task-id>...` to either re-dispatch from
114
+ a clean branch (discarding partial commits) or merge what's there
115
+ (user accepts risk). This is stricter than the pass-1 draft, which
116
+ would have auto-merged "if commits present" — that was unsafe because
117
+ commits alone do not prove the subagent finished its task contract.
118
+ - **`budgets.perSubagentUSD` is a HARD cap, not soft.** Dispatch is
119
+ rejected pre-flight if the estimate exceeds the cap, and a running
120
+ subagent is killed (SIGTERM → SIGKILL of its process group) if actual
121
+ cost overruns. To get soft-reservation semantics, omit
122
+ `perSubagentUSD` and rely solely on `perRunUSD`.
123
+ - **Task branches with merge commits are rejected by default.** Set
124
+ `concurrency.allowMergeCommitsInTasks: true` if your subagents
125
+ legitimately produce merge commits.
126
+ - **Audit-log durability — documented limitation.** Event writes are
127
+ single-`write(O_APPEND)` per JSONL line under the exclusive `flock`,
128
+ but the writer does NOT `fsync(events.ndjson)` per event. A power
129
+ loss between two appends can therefore lose the last few events even
130
+ though the file lock was held atomically. This is a deliberate
131
+ trade-off: per-event fsync would dominate scheduler throughput at
132
+ high concurrency. If your environment requires per-event durability,
133
+ set `maxParallelSubagents: 1` and the audit-log will degrade to
134
+ v7.10.0 semantics.
135
+
136
+ ### Fallback policy (backwards compatibility)
137
+
138
+ Plans without `depends_on:` annotations continue to work without changes:
139
+
140
+ - `concurrency.maxParallelSubagents: 1` → sequential dispatch
141
+ reproducing v7.10.0 behavior exactly.
142
+ - ZERO tasks declare `depends_on:` → sequential by default. Existing
143
+ plans are NEVER silently parallelized. Override with
144
+ `concurrency.assumeIndependentWithoutDependsOn: true` to opt in to
145
+ file-overlap inference.
146
+ - At least one task declares `depends_on:` → explicit deps + file-
147
+ overlap inference for the remaining unannotated tasks.
148
+
149
+ Cycle detection runs in all three cases before dispatch begins.
150
+
151
+ ### Resume semantics
152
+
153
+ `claude-autopilot run resume <ulid>` classifies tasks by their LAST
154
+ terminal event in `events.ndjson`:
155
+
156
+ - `task.merged` → DONE; skip.
157
+ - `task.completed` (no merged) → eligible; re-run merge orchestrator if
158
+ deps are merged.
159
+ - `task.failed` → terminal; surface, do not retry without intervention.
160
+ - `task.merge_conflict` → terminal; surface report path; user must
161
+ resolve before resume continues.
162
+ - `task.timeout` → terminal (dual emission of `task.timeout` +
163
+ `task.failed`).
164
+ - `task.started` with no terminal event → INTERRUPTED; requires
165
+ `--confirm-interrupted-tasks <task-id>...`.
166
+
167
+ ### Out of scope (deferred, per spec)
168
+
169
+ - Hosted profile sharing — separate spec.
170
+ - AI-generated custom config — separate spec.
171
+ - v6 run-state engine integration into the autopilot skill — issue #180.
172
+ - Frontend quality — issue #178.
173
+ - Expand/contract migration safety — issue #179.
174
+ - Parallelizing validate / codex-review / bugbot steps — separate spec.
175
+ - Distributed execution across machines — separate spec.
176
+
5
177
  ## 7.10.1 — 2026-05-13
6
178
 
7
179
  **v7.10.1 — `examples` verb.** Patch release. Closes the discoverability
@@ -37,6 +37,18 @@ export declare const HELP_GROUPS: HelpGroup[];
37
37
  * `claude-autopilot help <verb>` will show just the row in that case.
38
38
  */
39
39
  export declare const HELP_OPTIONS: Record<string, string>;
40
+ /**
41
+ * Documentation block for the v7.11.0+ `concurrency:` configuration in
42
+ * `guardrail.config.yaml`. Rendered by `claude-autopilot help concurrency`
43
+ * (advisory pointer — there is no `concurrency` verb; this is config docs).
44
+ *
45
+ * Keep this block in sync with:
46
+ * - `presets/schemas/guardrail.config.schema.json` (the validated shape)
47
+ * - `skills/autopilot/SKILL.md` Step 3 (the fallback rule consumer)
48
+ * - `skills/writing-plans/SKILL.md` (`depends_on:` annotation contract)
49
+ * - `src/core/concurrent-dispatch/dep-graph.ts` (`DEFAULT_FALLBACK_POLICY`)
50
+ */
51
+ export declare const CONCURRENCY_CONFIG_BLOCK = "guardrail.config.yaml \u2014 concurrency block (v7.11.0+):\n\n concurrency:\n maxParallelSubagents: 3 # int, range 1..8, default 3\n perSubagentTimeoutMs: 1800000 # int ms, default 30 min (1,800,000)\n assumeIndependentWithoutDependsOn: false # bool, default false\n useDedicatedMergeWorktree: true # bool, default true\n allowMergeCommitsInTasks: false # bool, default false\n\n budgets:\n perRunUSD: 10 # number USD, existing\n perPhaseUSD: 5 # number USD, existing\n perSubagentUSD: 3 # number USD or null (v7.11.0+)\n # HARD cap per subagent: dispatch\n # is rejected if preflight estimate\n # exceeds it; an in-flight subagent\n # is SIGTERMed if actual cost\n # exceeds it. Set null to disable.\n\nKeys:\n\n maxParallelSubagents\n Maximum concurrent subagents. Schema range 1..8 (enforced at config-load\n via presets/schemas/guardrail.config.schema.json \u2014 invalid values fail).\n Effective concurrency at runtime is further clamped by\n providerRateLimitConcurrency and the remaining task count. Setting to 1\n reproduces v7.10.0 sequential behavior exactly.\n\n perSubagentTimeoutMs\n Hard per-subagent timeout. On expiry the scheduler SIGTERMs the\n subagent's entire process group (kill -TERM -<pgid>); SIGKILL follows\n after 30s if no response. Emits both task.timeout (informational) and\n task.failed (terminal, error_type: 'timeout') events.\n\n assumeIndependentWithoutDependsOn\n Fallback policy for plans where ZERO tasks declare depends_on. Default\n false = run sequentially (preserves v7.10.0 semantics). Set true to opt\n in to file-overlap inference for unannotated plans. Has no effect when\n at least one task in the plan declares depends_on.\n\n useDedicatedMergeWorktree\n When true (default), the merge orchestrator cherry-picks task branches\n inside a dedicated integration worktree at\n .claude/worktrees/<run-ulid>/integration/ \u2014 the main repo working tree\n is never touched. Disable only if your repo cannot afford the extra\n worktree (rarely necessary).\n\n allowMergeCommitsInTasks\n When false (default), the merge orchestrator rejects task branches that\n contain merge commits. Subagents are expected to produce a linear\n sequence of commits on top of base_sha.\n\n budgets.perSubagentUSD\n HARD per-subagent cost cap. Dispatch is rejected when preFlightEstimate\n > perSubagentUSD. An in-flight subagent is killed and emits task.failed\n with error_type: 'budget_exceeded' if actual_cost_usd exceeds the cap\n mid-run. Set to null to disable the per-subagent cap entirely (in which\n case only the perRunUSD soft reservation applies).\n\nFallback rule (single source of truth \u2014 enforced in\nsrc/core/concurrent-dispatch/dep-graph.ts):\n\n 1. concurrency.maxParallelSubagents: 1 \u2192 sequential dispatch.\n 2. ZERO tasks declare depends_on \u2192 sequential, unless\n assumeIndependentWithoutDependsOn: true.\n 3. At least one task declares depends_on \u2192 use explicit deps + file-\n overlap inference for unannotated tasks.\n\nSee skills/writing-plans/SKILL.md for the depends_on annotation contract.";
40
52
  /**
41
53
  * Global flags advertised in --help. These work across most verbs (per-verb
42
54
  * support varies; v6.0.1 wires them into `scan` first, additional verbs land
@@ -364,6 +364,86 @@ function padVerb(verb) {
364
364
  const WIDTH = 16;
365
365
  return verb.length >= WIDTH ? verb + ' ' : verb + ' '.repeat(WIDTH - verb.length);
366
366
  }
367
+ /**
368
+ * Documentation block for the v7.11.0+ `concurrency:` configuration in
369
+ * `guardrail.config.yaml`. Rendered by `claude-autopilot help concurrency`
370
+ * (advisory pointer — there is no `concurrency` verb; this is config docs).
371
+ *
372
+ * Keep this block in sync with:
373
+ * - `presets/schemas/guardrail.config.schema.json` (the validated shape)
374
+ * - `skills/autopilot/SKILL.md` Step 3 (the fallback rule consumer)
375
+ * - `skills/writing-plans/SKILL.md` (`depends_on:` annotation contract)
376
+ * - `src/core/concurrent-dispatch/dep-graph.ts` (`DEFAULT_FALLBACK_POLICY`)
377
+ */
378
+ export const CONCURRENCY_CONFIG_BLOCK = `guardrail.config.yaml — concurrency block (v7.11.0+):
379
+
380
+ concurrency:
381
+ maxParallelSubagents: 3 # int, range 1..8, default 3
382
+ perSubagentTimeoutMs: 1800000 # int ms, default 30 min (1,800,000)
383
+ assumeIndependentWithoutDependsOn: false # bool, default false
384
+ useDedicatedMergeWorktree: true # bool, default true
385
+ allowMergeCommitsInTasks: false # bool, default false
386
+
387
+ budgets:
388
+ perRunUSD: 10 # number USD, existing
389
+ perPhaseUSD: 5 # number USD, existing
390
+ perSubagentUSD: 3 # number USD or null (v7.11.0+)
391
+ # HARD cap per subagent: dispatch
392
+ # is rejected if preflight estimate
393
+ # exceeds it; an in-flight subagent
394
+ # is SIGTERMed if actual cost
395
+ # exceeds it. Set null to disable.
396
+
397
+ Keys:
398
+
399
+ maxParallelSubagents
400
+ Maximum concurrent subagents. Schema range 1..8 (enforced at config-load
401
+ via presets/schemas/guardrail.config.schema.json — invalid values fail).
402
+ Effective concurrency at runtime is further clamped by
403
+ providerRateLimitConcurrency and the remaining task count. Setting to 1
404
+ reproduces v7.10.0 sequential behavior exactly.
405
+
406
+ perSubagentTimeoutMs
407
+ Hard per-subagent timeout. On expiry the scheduler SIGTERMs the
408
+ subagent's entire process group (kill -TERM -<pgid>); SIGKILL follows
409
+ after 30s if no response. Emits both task.timeout (informational) and
410
+ task.failed (terminal, error_type: 'timeout') events.
411
+
412
+ assumeIndependentWithoutDependsOn
413
+ Fallback policy for plans where ZERO tasks declare depends_on. Default
414
+ false = run sequentially (preserves v7.10.0 semantics). Set true to opt
415
+ in to file-overlap inference for unannotated plans. Has no effect when
416
+ at least one task in the plan declares depends_on.
417
+
418
+ useDedicatedMergeWorktree
419
+ When true (default), the merge orchestrator cherry-picks task branches
420
+ inside a dedicated integration worktree at
421
+ .claude/worktrees/<run-ulid>/integration/ — the main repo working tree
422
+ is never touched. Disable only if your repo cannot afford the extra
423
+ worktree (rarely necessary).
424
+
425
+ allowMergeCommitsInTasks
426
+ When false (default), the merge orchestrator rejects task branches that
427
+ contain merge commits. Subagents are expected to produce a linear
428
+ sequence of commits on top of base_sha.
429
+
430
+ budgets.perSubagentUSD
431
+ HARD per-subagent cost cap. Dispatch is rejected when preFlightEstimate
432
+ > perSubagentUSD. An in-flight subagent is killed and emits task.failed
433
+ with error_type: 'budget_exceeded' if actual_cost_usd exceeds the cap
434
+ mid-run. Set to null to disable the per-subagent cap entirely (in which
435
+ case only the perRunUSD soft reservation applies).
436
+
437
+ Fallback rule (single source of truth — enforced in
438
+ src/core/concurrent-dispatch/dep-graph.ts):
439
+
440
+ 1. concurrency.maxParallelSubagents: 1 → sequential dispatch.
441
+ 2. ZERO tasks declare depends_on → sequential, unless
442
+ assumeIndependentWithoutDependsOn: true.
443
+ 3. At least one task declares depends_on → use explicit deps + file-
444
+ overlap inference for unannotated tasks.
445
+
446
+ See skills/writing-plans/SKILL.md for the depends_on annotation contract.`;
367
447
  /**
368
448
  * Global flags advertised in --help. These work across most verbs (per-verb
369
449
  * support varies; v6.0.1 wires them into `scan` first, additional verbs land
@@ -409,6 +489,8 @@ export function buildHelpText() {
409
489
  }
410
490
  }
411
491
  }
492
+ lines.push(CONCURRENCY_CONFIG_BLOCK);
493
+ lines.push('');
412
494
  lines.push('Run \x1b[36mclaude-autopilot help <command>\x1b[0m for command-specific options.');
413
495
  return lines.join('\n') + '\n';
414
496
  }
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@delegance/claude-autopilot",
3
- "version": "7.11.0-pre.3",
3
+ "version": "7.11.1",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
- "tag": "next"
6
+ "tag": "latest"
7
7
  },
8
8
  "description": "Autonomous development pipeline for Claude Code: brainstorm → spec → plan → implement → migrate → validate → PR → review → merge. Multi-model, local-first, every phase a skill you can intervene in.",
9
9
  "keywords": [
@@ -53,6 +53,10 @@
53
53
  "types": "./dist/src/core/run-state/sameness-detector.d.ts",
54
54
  "default": "./dist/src/core/run-state/sameness-detector.js"
55
55
  },
56
+ "./concurrent-dispatch": {
57
+ "types": "./dist/src/core/concurrent-dispatch/index.d.ts",
58
+ "default": "./dist/src/core/concurrent-dispatch/index.js"
59
+ },
56
60
  "./bin/claude-autopilot.js": "./bin/claude-autopilot.js",
57
61
  "./bin/guardrail.js": "./bin/guardrail.js",
58
62
  "./package.json": "./package.json"
@@ -0,0 +1,70 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://github.com/axledbetter/claude-autopilot/presets/schemas/guardrail.config.schema.json",
4
+ "title": "guardrail.config.yaml",
5
+ "description": "Top-level shape of guardrail.config.yaml. Only blocks that are validated at config-load are listed under properties; unrecognized keys are still permitted today (additionalProperties: true) so existing presets continue to parse while new validated blocks land in subsequent releases.",
6
+ "type": "object",
7
+ "required": ["configVersion"],
8
+ "additionalProperties": true,
9
+ "properties": {
10
+ "configVersion": {
11
+ "type": "integer",
12
+ "minimum": 1
13
+ },
14
+ "budgets": {
15
+ "type": "object",
16
+ "additionalProperties": true,
17
+ "description": "Cost caps in USD. `perRunUSD` and `perPhaseUSD` are enforced run-wide. `perSubagentUSD` is a HARD cap per concurrent subagent — dispatch is rejected if the preflight estimate exceeds it, and a running subagent is SIGTERMed if its actual cost overruns the cap. Leave `perSubagentUSD` null/omitted to fall back to a soft `perRunUSD`-only reservation model. additionalProperties is intentionally `true` in v7.11.0 for backwards-compatibility with existing user configs that may carry historical budget keys; a future minor will enumerate the full set and tighten this to `false`.",
18
+ "properties": {
19
+ "perRunUSD": {
20
+ "type": "number",
21
+ "minimum": 0
22
+ },
23
+ "perPhaseUSD": {
24
+ "type": "number",
25
+ "minimum": 0
26
+ },
27
+ "perSubagentUSD": {
28
+ "type": ["number", "null"],
29
+ "minimum": 0,
30
+ "description": "HARD per-subagent cost cap in USD. Dispatch is rejected when preFlightEstimate > perSubagentUSD; an in-flight subagent is killed and emits task.failed if actual_cost_usd exceeds it mid-run. Set to null to disable the per-subagent cap and rely solely on perRunUSD."
31
+ }
32
+ }
33
+ },
34
+ "concurrency": {
35
+ "type": "object",
36
+ "additionalProperties": false,
37
+ "description": "Concurrent subagent dispatch settings (v7.11.0+). All keys are optional; defaults reproduce v7.10.0 sequential behavior for plans without depends_on annotations.",
38
+ "properties": {
39
+ "maxParallelSubagents": {
40
+ "type": "integer",
41
+ "minimum": 1,
42
+ "maximum": 8,
43
+ "default": 3,
44
+ "description": "Maximum number of concurrent subagents (effective concurrency is further clamped by providerRateLimitConcurrency and taskCount). Setting to 1 reproduces v7.10.0 sequential behavior exactly. Above 8 the API rate limits dominate and additional parallelism does not help."
45
+ },
46
+ "perSubagentTimeoutMs": {
47
+ "type": "integer",
48
+ "minimum": 1000,
49
+ "default": 1800000,
50
+ "description": "Hard timeout per subagent in milliseconds (default 30 minutes). On timeout the scheduler SIGTERMs the subagent's process group; SIGKILL follows after 30 seconds if no response."
51
+ },
52
+ "assumeIndependentWithoutDependsOn": {
53
+ "type": "boolean",
54
+ "default": false,
55
+ "description": "When false (default), a plan in which ZERO tasks declare depends_on is run sequentially — preserving v7.10.0 semantics. Set true to opt in to file-overlap inference for unannotated plans."
56
+ },
57
+ "useDedicatedMergeWorktree": {
58
+ "type": "boolean",
59
+ "default": true,
60
+ "description": "When true (default), the merge orchestrator cherry-picks task branches inside a dedicated integration worktree under .claude/worktrees/<run-ulid>/integration/ so the main working tree is never mutated by the autopilot run. Disable only if your repo cannot afford the extra worktree (rarely necessary)."
61
+ },
62
+ "allowMergeCommitsInTasks": {
63
+ "type": "boolean",
64
+ "default": false,
65
+ "description": "When false (default), the merge orchestrator rejects task branches that contain merge commits. Subagents are expected to produce a linear sequence of commits on top of base_sha."
66
+ }
67
+ }
68
+ }
69
+ }
70
+ }
@@ -145,6 +145,25 @@ Rules:
145
145
  - Specs may contain sensitive architecture details (tenant/RLS behavior, auth flows, schema names, internal endpoints). The "no secrets" rule extends to "no production-sensitive design content in tempfiles you'd be uncomfortable surfacing"; paraphrase such content before writing
146
146
  - Never write secrets, API keys, or production credentials to tempfiles regardless of location
147
147
 
148
+ ## DEFAULT: Concurrent multi-PR dispatch when the user supplies multiple independent deliverables
149
+
150
+ When the user describes multiple independent deliverables in one invocation (e.g., "ship A, B, and C as separate PRs"), dispatch them as **parallel Agent subagent invocations** in a single message — each in its own isolated worktree (`isolation: "worktree"`), each running its own end-to-end pipeline (brainstorm → spec → plan → implement → validate → PR → codex-review → bugbot). Do not serialize them. Concurrent dispatch is the default unless explicit serialization is requested. Only serialize when the user explicitly says so OR the deliverables depend on each other.
151
+
152
+ ### Independence preflight (run before dispatching concurrently)
153
+
154
+ Before fanning out, do a quick dependency/conflict scan. Serialize (or designate ONE coordinator PR for the shared edit) when any of the following are true for two or more proposed deliverables:
155
+
156
+ - **Shared release metadata**: root `package.json` version, `package-lock.json`, workspace `package.json` versions, `CHANGELOG.md`, release notes.
157
+ - **Shared schema or contracts**: DB migrations (`data/deltas/` or equivalent), RLS policies, generated types (`types/supabase.ts` or equivalent), public API contracts, OpenAPI/JSON schemas.
158
+ - **Shared infrastructure**: queue/topic names, env-var registry, shared TypeScript types/interfaces consumed by all PRs, monorepo config (`tsconfig`, `nx.json`, workspace globs).
159
+ - **Same module/route**: PRs that all touch the same handler, the same React component tree, or the same service file.
160
+
161
+ If file ownership across the PRs is genuinely disjoint AND none of the shared-artifact categories above apply, proceed concurrently. Otherwise, either serialize (run sequentially in dependency order) or split out the shared edit into a single coordinator PR that lands first, then dispatch the dependent PRs concurrently against the post-merge base.
162
+
163
+ ### Avoid duplicated global edits across concurrent subagents
164
+
165
+ When dispatched concurrently, individual feature subagents should NOT independently bump versions, edit `CHANGELOG.md`, regenerate lockfiles, or touch release metadata unless the parent operator has explicitly assigned that edit to exactly one subagent. The default for a fan-out is: feature code only in each subagent; release/version/changelog changes go in a separate coordinator PR or are added by the operator after the fan-out merges. This prevents merge conflicts on global artifacts that are otherwise unrelated to each PR's feature work.
166
+
148
167
  ## Step 0: Brainstorming with per-step Codex validation
149
168
 
150
169
  **Skip this step entirely if a spec already exists.** Otherwise:
@@ -188,26 +207,81 @@ Output: Plan at docs/superpowers/plans/YYYY-MM-DD-<topic>.md
188
207
 
189
208
  After the plan is written but BEFORE committing it, run `npx tsx scripts/codex-review.ts <plan-path>`. Apply CRITICAL findings (sequencing errors, missing test coverage on a load-bearing path, schema/migration ordering bugs) to the plan inline. Then commit. Always use subagent-driven development for execution — do not ask the user.
190
209
 
191
- ### Step 2: Set up worktree
210
+ ### Step 2: Set up feature branch (ref only — do NOT check out in main worktree)
192
211
 
193
212
  ```
194
213
  Invoke: superpowers:using-git-worktrees
195
214
  Branch: feature/<topic-slug>
215
+ Mode: create as a ref only; leave the main worktree on its prior branch.
196
216
  ```
197
217
 
198
- ### Step 3: Execute plan
218
+ Step 2 creates `feature/<topic-slug>` but does NOT check it out in the main
219
+ worktree. Concurrent dispatch (Step 3) will create the SOLE checkout of the
220
+ feature branch in `.claude/worktrees/<run-ulid>/integration/` — git linked
221
+ worktrees forbid the same branch being checked out twice, so the scheduler
222
+ must own the only checkout. The main repo working tree stays untouched for the
223
+ entire run.
224
+
225
+ If you are using `superpowers:using-git-worktrees`, pass it the "branch only,
226
+ no checkout" mode (or equivalent) so it stops at `git branch
227
+ feature/<topic-slug> <base-sha>` and does not run `git checkout` /
228
+ `git worktree add` against the main repo.
229
+
230
+ ### Step 3: Execute plan (concurrent dispatch)
199
231
 
200
232
  ```
201
- Invoke: superpowers:subagent-driven-development
202
- Input: The plan file
203
- Mode: dispatch fresh subagent per task
233
+ Invoke: claude-autopilot's concurrent dispatcher
234
+ Input: The plan file (with depends_on: annotations where applicable)
235
+ Mode: dispatch fresh subagents in parallel per the dep graph
204
236
  ```
205
237
 
206
- For each task:
207
- - Dispatch implementer subagent
208
- - On completion: verify commit landed in worktree
209
- - Skip formal spec/quality review to maintain speed (the validate step catches issues)
210
- - If subagent fails to write to worktree: implement directly
238
+ **Default effective concurrency:**
239
+ `min(3, providerRateLimitConcurrency, taskCount)`.
240
+ Override via `guardrail.config.yaml` `concurrency.maxParallelSubagents`
241
+ (schema range `1..8`).
242
+
243
+ **Fallback rule (single source of truth — also enforced in
244
+ `src/core/concurrent-dispatch/dep-graph.ts`):**
245
+
246
+ - If `concurrency.maxParallelSubagents: 1` → sequential (reproduces v7.10.0
247
+ behavior exactly).
248
+ - If ZERO tasks in the plan have `depends_on:` annotations → sequential,
249
+ unless `concurrency.assumeIndependentWithoutDependsOn: true` (opt in to
250
+ file-overlap inference).
251
+ - If at least one task has `depends_on:` → use the explicit deps + fall back
252
+ to file-overlap inference for the remaining unannotated tasks.
253
+
254
+ For each task, the scheduler:
255
+ - creates a per-task worktree at `.claude/worktrees/<run-ulid>/<task-id>/`,
256
+ branched from the current feature tip (`base_sha` captured at dispatch);
257
+ - dispatches an implementer subagent to commit on
258
+ `autopilot/<run-ulid>/<task-id>`;
259
+ - on success, runs the merge orchestrator (under the cross-process repo lock)
260
+ to cherry-pick `base_sha..task_branch_tip_sha` onto the integration
261
+ worktree's `feature/<topic-slug>` checkout in plan-declaration order.
262
+
263
+ **On any task failure**: halt the run, SIGTERM in-flight subagent process
264
+ groups (kill -TERM -<pgid>; SIGKILL after 30s if no response), and surface a
265
+ breakdown to the user:
266
+ - `merged`: tasks whose commits are on the feature branch (guaranteed-good
267
+ set).
268
+ - `completed-but-unmerged`: commits exist on per-task branches; worktrees
269
+ preserved for inspection.
270
+ - `in-flight`: subagents that received SIGTERM; worktrees preserved.
271
+
272
+ **On cherry-pick conflict**: diagnostics are written to
273
+ `.claude/run-state/<run-ulid>/conflicts/<task-id>.md` BEFORE
274
+ `cherry-pick --abort` runs; the run halts and the user resolves manually
275
+ (add an explicit `depends_on:` to the plan, or fix the conflict in the
276
+ preserved worktree).
277
+
278
+ **Subagent contract:** subagent writes its own commits in its worktree. If
279
+ the subagent fails to write to its worktree, fall back to direct
280
+ implementation in that worktree only — never in the integration worktree or
281
+ main repo working tree.
282
+
283
+ Skip formal spec/quality review per task to maintain speed; the validate
284
+ step (Step 4) catches issues across the merged feature branch.
211
285
 
212
286
  ### Step 4: Validate
213
287
 
@@ -0,0 +1,188 @@
1
+ ---
2
+ name: writing-plans
3
+ description: Write an implementation plan from an approved spec — task-by-task breakdown with files-to-change, step checkboxes, and (v7.11.0+) optional depends_on annotations for concurrent subagent dispatch. Use when the user has an approved spec and needs a plan ready for /implement or claude-autopilot Step 3.
4
+ ---
5
+
6
+ # Writing plans
7
+
8
+ A plan turns an approved spec into a sequence of executable tasks. Each task
9
+ is the atomic unit dispatched to one subagent. Tasks declare the files they
10
+ touch, the steps the subagent should perform, and optionally the other tasks
11
+ they depend on (v7.11.0+).
12
+
13
+ > **For the underlying brainstorming + spec flow**, see
14
+ > `superpowers:brainstorming` and `superpowers:writing-plans` from the
15
+ > superpowers plugin. This document is the claude-autopilot-side companion
16
+ > covering the `depends_on:` annotation introduced in v7.11.0 and the
17
+ > fallback policy that governs how it interacts with concurrent dispatch.
18
+
19
+ ## Plan file shape
20
+
21
+ Plans live at `docs/superpowers/plans/YYYY-MM-DD-<topic>.md`. Top-level
22
+ structure:
23
+
24
+ ```markdown
25
+ # <Topic> Implementation Plan
26
+
27
+ > **For agentic workers:** Use claude-autopilot Step 3 (concurrent dispatch)
28
+ > or superpowers:subagent-driven-development to execute this plan task-by-task.
29
+
30
+ **Goal:** <one-paragraph statement>
31
+ **Architecture:** <one-paragraph statement>
32
+ **Tech Stack:** <brief notes>
33
+
34
+ ---
35
+
36
+ ### Task 1: <task name>
37
+
38
+ **Files:**
39
+ - Create: `src/foo.ts`
40
+ - Test: `tests/foo.test.ts`
41
+
42
+ - [ ] **Step 1: <step name>**
43
+
44
+ <step content — code blocks, instructions, etc.>
45
+
46
+ - [ ] **Step 2: <step name>**
47
+
48
+ <more content>
49
+
50
+ ### Task 2: <task name>
51
+
52
+ **Files:**
53
+ - Modify: `src/bar.ts`
54
+
55
+ - [ ] **Step 1: ...**
56
+ ```
57
+
58
+ Each task has:
59
+ - A heading `### Task N: <name>` (numbered case-sensitively; the name is
60
+ human-readable and may be fuzzy-matched in `depends_on:` references).
61
+ - A `**Files:**` block listing files this task creates, modifies, or tests.
62
+ - One or more `- [ ] **Step N: ...**` checkboxes the subagent ticks as it
63
+ implements.
64
+
65
+ ## `depends_on:` annotation (v7.11.0+)
66
+
67
+ To enable concurrent execution, annotate tasks that depend on other tasks.
68
+ The annotation goes on its own line in the task header, after `**Files:**`:
69
+
70
+ ```markdown
71
+ ### Task 3: Wire foo into bar
72
+
73
+ **Files:**
74
+ - Modify: `src/bar.ts`
75
+ - Modify: `src/foo.ts:42-60`
76
+
77
+ **depends_on:** Task 1, Task 2
78
+
79
+ - [ ] **Step 1: ...**
80
+ ```
81
+
82
+ ### Rules
83
+
84
+ - `depends_on:` is **optional**. If absent, the scheduler infers
85
+ dependencies from file overlap (two tasks touching the same path become a
86
+ sequential pair, ordered by plan-declaration index).
87
+ - References are by `### Task N: <name>` heading. **The task number is
88
+ matched case-sensitively; the name is fuzzy-matched** so minor wording
89
+ drift between the reference and the heading is tolerated.
90
+ - Multiple deps are comma-separated: `**depends_on:** Task 1, Task 2`.
91
+ - Cycles are a **hard error**. The scheduler surfaces the cycle path and
92
+ refuses to dispatch.
93
+ - A task that **modifies** a file another task **creates** has an implicit
94
+ dependency on the creating task — the scheduler injects it automatically,
95
+ even without an explicit annotation.
96
+ - File overlap without an explicit `depends_on:` produces a **warning**, not
97
+ an error. The scheduler treats overlapping tasks as a sequential pair in
98
+ plan-declaration order. Surfaced in the run report so the user can add an
99
+ explicit annotation if the inferred ordering was wrong.
100
+
101
+ ## Fallback policy (single source of truth)
102
+
103
+ The fallback policy lives in `src/core/concurrent-dispatch/dep-graph.ts`
104
+ (`DEFAULT_FALLBACK_POLICY` + `buildDepGraph`) and is mirrored in
105
+ `skills/autopilot/SKILL.md` Step 3:
106
+
107
+ 1. **`concurrency.maxParallelSubagents: 1`** → sequential dispatch.
108
+ Reproduces v7.10.0 behavior exactly. Use this as the escape hatch.
109
+ 2. **ZERO tasks in the plan have `depends_on:`** → sequential by default.
110
+ Existing plans without annotations are never silently parallelized.
111
+ Override with `concurrency.assumeIndependentWithoutDependsOn: true` to
112
+ opt in to file-overlap inference for an unannotated plan.
113
+ 3. **At least one task has `depends_on:`** → use the explicit deps + fall
114
+ back to file-overlap inference for the remaining unannotated tasks.
115
+
116
+ Cycle detection runs in all three cases before dispatch begins.
117
+
118
+ ## Example — mixed annotated + unannotated tasks
119
+
120
+ ```markdown
121
+ # Banking integration plan
122
+
123
+ **Goal:** wire Fiserv adapter into the data sync pipeline.
124
+ **Architecture:** adapter under app/services/banking-integrations/adapters,
125
+ sync orchestrator under inbound/, compliance check piggy-backs on the sync.
126
+
127
+ ---
128
+
129
+ ### Task 1: Fiserv adapter skeleton
130
+
131
+ **Files:**
132
+ - Create: `app/services/banking-integrations/adapters/fiserv.adapter.ts`
133
+ - Test: `app/services/banking-integrations/adapters/__tests__/fiserv.adapter.test.ts`
134
+
135
+ - [ ] **Step 1: Define the adapter class extending BaseBankingAdapter.**
136
+
137
+ ### Task 2: Borrower-matcher service
138
+
139
+ **Files:**
140
+ - Create: `app/services/banking-integrations/inbound/borrower-matcher.service.ts`
141
+ - Test: `app/services/banking-integrations/inbound/__tests__/borrower-matcher.service.test.ts`
142
+
143
+ - [ ] **Step 1: Implement EIN-then-name-then-email matching.**
144
+
145
+ ### Task 3: Wire adapter into data sync
146
+
147
+ **Files:**
148
+ - Modify: `app/services/banking-integrations/inbound/bank-data-sync.service.ts`
149
+ - Modify: `app/services/banking-integrations/adapters/fiserv.adapter.ts`
150
+
151
+ **depends_on:** Task 1, Task 2
152
+
153
+ - [ ] **Step 1: Call the adapter from syncBankData; pipe results through borrower-matcher.**
154
+
155
+ ### Task 4: Update CHANGELOG
156
+
157
+ **Files:**
158
+ - Modify: `CHANGELOG.md`
159
+
160
+ - [ ] **Step 1: Prepend a Banking integration entry under Unreleased.**
161
+ ```
162
+
163
+ How the scheduler resolves this plan with `maxParallelSubagents: 3` and
164
+ `assumeIndependentWithoutDependsOn: false`:
165
+
166
+ - Task 1 and Task 2 declare no overlap with each other and have no
167
+ `depends_on:`, but Task 3 declares `depends_on: Task 1, Task 2` — so the
168
+ plan has at least one annotation, the explicit-deps + file-overlap
169
+ inference branch is used.
170
+ - Tier 0: `Task 1, Task 2, Task 4` (no satisfied deps, no overlap with each
171
+ other) — dispatched in parallel up to `maxParallelSubagents`.
172
+ - Tier 1: `Task 3` — eligible only after Tasks 1 and 2 reach state
173
+ `merged`.
174
+
175
+ If you remove the `**depends_on:** Task 1, Task 2` line from Task 3, the
176
+ plan has zero annotations, falls back to sequential dispatch, and runs
177
+ Tasks 1 → 2 → 3 → 4 in plan-declaration order — reproducing v7.10.0
178
+ behavior.
179
+
180
+ ## When NOT to annotate
181
+
182
+ - The plan is small (≤ 3 tasks) and the wall-clock gain is not worth the
183
+ annotation maintenance cost.
184
+ - All tasks touch the same handful of files (high overlap, no
185
+ parallelizable structure).
186
+ - You want to ship the plan against v7.10.0 with the
187
+ `concurrency.maxParallelSubagents: 1` escape hatch and add annotations in
188
+ a follow-up.