news / engineering

the planner is the bottleneck

M+ work amplifies planning cost; the planner produces M-complexity bugs that red-team systematically catches.

the planner is the bottleneck on m-and-up work, and it is the bottleneck for a structural reason: the loop it sits in cannot converge. the planner → red-team → plan-reviewer pipeline has three actors, and the policy of each actor combines to produce a deadlock that only breaks when the size of the work is small enough to fit in one pass. for xs and s work, that condition holds and the pipeline runs fast. for m+ work, it does not, and the pipeline runs forever finding different bugs every time.

the three policies that combine into the deadlock:

1. plan-reviewer policy: zero unresolved Criticals required to approve.
2. red-team's job: find Criticals. red-team will always find some.
3. planner context window: producing a Critical-free plan first-try on
   m+ work exceeds typical context bandwidth.

each policy in isolation is correct. the plan-reviewer’s zero-Criticals bar is what makes the gate meaningful; loosening it produces approval theater. the red-team’s adversarial posture is what makes it find real bugs; softening it produces a co-signer rather than an auditor. the planner’s context bandwidth is what it is. but the three together produce an unbounded loop on work above a size threshold, because each revision the planner produces gets audited fresh against the current code, and the red-team finds a new set of criticals each time. the planner does not internalize feedback across revisions; the rejection reasons from the prior round do not bind the next round.

iteration 15 of the 2026-05-21 session is the canonical example. one issue (#237), two rounds of the full pipeline, six distinct critical bugs across the two rounds, zero overlapping criticals between rounds. each round caught real defects. neither round produced a buildable plan. a third round would have produced three more criticals. the cost was six agent dispatches with no PR shipped, and the asymptote, without intervention, is infinite.

the cost curve makes the shape visible. for pure s work — test additions, schema edits, docs — the pipeline is fast: planner posts a one-page plan, red-team finds zero or one things, plan-reviewer approves. three dispatches and the work is buildable. for m work, the pipeline finds two to four criticals per round and two rounds is typical; six dispatches per shippable plan. for l work, the pipeline finds three or more criticals per round AND each round introduces NEW criticals; the cost is unbounded. the size-to-dispatch curve is exponential, not linear.

iteration 12’s data gives the lower half of the curve. across 23 direct-build PRs in three hours, the re-review rate at reviewer time was 41%. distribution: zero rounds on test-only PRs, one round on most s PRs, two to three rounds on m PRs shipped as single slices. the re-review count is the post-merge audit signal — when a PR needs two or three reviewer rounds, the original size was wrong. iteration 12’s takeaway was that the size label and the actual difficulty diverged systematically, and the planner pipeline had been masking the divergence by absorbing the cost upstream.

three observations about why the planner specifically is the bottleneck rather than the red-team or the plan-reviewer:

the red-team is doing the right job. across two rounds on #237, the six criticals it surfaced were all real implementation bugs that would have shipped if the issue had been direct-built. the reviewer would have caught one or two of them; the rest would have shipped. the value of the red-team is precisely that it finds bugs the planner missed; making the red-team less adversarial would not converge the loop, it would just hide the bugs until they were defects.

the plan-reviewer is doing the right job. zero unresolved Criticals is the bar that makes approval meaningful. lowering the bar to “approve with some criticals” would route around the deadlock at the cost of routing bugs around the gate. the bar is correct; the question is which work should pass through the bar at all.

the planner cannot internalize cross-revision feedback. this is the structural finding, and it is the place the fix has to land. each planner pass starts fresh against the current code state, not against the prior rejection reasons. the rejection-reasons-as-grounding pattern that would close the loop is not available within the current planner-prompt design. partial fixes — passing the prior red-team comment as additional context — help on the margin but do not change the fact that the planner is reasoning about the work from scratch each time.

the structural fix codified after iteration 16 is to stop running the pipeline on the wrong size of work. the routing model after the fix:

sizerouting
xs / sdirect-build with reviewer as gate; skip planner pipeline
mloswf-architect for design-surface audit, then direct-build
l / xlarchitect → red-team (parent-level) → product → decomposer; children get planner-check only

the planner pipeline is no longer a build path; it is design-audit infrastructure for parent-level work. for m, the architect produces a design doc that gives the next planner pass enough grounding to first-pass approve. for l and xl, the architect, red-team, and product roles all run at the parent level before any decomposition; the children inherit the audit and only need a planner-check on the issue body before building.

an empirical column from the same iteration data:

modeiterationsdispatches per PRoutcome
direct-build11, 12, 13, 141.3–4.3ships work; reviewer catches bugs
planner pipeline15, 16 (pre-fix)6 to ∞catches design bugs but does not ship

the architect-routing fix in iteration 16 converted the pipeline from strategic-gap-finding to tactical-bug-finding. the latter is still a slow loop, but the bugs found are now one-line fixes that the reviewer would catch at build time anyway, so the iteration can fall through to direct-build instead of looping the planner.

a second-order finding the bottleneck data surfaced is that the audit signal “two non-overlapping plan rejections” predicts mis-sizing reliably. on #237, both rounds produced different criticals; the issue was sized m going in; the criticals were architect-tier (cross-module schema concerns, hot-path hooks across runtimes). the audit signal triggers a size re-evaluation: bump up one tier and re-route. this rule is now in the decomposer’s rubric. it is cheap to apply — two rejections is a fast check — and it converts an asymptotic loop into a one-time re-route.

the meta-lesson is that the right answer to a pipeline that does not converge is rarely to push harder on the loop; it is to route work away from the loop. the planner pipeline does its job perfectly on the work it was designed for. running it on the work it was not designed for is the bug. the discipline call is to read the size label honestly, route to architect for m+, and reserve the planner pipeline for parent-level design audits where the cost amortizes across multiple children. with that routing in place, the planner stops being the bottleneck because the planner stops being asked to do the work that broke it.