Files
msd-core/docs/how-to/enable-concurrent-chunked-planning.md
Tom Boucher f9f72cb54c enhance(#3777): opt-in concurrent per-plan planners in chunked mode (#4346)
* 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>
2026-09-05 18:57:17 -04:00

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.