Skip to content

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

MAX_CONCURRENT = 8

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

  1. Compute the selected reviewer set (floor ∪ diff-triggers ∪ type-reviewers).
  2. Dispatch the first MAX_CONCURRENT reviewers in parallel.
  3. 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.
  4. 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 deferred in 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.