Question. Phase A settled offline that a cascade over a small panel beats the
single default model on the cost–quality frontier. Does that survive the real
plan → run pipeline?
Answer. No, and the way it fails is more useful than the headline. Routing did not help (3/9 → 2/9), it saved 32% on spend that the planner's own variance swamps, and the panel's strong model served zero calls in the entire experiment. The learning check came back positive and harmful: the ledger demonstrably changed the router's mind between run 1 and run 3, and both tasks it touched collapsed from working to zero.
The apparatus, panel and baseline are in DESIGN.md,
panel.json and BASELINE.md.
Nine cells per arm, three replicates of three tasks, identical briefs, identical graders, same machine, same day.
| task | A success | B success | A score | B score | A $ mean | B $ mean | A nodes | B nodes |
|---|---|---|---|---|---|---|---|---|
| t1-logstore | 0/3 | 0/3 | 0.667 | 0.667 | $0.144 | $0.038 | 11, 8, 10 | 1, 1, 9 |
| t2-synthesis | 3/3 | 2/3 | 1.000 | 1.000 | $0.073 | $0.071 | 26, 5, 5 | 5, 13, 18 |
| t3-shiftplan | 0/3 | 0/3 | 0.714 | 0.571 | $0.075 | $0.089 | 3, 5, 8 | 3, 8, 4 |
| overall | 3/9 = 0.333 | 2/9 = 0.222 | 0.714 | 0.667 | $0.877 total | $0.593 total |
Wall clock: A 99.1 min (three concurrent streams), B 94.6 min (sequential). Not comparable — see section 6.
The one cell that moved is the one that broke. t2 went 3/3 → 2/3, and the lost cell is replicate 3, which scored 0.000 having scored 1.000 in every other cell of both arms. t1 and t3 are unchanged at 0/3. Nothing improved.
The 32% cost saving is not a routing result. Arm B's t1 drew 1-node graphs
in two of three replicates where arm A drew 8–11; that is the planner, not the
router, and BASELINE.md already recorded arm A's own replicates spanning 5 to
26 nodes for a byte-identical brief at 5.4x the cost. The node columns are in
the table so the two cannot be read apart.
| model | role | attempts in arm B |
|---|---|---|
~deepseek/deepseek-v4-flash-latest |
mid | 1280 |
google/gemma-3-12b-it |
base | 131 |
qwen/qwen3-30b-a3b-instruct-2507 |
base | 0 |
z-ai/glm-4.7-flash |
base | 0 |
moonshotai/kimi-k2.6 |
top | 0 |
kimi-k2.6 is the reason the panel exists — the only model in either phase significantly above the pack, 20/20 on the anchor battery, theta +4.09. It was never called once. Three of five panel members were never called at all.
learning-diff.py against the fresh-ledger control:
reordered with a shared ledger : plan.audit, plan.bind, plan.ensemble,
plan.expand, plan.fanout, plan.ground,
plan.size, plan.spine (8 of 11)
reordered with a fresh ledger : none (0 of 11)
attributable to the ledger : all eight
The control is what makes this a result rather than an anecdote. With a fresh ledger per cell the rung order is identical in run 1 and run 3 for every class; with the ledger carried forward, eight classes reorder. The router learned.
What it learned was to drop its best model.
| class | run 1 | run 3 |
|---|---|---|
| plan.spine (and 7 others) | flash > gemma > kimi-k2.6 | flash > gemma > qwen3-30b-a3b |
And the outcome, same tasks, same briefs:
| task | shared r1 | shared r3 | fresh r1 | fresh r3 |
|---|---|---|---|---|
| t1-logstore | 0.667 | 0.667 | 0.667 | 0.778 |
| t2-synthesis | 1.000 | 0.000 | 1.000 | 1.000 |
| t3-shiftplan | 0.571 | 0.000 | 0.714 | 0.857 |
The control run 3 scored 1.000 and 0.857 on the two tasks the shared run scored
0.000 on. The collapse is attributable to the ledger, not to variance, and it
reproduced in an accidental fourth pass
(results-armB-pass4.jsonl: t2 0.000, t3 0.000).
Across all nine arm-B cells there were 108 settled exec.leaf verdicts:
unverified_success : 103 (move nothing — correctly, nothing checked them)
budget_stop : 5 (graded negative)
A leaf that finishes returns unverified_success, because the harness has no
grader in the loop — the deterministic graders in this experiment run after
codeaf run exits. So the only leaf outcomes that ever reach the ledger are the
failures. Flash's exec.leaf rating was therefore fitted to a sample that is
100% negative, and finished at:
exec.leaf deepseek-v4-flash-0731 -0.98 n=5
against gemma's untouched cold-start of -1.00. On Ability(rating)/price that
is gemma 0.269/0.150 = 1.79 against flash 0.273/0.180 = 1.52 — so gemma
opens the leaf. Five budget stops, all from t1, flipped leaf routing for every
task on the panel.
exec.leaf is one global class. There is no conditioning on task, on leaf
size, or on anything else, so a rating learned from t1 — the one task whose
leaves carry 2.2M prompt tokens and hit the 300k budget — was applied unchanged
to t2's document-reading leaves and t3's small repair leaves, where flash had
never failed. That is the whole of the t2 and t3 collapse.
This is exactly the caveat Phase A wrote down, biting in the one place the harness cannot honour it: "the cascade's economics require a cheap, trustworthy verifier." For planning calls one exists — the schema check — and those classes behaved sensibly throughout. For a leaf there is none.
order() force-promotes the highest-rated model to the last rung, but only if
chosen[0] != best.rung. On a cold panel best is kimi-k2.6 (role top, +1)
and the rule fires, which is why run 1's cascade ended in kimi.
As flash accumulated positive planning observations its rating climbed past
kimi's cold-start prior — plan.expand +2.31 (n=48), plan.spine +2.21 (n=39)
— so flash became best, chosen[0] == best.rung, and the promotion stopped
firing. The last rung reverted to whatever ranks third on Ability/price, which
is qwen3-30b-a3b at $0.193 over kimi at $2.48.
The panel loses its strong escalation target precisely as it becomes confident about the cheap one, and it loses it because of successes, not failures.
The brief asked specifically whether the cascade rescued t1's contract-conformance failures and t3's interval bug. It did not, and it could not have.
t1-logstore. 21 leaf attempts above rung 0 across the arm. Every escalation
that changed model went ds-v4-flash -> gemma-3-12b — from the model measured at
18/20 on the anchor battery to the one measured at 11/20. Score stayed 0.667 in
all three replicates, failing the identical three tests as in arm A
(garbage_only_segment_opens_empty, a_hand_written_segment_is_readable,
active_segment_rolls_at_the_threshold).
t3-shiftplan. One escalation in replicate 2, also to gemma. Score 0.571, below arm A's 0.714 median. The empty-interval family failed in every replicate of both arms.
Three structural reasons the cascade cannot reach these failures:
- The failures are not escalating verdicts. A leaf that writes a wrong
overlaps()finishesdone->unverified_success, which does not escalate. Only budget stops, turn caps and empty responses do. The contract-conformance failures are invisible to the escalation trigger by construction. - Escalation climbs cost-effectiveness, not ability.
leaf()picksorder[call.Attempt()], andorderis sorted byAbility/price. Rung 1 is gemma. Escalating from an 18/20 model to an 11/20 model is a downgrade. Escalations = 1. Even if rung 2 were the right target, a leaf gets one retry, so kimi at rung 2 is unreachable for a leaf under any circumstances.
Reported rather than fixed: each changes what the router does, and patching the subject of a measurement while measuring it would invalidate both.
| # | defect | evidence | suggested fix |
|---|---|---|---|
| 1 | Leaf ratings are fitted to failures only. 103 of 108 leaf outcomes are unverified_success and move nothing, so the rating comes from a 100%-negative sample. |
exec.leaf rating -0.98 from n=5, all budget_stop |
Require a minimum count of graded observations — and of both signs — before a learned rating may override the cold-start prior. |
| 2 | exec.leaf is one global class. A rating learned on one task's pathological leaves routes every other task's leaves. |
5 budget stops on t1 collapsed t2 (1.000 -> 0.000) and t3 (0.571 -> 0.000) | Condition the leaf rating on node size, which is already on every node and is exactly the axis separating t1's oversized leaves from t3's atomic ones. |
| 3 | Success demotes the top rung. As the incumbent's rating passes the top model's cold-start prior, the force-promotion rule stops firing and the strong model leaves the cascade. | 8 of 11 classes went ... > kimi-k2.6 -> ... > qwen3-30b-a3b between run 1 and run 3 |
Keep the highest-role model terminal regardless of measured order, or compare against the top model's own rating rather than letting best be reassigned. |
| 4 | Leaf escalation climbs cost-effectiveness, not ability. Rung 1 is the second-best value, which on a barbell panel is the weakest model. | every t1/t3 escalation went flash -> gemma | For a leaf retry, pick the highest-rated untried rung rather than order[attempt]. |
| 5 | Leaf escalations record no chain. leaf() passes nil for tried, so a retried leaf logs rung: 1 with an empty escalation. |
every leaf escalation in this arm | Pass the pinned-and-failed slug through, as cascade() already does. |
| 6 | No exploration. Only the chosen model accumulates evidence, so a model never chosen is never measured. | 3 of 5 panel members had zero observations after 9 cells and ~1,000 calls | An occasional forced trial, or seed new models from an anchor battery — panel/anchor_battery.py costs $0.02/model and already exists. |
Defect 6 is what makes the others hard to see coming: the ledger is confident about exactly one model and has no information about the four it chooses against.
- The per-cell progress line was rewritten from a broken
python3 -cinto a heredoc, which broke it worse — the heredoc is stdin, so the piped row never arrived. It islastrow.pynow. summarize_eventskeyed escalation on theescalationfield, which defect 5 leaves empty, so it counted zero leaf escalations. It countsrung > 0now, andreroute.pyrecomputed the existing rows from their stored events rather than re-running the cells.- Output paths took their case from
$ARM, writingresults-armb.jsonl.
Two background kills interrupted the shared-ledger arm, and my second resume was launched while the first was still running, so two writers briefly shared one ledger and one results file. What that does and does not damage:
- the ledger is intact — locked per update, event log append-only; no observation lost or double-counted;
- the scores are intact — every cell had its own plan, workspace and grader;
- per-cell event attribution in the overlapping passes is approximate, since the runner slices the append-only log by line position.
dedupe-armB.py splits the passes; results-armB-pass4.jsonl holds the
accidental fourth pass, kept because it independently reproduced the collapse.
results-armB.jsonl was then deleted by my own rm results-armb.jsonl —
this filesystem is case-insensitive, so the two names are one file. Every cell
directory survived, so the nine rows were recomputed from them rather than
re-run: cost, tokens, graph and grade come from each cell's own done.json,
workspace and ledger-after, and wall clock was restored from the run logs.
The reported scores are byte-identical to the originals. One consequence is
visible in the numbers: the replicate-3 directories had been overwritten by
the fourth pass, so replicate 3 above is that pass. Its scores are the same
0.000 / 0.000 either way, which is why the collapse survives the accident
unchanged, but its costs and event counts are the fourth pass's.
The per-cell router events are in events-armB.jsonl and
events-armB-fresh.jsonl, keyed by (task, replicate), rather than inline in
the results rows — one log inlined nine times pushed the results past 3MB.
learning-diff.py loads them, and stamps each row with the file it came from:
the two arms share (task, replicate) keys, so a lookup that searched both tables
would answer the control with the shared arm's events and report them identical,
which is precisely the conclusion the control exists to test.
Wall clock is not comparable between the arms. Arm A ran three concurrent
streams, arm B sequentially. Uncontended per-cell timings are the calibration
round's, in BASELINE.md.
| stage | cells | spend |
|---|---|---|
| panel selection (anchor battery) | 220 | $0.6739 |
| calibration round 1 | 3 | $0.2421 |
| arm A | 9 | $0.8769 |
| arm B, shared ledger (12 cells run; 9 reported, 3 superseded) | 12 | $0.7646 |
| arm B, fresh-ledger control | 9 | $0.6376 |
| total | 253 | $3.1951 |
Arm B used $1.40 of its $8 budget (18%). The whole programme, including panel selection and the baseline, cost $3.20.
Do not ship the router in this configuration. On this suite it is neutral at best and actively harmful once the ledger has three runs of history behind it.
Cheapest fix first:
- Defect 1 — gate a learned rating behind a minimum count of graded observations. It alone would have prevented the entire collapse: five graded observations should never have outvoted a prior.
- Defect 3 — pin the terminal rung to the highest-role model, or the panel's reason for existing evaporates on contact with success.
- Defect 4 — leaf escalation should climb ability; escalating to a weaker model cannot help by construction.
- Defect 2 — condition
exec.leafon node size. - Defect 6 — seed unmeasured panel members from the anchor battery.
Then re-run this: the harness is parameterised, the graders hold at 84 selfchecks, and the arms are one environment variable apart.
The suite also needs a stronger discriminator first. t1 and t3 both failed 0/3 in both arms on the same items — a stable boundary, good for detecting change, but with no cell in either arm moving fail to pass this experiment could only ever have detected harm. A task where the strong model plausibly succeeds and the cheap one plausibly fails is what would let a routed arm show a gain, and the anchor battery already identifies the band it should sit in.