fix(auto-routing): keep session incumbents inside the benchmark noise band - #4797
Conversation
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Executive SummarySince the last review, only Files Reviewed (1 file)
Previous Review Summary (commit b86d01f)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit b86d01f)Status: No Issues Found | Recommendation: Merge Executive SummaryReviewed the sticky-band predicate change in Files Reviewed (3 files)
Reviewed by claude-sonnet-5 · Input: 22 · Output: 3.6K · Cached: 599.7K Review guidance: REVIEW.md from base branch |
Summary
In
cost_per_accuracymode,computeDecisionkept a session's incumbent model only when the incumbent cleared the route'sminAccuracybar (0.95). That bar is a point estimate over 10 distinct benchmark cases per route (repetitions re-run the same prompts and add no independent tasks), so pass/fail flips on binomial noise — and every flip ejects every session parked on that model, discarding a warm prompt cache at ~72k median context.The change replaces the
meetsThresholdrequirement on the sticky path with a tolerance band: keep a cost-mode incumbent whose route accuracy is within 0.10 ofminAccuracy.best_accuracymode still requiresmeetsThreshold, and the existing cost escape (fresh pick cheaper by more thanswitchCostFactor) still fires.switchReasontelemetry now derives from the same predicate as the keep decision, so a band-eligible incumbent that is cost-switched is labelledcost, notthreshold.Measured against the live routing table (
decider-2026-07-22T10-51-06-305Z) and a pinned 24-hour telemetry window (2026-07-26T12:00Z – 2026-07-27T12:00Z, Axiomcloudflare-logpush):The band makes 49 of the 91 threshold-forced incumbents eligible to stay; 6 of those still fail the unchanged cost condition and are relabelled
threshold → costrather than prevented — hence the predictedcostrise, which is expected behaviour, not a regression. Net effect: 43 of 91 daily forced switches (47 %) disappear, including 9 of the 14 daily punts ontoclaude-sonnet-5inplanning_design/technical_planning(its sole passer, at 6.2–14.2× the incumbents' benchmark-case cost). The split is discriminating: the largest remaining ejection (minimax-m3leavingdebugging/bug_fixingat 24/30) is genuinely weak there and still fires.Correction to the source document. The source doc's diagnosis is confirmed (83 % of switches are threshold-forced; 98 % follow a route change, concentrated in sessions oscillating between semantically adjacent routes). Its magnitude is wrong by ~53×: it modelled 22.6 switches per 100 turns by assuming a 50 % route-change probability per turn; the measured rate is 0.43 per 100 decisions, because the classifier cache hits 95 % of the time within a conversation. The modelled "$300–400/day of forced-switch cache rebuilds" is really $2–25/day. The justification for shipping is therefore not the line item but the 54 sessions/day that get a model swapped mid-conversation — a visible latency and behaviour event — 83 % of them decided by a gate the benchmark cannot resolve.
Honest disclosure — what the band retains. Classifying all 43 net retentions: A1 (19/day) keeps an incumbent that is materially cheaper (0.07–0.86×) than a threshold-clearing fresh pick; A2 (11/day) declines a qualified upgrade for cache continuity alone — the modal case keeps
kimi-k2.7-code(27/30) overminimax-m3(29/30, clears the bar) at a $0.000005 cost difference, i.e. it acts on a difference of 2 graded cases out of 30 that n = 10 cannot resolve (the one-sided Wilson upper bound for 0.9000 is 0.977, above the bar); B (13/day) chooses between two models that both miss the bar on a zero-passer route. A2 is the class a reviewer should challenge: this change forgoes ~11 qualified upgrades/day by design. A dominance guard that would cut the 10/day strictly-dominated retentions was considered and rejected — it acts onavgCostUsdmargins (1.16–1.26×) that are not trustworthy at that size, and it barely touches A2 (11 → 10/day) because in the modal case the fresh pick costs fractionally more. Re-examine both if the routing table ever carries a real per-turn cost signal (cache-read price rather than benchmark-case average).Simpler-shape decision (recorded per workflow). The source doc asked for a Wilson lower bound / publish-time hysteresis on
meetsThreshold(Step 2) and an ε band on the sticky condition (Step 3). Implementing both separately means publishing per-candidate case counts or interval bounds throughRankedCandidateSchema→ the table builder → a new D1 column →rowsToRoutingTable, then computing an interval at serve time. At the live dataset size that machinery is inert: with n = 10 the Wilson boundary sits at an observed accuracy of ≈ 0.837, a 0.10 band keeps everything ≥ 0.85, and the two rules differ only on accuracies in [0.837, 0.85) — of which the live table contains none (every published accuracy is a multiple of 1/30). On the data actually served the two rules select identical models, so this PR ships the constant, calibrated against the measured identical-behaviour plateau [0.0833, 0.1167) ("keep ≥ 26/30, eject ≤ 25/30"), with the upgrade path marked in a code comment.Rollback: revert-and-redeploy; the change takes effect on the next
auto-routingworker deploy. Deliberately no kill-switch knob — adding one would mean the same contract/migration surface this PR avoids.Deferred, with re-entry criteria (not silently dropped):
codebase_understandingthe field spans 16/30–28/30; "within ε of best" could retain a 0.53 model under a 0.60 best). Note the shipped absolute band already fires on zero-passer routes —investigation/codebase_understandinghas 0 passers but 9 of 14 candidates in band — so the arm is not needed to reach the degenerate routes. Re-entry: a route with meaningful traffic that keeps switching and has no in-band candidates at all gets its own change and review.Post-deploy validation (not a gate on this PR): re-run the pinned-window Axiom query on ≥ 3 days of data. Primary signal:
thresholdswitches ~91/day → ~42/day (falsifiable prediction; a materially different outcome means the mechanism model is wrong),cost16 → ~22 (relabels),capabilityunchanged at 2. Acostcount materially above ~22 is the real warning sign — it would mean in-band incumbents are kept and then cost-switched a turn later, churn the band was supposed to remove rather than relocate. Guardrail: watch per-routedecidedModelmix for drift toward the expensive end, since an in-band incumbent can now sit at up to 3× the cheapest eligible model's cost on every subsequent turn — the main product risk against the one-time rebuild saving. The prediction is void if a new routing table publishes before measurement.Verification
No manual device or UI testing: the change alters which model a server-side routing decision returns inside a worker with no UI, no new failure mode, and no user-facing surface — the feature-state matrix is structurally not applicable, and no mobile/web client renders anything derived from
stickyorswitchReason.pnpm vitest run src/decision-engine.test.ts— 38/38, including 5 new fixtures taken verbatim from the live routing table (zero-passer keep, sole-expensive-passer keep, qualified-upgrade-declined keep, in-band cost relabel,best_accuracystill ejects)pnpm testinservices/auto-routing(143/143) andpackages/auto-routing-contracts(84/84) — every pre-existing test passes unedited (no existing test encodes "below threshold ⇒ always switch"; the one candidate,weak/chatat 0.5 vs a 0.6 band floor, was pre-verified)pnpm typecheck,pnpm lint,git diff --checkcleanVisual Changes
N/A
Reviewer Notes
incumbentStickyEligible, which is shared by the keep decision and theswitchReasonderivation so the two cannot disagree — the one way this change could silently corrupt its own before/after measurement was keyingswitchReasontomeetsThresholdwhile keeping on the band. Test 5d (planning_design/architecture_design,inkling$0.00660620 vs incumbentclaude-sonnet-5$0.03943792, both below bar but in band → must readcost) exists specifically to catch that; test 5e (same route as 5b, mode flipped tobest_accuracy, accuracy gap 0.0334 < the 0.05 switch threshold) exists to catch the band leaking intobest_accuracy.pickFreshCandidatereturnscandidates[0]in cost mode — a fixture listing the incumbent first would silently test a different scenario.docs(mobile): record planner workflow learnings) is a required workflow deliverable, unrelated to the behavioural change.