Bounded Reviewer Dispatch (SPEC-145 US-3, Decision 5 / AD-4)¶
How /vt-d-4-review dispatches the reviewer set chosen by
persona-catalog.md / persona-select.sh — so latency and
context scale with the diff, and an extended reviewer set (or ultracode mode)
never fails on a concurrency ceiling.
The bound¶
A fixed number, stated explicitly so test-persona-selection.sh can assert
it. Rejected alternatives: a host-dynamic min(16, cores-2) (non-deterministic
in tests) and a settings-configurable key (deferred — a vt_review_max_concurrent
setting can be added later if a real need appears). At most 8 reviewer subagents
run at once.
Raised from 4 to 8 on 2026-07-03 per SPEC-145 review PERF-1: at the time, the
measured selection was 6 reviewers for a common TS/JS code review (floor 2 +
code-core 3 + language 1) and 9 for an unknown-diff or frontend-heavy review.
At 4, a common review took 2 waves and the worst case 3; at 8, the common case
fit in one wave and the worst case in two. Determinism is preserved by asserting
a constant (whatever the number), not specifically 4 (see Decision 5 amendment
in decisions.md).
The unknown-diff figure is now 13, not 9 (measured 2026-08-09 by running the
selector with --types code and no --files against an empty PROJECT_ROOT).
The roster grew as reviewers were added to the conservative branch:
tdd-compliance-reviewer (SPEC-159), kieran-python-reviewer and
design-implementation-reviewer (BUG-004), and php-reviewer (SPEC-168) — which
is why the 9 above went stale in three separate increments without anyone noticing.
The consequence is worth stating plainly rather than quietly updating the number:
at MAX_CONCURRENT = 8, an unknown-diff review no longer fits in one wave. It
takes two. That does not break anything — the queue semantics below handle it, and
the constant is asserted rather than the roster size — but the "common case fits in
one wave" rationale above no longer describes the unknown-diff case. Whether to
raise the constant is a separate decision with its own measurement, not a
side effect of adding a reviewer, so it is left to its own spec.
Queue + retry semantics¶
- Compute the selected reviewer set (floor ∪ diff-triggers ∪ type-reviewers).
- Dispatch the first
MAX_CONCURRENTreviewers in parallel. - Hold the remainder in a FIFO queue; as each running reviewer returns, pull the next queued reviewer and dispatch it. Order is deterministic (the sorted selection order) so behavior is reproducible.
- On a capacity error from the host (too many concurrent subagents),
retry with backoff — do not hard-fail. The reviewer goes back on the queue
and is re-dispatched when a slot frees. Backoff is exponential with a small
cap; a reviewer that repeatedly cannot be scheduled is reported as
deferredin the review output, never silently dropped.
Capacity errors are a scheduling condition, not a review failure: the fixed bound plus retry-on-capacity is what lets the selection grow (ultracode, extra personas) without race failures.
5. The collection barrier — dispatch is not collection¶
Queue semantics say a reviewer "still runs; it just runs later". That guarantee is
only worth anything if the orchestrator waits for later. It must not grade while
any dispatched reviewer is outstanding — see SKILL.md Step 2.9, which owns the
ledger and the gate fields.
The bound makes this failure mode structural rather than incidental. At
MAX_CONCURRENT = 8, the 13-reviewer unknown-diff selection runs in two waves, so
an orchestrator that grades when wave 1 goes quiet systematically discards wave 2 —
and the discarded reviewers are always the same ones, because the dispatch order is
deterministic. That is not a hypothetical: on 2026-08-10 (SPEC-171 pass 2) the three
reviewers dropped this way returned minutes after grading with 33 findings, including
that pass's only CRITICAL, and six earlier passes had recorded the identical absence
as a reviewer failure.
A reviewer that has not returned yet is outstanding, never failed — the two are distinguishable only by waiting, and recording the second when you observed the first writes a false statement into a durable gate and throws away a real report.
Why this pairs with selection¶
Selection decides who reviews; bounded dispatch decides how many at once. Together they deliver the US-3 goal: the median reviewer count drops from a fixed 6 to a diff-scoped 3–4 (selection), and whatever the count, dispatch never exceeds 8 concurrent nor fails on capacity (bound + retry). Neither half drops a selected reviewer — a queued or retried reviewer still runs; it just runs later.