Files
msd-core/docs/how-to/enable-parallel-reviewer-lanes.md
Jakub Zych a9a7a328e6 refactor: hard-fork GSD -> MSD (Make Software Done)
Mechanical rename produced by scripts/msd-rename.cjs: gsd/Gsd/GSD -> msd/Msd/MSD
across contents and paths, upstream package/repo coordinates -> @golem15/msd-core
and golem15com/msd-core. Deep links into upstream history, sibling upstream
packages, the GSD-2 import feature, CHANGELOG.md and .changeset/ are kept as-is.

Hand edits on top: MSD block-letter banner and logos, LICENSE copyright line,
package/plugin identity, regenerated lockfile, install-tree fixtures, derived
registries and benchmark baseline; migration checksum baseline re-locked
(MSD keeps its own install state, so no install had applied the old sums);
sort-order and regex-escaped expectations in tests adjusted.
2026-10-06 01:47:40 +02:00

140 lines
6.5 KiB
Markdown

# How to enable parallel reviewer lanes
Cut the wall-clock cost of a multi-reviewer `/msd-review` pass from the sum of its lanes toward
its slowest lane — without losing the rate-limit protection the sequential default exists to
provide.
> **Default-off, and deliberately so.** Reviewer lanes are dispatched one at a time because
> concurrent invocation can trip provider rate limits, and a lane lost to a rate limit is a
> cross-AI review that quietly went blind in one eye. Turning this on is you asserting that your
> providers can take the concurrency. Nothing detects that for you.
**What you need:**
- Two or more reviewer lanes that actually run on this host. With one lane there is nothing to
overlap and the setting changes nothing.
- Provider capacity for concurrent requests — separate accounts, generous quota, or local model
servers (`ollama`, `lm-studio`, `llama-cpp`) that have no external limit at all.
---
## Step 1 — Check what your review pass actually runs
Parallelism only helps if several lanes are selected. Confirm the set first:
```bash
msd config-get review.default_reviewers
```
If that returns `Key not found`, no-flag runs use every detected reviewer and `--all` is
redundant. If it names a single reviewer, stop here — enabling the key would change nothing.
---
## Step 2 — Turn the key on
```bash
msd config-set review.parallel_lanes true
```
Verify it took:
```bash
msd config-get review.parallel_lanes --raw
# → true
```
**The guard is strict equality.** Only the exact value `true` opts in. `"1"`, `"yes"`, `"on"` and
`"TRUE"` are all read as *not enabled* and leave dispatch sequential. This is intentional: a
mistyped config gets the conservative behavior rather than firing concurrent requests at a
rate-limited provider. If `config-get` shows anything other than `true`, the setting is off.
---
## Step 3 — Run a review and read the result
```bash
/msd-review --phase 3 --all
```
or, for the convergence loop:
```bash
/msd-plan-review-convergence 3 --all
```
Open `{phase_dir}/{padded_phase}-REVIEWS.md` and check the `reviewers:` frontmatter list. Every
lane you selected must appear there. That list is the contract: lanes are joined before the file
is rendered, so a missing reviewer means that lane did not produce a review — never that
aggregation ran early.
**If every selected lane failed, `REVIEWS.md` is not written at all** (ADR-3473 §8.5, #3885) — the
run reports the failure instead of synthesizing a review artifact from zero lane results. This is
not specific to parallel dispatch (a sequential run where every lane fails behaves the same way),
but concurrency gives you more ways to lose every lane in one pass. Each lane's raw output and any
non-empty `.err` file are preserved beside the phase's artifacts before the run's own cleanup runs,
so a missing `REVIEWS.md` is diagnosable, not silent — see the table below for what a *partial*
failure (some, not all, lanes down) looks like instead.
Section order in `REVIEWS.md`, and line order in the run's `msd-review-lane-results.jsonl`, are
unchanged from sequential dispatch. They follow reviewer-selection order, not completion order,
so a diff of two runs shows no reordering churn.
---
## Telling the outcomes apart
The single most useful habit: **an empty or stub review is a dropped lane, not a clean review.**
That is true sequentially too, but concurrency gives you more ways to drop one at once.
| What you see | What it means | What to do |
|---|---|---|
| Every selected lane in `reviewers:`, all sections populated | Working as intended | Nothing |
| A lane's section carries the "failed or returned empty output" header | The lane ran and produced nothing usable. Read the captured stderr in the stub | If it names a rate limit or quota, your provider cannot take this concurrency — see below |
| A lane reports `probe_timeout` or `host_unreachable` | The lane could not be reached at all — a local server that is down, not a concurrency effect | Start the server; unrelated to this setting |
| A lane reports `budget_too_small` | Its prompt budget cannot fit the minimum review set | Raise `review.max_prompt_tokens_per_reviewer.<slug>`; unrelated to this setting |
| A lane reports `egress_host_changed` | The lane was consented to one destination and the config now names another. It is blocked, not redirected | Re-consent deliberately; unrelated to this setting |
| A lane is missing from `reviewers:` entirely | It was never selected | Check your flags and `review.default_reviewers` |
| Several lanes stub out at once, with provider errors | The concurrency is more than your account can take | Turn the key back off, or narrow `review.default_reviewers` |
**Rate-limited lanes fail loudly.** A lane that gets throttled goes down the same path as any
other failing lane — a diagnostic stub carrying its stderr, kept distinguishable from a real
review by its header. It is not silently dropped and it does not abort its sibling lanes.
---
## Turning it back off
```bash
msd config-set review.parallel_lanes false
```
The next pass dispatches sequentially again. Nothing else changes: no artifact written under the
parallel setting needs migrating, because the output layout is identical in both modes.
---
## What this does not speed up
**Convergence cycles stay sequential.** `/msd-plan-review-convergence` runs
`plan-phase → review → replan → re-review`, and each cycle genuinely depends on the previous
one's output. Enabling this key makes each *review pass* inside a cycle faster; it does not
reduce the number of cycles, and it does not overlap planning with reviewing. A three-cycle
convergence run is still three sequential rounds.
**There is no concurrency bound.** Every selected lane dispatches at once. Eleven selected lanes
means eleven concurrent requests. If that is more than you want, the control is the size of your
selected set — `review.default_reviewers` or explicit flags — not a throttle on this setting.
**Reviewer instances sharing an adapter are not grouped.** Two
[`review.reviewer_instances`](../CONFIGURATION.md#reviewer-instances-for-msd-review-1517) entries
backed by the same CLI dispatch concurrently against that one provider. If you run several
same-provider instances, you are the most likely configuration to hit a limit, and this setting
gives you no way to serialize just those.
---
**See also:** [Configuration reference](../CONFIGURATION.md#parallel-reviewer-lanes-for-msd-review-3034)
· [Reviewer instances](../CONFIGURATION.md#reviewer-instances-for-msd-review-1517)
· [`/msd-review` command reference](../COMMANDS.md)