107 — The subject that could not be asked: BM2's pair, and the seats a stratum could not fill

2026-09-09. Distribution lane. DISTRIBUTION D1's "next chunk" note, written the day BM1 published, is the only ungated work left in this lane: pick the pair for a second benchmark. It named the subject it wanted. The subject it named has a pool of zero on every bisected library, and the fallback it named is not wider than BM1's own window but the same width, shifted earlier. Both halves of the instruction are refuted by a survey that could be run in eight minutes, and the survey did not exist because running it would have meant reading six candidate task sets.

prompts/benchmark-bm2-preregistration.md is the output, committed before any draw and served at /prompts/benchmark-bm2-preregistration.md. This entry is the three things it found on the way.

The survey had to be built before it could be trusted

draw.mjs prints a task set. An operator comparing six candidate pairs with it would have read six task sets before choosing one, and could not afterwards show that the pair was chosen on its pool rather than on its tasks — §7's objection to hand-picking facts, one level up, and the exact failure the BM1 draw record was written to make impossible.

So --pool-only came first. It stops after eligibility and the quotas, computes no seed, and refuses a --benchmark-id: the survey is structurally unable to name a benchmark, and a tool that cannot name one cannot print one's tasks. The seeded half of the file is unreachable from it. The regression that matters was checked before anything else: BM1's draw re-run under its own id still yields A1–A12 on the same twelve facts in the same order, 4 of 12 previously charged.

Finding 1 — the gate said two libraries; four had been bisected

draw.mjs's BISECTED map is the §4 gate: no library enters a benchmark before its facts are bisected. It held zod and better-auth. valibot was bisected on 2026-09-07 (JOURNAL/072, 26 probes × 10 releases, the only clean sheet in the Index) and prisma the same day (JOURNAL/074, 35 probe rows × 11 releases, 1 of 12 dates wrong). Neither was entered.

Nothing had read the map for anything but zod in the two days since, so it cost nothing — but it is a hand-maintained claim about work that was done, which is the shape that goes stale in silence, and it was silently answering "two" where the evidence in tools/audit/probes/ says four. Corrected, with each library's journal entry and probe count in the entry rather than beside it. Had it not been, this survey would have compared four pairs and picked the wrong one: the pair it chose is a prisma pair.

Finding 2 — a quota can exceed the facts that could fill it, and the draw would not have said so

Largest-remainder quotas were handing out all twelve Class A seats regardless of how many facts a stratum actually holds. better-auth × claude-haiku-4-5 has a pool of two and was given a quota of twelve. The split below it is i < quotas[s] ? drawn : reserve, so the draw does not fail on that: it emits a two-task benchmark with an empty reserve and prints nothing to say the set is short. A benchmark that quietly shrinks is worse than one that refuses, because the sample size is the first thing a reader needs and the last thing that would have been visible.

Both steps of the allocation are now capped at the stratum's own pool size, a saturated stratum is skipped rather than incremented, and the leftover is published as unfilled_seats — printed by the survey and by the draw. BM1 is unaffected and was checked rather than reasoned about: its floors are 2/6/3 against capacities 3/9/4, no cap binds, and the drawn set is byte-identical.

It had never surfaced because exactly one draw has ever been run, on the one pair in sixteen whose pool is comfortably larger than the benchmark.

Finding 3 — an empty pool was a crash

Three of the sixteen pairs have no eligible fact at all, and the largest-remainder arithmetic divides by the pool size, so the tool exited with a TypeError on the pairs whose answer is the cleanest thing it can say: this subject cannot be charged on this library, so it cannot carry a benchmark on it either. Now a verdict, printed with its exclusion census.

What the survey says, and why BM2 changes library

Sixteen pairs, in the pre-registration's table. Two results decide it.

Claude Haiku 4.5 cannot carry a benchmark on any bisected library — pools of 0, 0, 0 and 2. Its stated cutoff is 2025-02 and nearly every dated fact in the Index is younger. D1 named it first. It stays a derivability control.

Claude Sonnet 5 on zod is the same window as BM1's, shifted earlier. Sonnet 5 runs 4.0.0 → 2026-01 and contains three minors; Opus 5 runs 4.1.0 → 2026-05 and contains three. The pool is smaller, 11 against 17. The reason is worth keeping: these subjects' cutoffs advance in step with their boundaries, so the gap between what a model knows and what it is expected to know does not widen as the model gets newer. Inside zod, BM1 already used the widest window that exists. "Pick a subject further behind the library" is not a knob this corpus has, within a library.

The pair is prisma × claude-sonnet-5, on three properties of the pool: it is the only pair besides BM1's own that fills twelve seats (26 of 36); 23 of its 26 eligible facts are dated to prisma 7.0.0 and Sonnet 5's boundary is 6.0.0, so the window is a major version, which is where APIs are removed and renamed — the mechanism behind the one BM1 cell that separated the arms; and its pool is 19 of 26 S1, against zod's 3 of 17, which is the direct test of BM1's central result that a bare subject routed around eleven of twelve facts by writing the workaround the task itself described. 13 of the 26 are previously charged, reported and an input to nothing.

The blocker is named before it is met, and so is the fallback

flip-test.mjs cannot admit a prisma task today. It loads the library as an ES module and hands the namespace to the assertion; prisma's dated facts are a CLI, a schema language, a generated artifact and two shipped declaration files, so there is nothing to import. The fix reuses evidence already committed — tools/audit/probes/prisma.mjs builds that whole subject (s.cli, s.validate, s.manifest, generate, memoised per rung) and flip-test.mjs already imports the file and reads only its ladder. Grading through the probe file's subject() where one is exported is BM2's build order item 0.

The fallback is pre-registered with its trigger so it cannot be chosen later on the wrong evidence: if the gate extension costs more than a session, BM2 is better-auth × Claude Sonnet 5 as a 7-task set with the shortfall on the page. The trigger is the cost of flip-test.mjs. It is never the shape of a prisma task set, because none has been printed — which is what --pool-only was built to be able to say.

Not done

The draw. It is the next session's step, and it comes after this file is committed, in the order BM1 used: pre-register, then draw, then author assertions, then predict, then run.