* test(#3777): add failing-first coverage for concurrent per-plan planner dispatch Extracts and executes the real bash blocks this PR is about to add to plan-phase.md and chunked-planning-mode.md (CHUNKED_PARALLEL resolution and the BATCH_PLAN_IDS dedup guard), plus config-set/config-get coverage for the new planning.chunked_parallel key. Expected RED against the current shipped workflow text — the extraction anchors do not exist yet. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * feat(#3777): dispatch chunked mode's per-plan planners concurrently within a Wave Adds opt-in planning.chunked_parallel (default false, byte-identical to the existing serial loop). When true and the runtime's negotiated dispatch capacity (dispatch-capacity, #3673) is greater than 1, chunked planning's per-plan Tasks that share one outline Wave are issued together instead of one at a time; a later Wave still waits for the current one to be verified on disk and committed. A host with no declared maxConcurrency (most non-Claude runtimes today) stays serial regardless of the setting. Resolution and the Plan-ID dedup guard live in chunked-planning-mode.md itself (gated on the section's own CHUNKED_MODE skip-check) rather than in plan-phase.md, so a non-chunked run pays no extra gsd_run calls. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * test(#3777): repoint extraction at chunked-planning-mode.md after the move CHUNKED_PARALLEL resolution moved out of plan-phase.md into chunked-planning-mode.md itself (see the preceding commit); update the test's extraction path and header comment to match. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(#3777): relocate the canonical runtime-launcher preamble before its first use The CHUNKED_PARALLEL resolution block's two gsd_run calls landed earlier in the file than the sole existing preamble (in the commit step), which tests/runtime-launcher-parity.test.cjs's (B) check requires to precede every gsd_run call in the file. Move the preamble (not duplicate it) to the top of the resolution block; the commit step's fenced block now just calls gsd_run directly. Caught by the GREEN checkpoint gsd-test run before push. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(#3777): strip the canonical preamble from the extracted resolution block The CHUNKED_PARALLEL resolution fence now carries the relocated runtime-launcher preamble as its first line (previous commit). Extracting the whole fence and running it after the test's own gsd_run stub let the embedded preamble's own resolver logic `unset -f gsd_run` and exit 1 before reaching the resolution logic, since no real gsd-tools.cjs exists in the temp script dir — every test calling runChunkedParallelResolution() failed. Strip the preamble (sourced from gsd-core/workflows/_runtime-launcher.snippet.sh, the same file scripts/sync-runtime-launcher.cjs treats as canonical) before splicing in the stub, so this suite tests only the resolution logic it is actually about. Caught by the post-rebase gsd-test run before push. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * docs(#3777): add the How-To page the phase gate requires Enablement is 2 commands (config-set, then --chunked), which this repo's own doc-quadrant gate flags as how-to-owed: a reference table cannot carry a sequence. Covers enablement, the dispatch-capacity gate's honest "most runtimes today: no effect" case, and the two accepted trade-offs. An earlier reasoning pass (recorded in .gsd/phase/.../70-docs.json before this commit) had incorrectly claimed #3034 shipped with no equivalent how-to page, as precedent for skipping one here. That claim was false — docs/how-to/enable-parallel-reviewer-lanes.md exists and is indexed. The phase gate caught the omission before merge; corrected here. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * docs(#3777): backfill changeset PR number Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: sim <sim@local> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
3.2 KiB
How to enable concurrent per-plan planners in chunked mode
Speed up a multi-plan phase's chunked planning run by letting independent per-plan Tasks run at the same time instead of one after another.
Before you start
This only matters if you already use chunked mode (workflow.plan_chunked: true, or
/gsd-plan-phase {N} --chunked). Chunked mode splits planning into a short outline Task followed
by one short Task per plan, committing each plan individually so an interrupted run resumes from
the last committed plan. By default those per-plan Tasks still run one at a time.
Enable it
gsd config-set planning.chunked_parallel true
{
"planning": {
"chunked_parallel": true
}
}
Then run chunked planning as usual:
/gsd-plan-phase {N} --chunked
That's it — no other setting to touch, and no other capability's config is involved.
What actually changes
Nothing changes for a phase whose outline has only one plan per Wave — there is nothing to run concurrently. For a phase with several plans in the same Wave, those plans' Tasks are now issued together instead of one at a time; a later Wave still waits for the current one to finish and commit before starting, so cross-Wave ordering is unaffected.
Whether it actually does anything on your runtime
This setting is gated on the runtime's own negotiated concurrency ceiling
(gsd-tools query dispatch-capacity), not on the config value alone:
- Claude Code declares a capacity above 1, so turning this on has a real effect there.
- Every other runtime today (Codex, Cursor, OpenCode, ...) declares no concurrency ceiling and
falls back to the safe floor of
1— turning this setting on has no effect there; chunked planning stays exactly as serial as it was before. This is not a bug to work around: it means the setting never fires concurrent dispatch on a host that cannot usefully run it.
There is no per-runtime flag to set yourself — the gate is automatic and always correct for the runtime you're on.
Trade-offs to know before turning this on
- Per-plan commits interleave. With serial dispatch, plans commit strictly in outline order. With concurrent dispatch, whichever plans in a batch finish first commit first — still one commit per plan, never a combined commit, but not necessarily in outline order within a batch.
- Crash-resume granularity is coarser. If a run is interrupted mid-batch, every plan that already finished and committed stays committed — but "already finished" is no longer necessarily "everything up to the last plan in outline order," the way serial mode guarantees. Resuming the run picks up exactly where it left off either way; only the shape of what's already on disk when you resume can differ.
If either of those matters more to you than the speed-up, leave this setting at its default
(false) — chunked mode's crash resilience story is otherwise unchanged.
Turn it off again
gsd config-set planning.chunked_parallel false
Or just remove the key from .planning/config.json — false is the default.
See also: Configuration reference — Concurrent per-plan planners in chunked mode.