125 — The rename that is version-dependent in both directions

2026-09-10 · distribution lane · DISTRIBUTION D1 / BM2 step 1

BM2's fourth acceptance assertion is authored and the gate refused its task. A4 — LF15, prisma migrate diff renamed its inputs at 7.0.0 — was built in full, run against the same twenty-three installed prisma releases as A1, A2 and A3, and came back with two complementary rows:

correct  ............+++++++++++
stale    ++++++++++++...........
both artifacts carry a version dependence — the correct solution rises and the stale one falls,
so the task has two boundaries and the results could not say which one it measured

No amendment was needed and none was written. The refusal is the two-boundary rule §9's second amendment already carries, firing for the first time on a real task, and the sentence it produced is the true one about what is wrong.

Why a rename is the shape that trips it

Every refusal BM2 has collected so far was about one artifact's row. The seventh amendment refuses a rising task whose boundary is a major's floor, because "the API did not exist below" and "this artifact is written in the new major's dialect" are false on exactly the same rungs. The eighth refuses a task whose two rows are identical, because it separates nobody. A4 is neither. Its two rows are as different as two rows on this ladder can be — each is the other's complement — and that is precisely the problem.

A removed fact puts the version dependence in the stale artifact alone: the old spelling stops working and the correct answer is something that always worked. A rename puts one in each. The old spelling dies at the release and the new spelling is born at it, so the correct answer inherits a version dependence of its own and the task acquires two boundaries at one release. Both halves were measured on this ladder rather than argued:

A benchmark cell would then be unreadable in the way the refusal says. The arm difference might well be real, but the boundary the results file records could not say which artifact's dependence produced the number, and the shape the manifest declares would be a choice rather than a measurement. Admitting it would rest a published number on a coin with the same face on both sides.

change_kind does not predict this, and the set already contains the counter-example

The tempting generalisation — renamed facts cannot carry a Class A task — is false, and BM2's own draw disproves it. What predicts the two-boundary shape is a narrower and checkable question: does the correct answer's API exist below the fact's release?

factseatnew spelling below 7.0.0?
LF15 --from-schema / --to-config-datasourceA4no
LF25 @prisma/client/edge, which replaced /wasmA8yes

./edge is in @prisma/client's export map at 6.0.0, 6.19.0, 7.0.0 and 7.10.0; ./wasm is there at 6.0.0 and 6.19.0 and gone from 7.0.0. So LF25's correct answer can be flat-passing and the falling shape is available to A8, while LF15's cannot be. Both facts are renamed; the kind field says nothing about which. The question is recorded in prompts/benchmark-bm2-draw.md for the seats still to be authored — as a question, not as a prediction of any seat's outcome, because a seat's outcome is what its gate run says. A8 is authored and gated like every other seat.

The instrument the task needed, and it is reusable even though the task is not

A4's graded verdict is an absence: no rejection in the CLI's output. An absence and a blind instrument return the same value — the rule tools/lib/identifiers.mjs exists to enforce — and here the instrument really can go blind, because at 7.10.0 the correct invocation's entire output is the empty string, which is exactly what a CLI that never ran produces.

So before the produced argv is run, the assertion runs migrate diff --sp-canary-unknown in the same directory. That flag names nothing any release of prisma has, so it must be rejected on every rung; if it is not, the assertion throws — an error cell, the harness's own failure, never a false. It is A3's if (!r.generated) throw in a different coat: only the harness may throw, and a verdict is never produced by an instrument that cannot see.

Made to fail against the defect it names before it was trusted (JOURNAL/118's rule), against three stub subjects: one returning "" to everything throws; one that rejects only the canary returns true; one that rejects the real invocation returns false carrying the toolchain's own words.

Two things measured on the way past

prisma 7 answers an empty diff, silently, when there is no config file. At 7.10.0, with no prisma.config.ts in the directory, prisma migrate diff --from-schema schema.prisma --to-empty --script prints nothing and exits 0 — and --exit-code, whose contract is empty 0, error 1, not empty 2, reports 0 for a schema holding one model. With a prisma.config.ts present the same invocation prints the CREATE TABLE script and exits 2. So any prisma 7 task whose criterion is "the diff produced SQL" needs a config file, which is LF7 — drawn as A6, dated at the same release. That is a fourth door added to the three JOURNAL/119 recorded, and it is why A4's criterion is the narrow one: which spellings the CLI takes, and nothing else in the room.

LF15's own probe rows read the help table. LF15a..d are four migrate diff --help greps. That is the instrument JOURNAL/084 spent four days learning not to trust — --url is absent from 6.19.0's help and present in 7.10.0's, the exact opposite of which releases accept it — and LF16's clauses were rewritten to pass the flag for that reason. A4 passes the flags. The fact is not wrong and its date is not in question here; what is recorded is that one of its four clauses is measured by a weaker instrument than the task drawn from it, and that the task's rows agree with the fact's date anyway.

The seat, and a rule that moved something already written down

A4's seat goes to the S1 reserve. The order was fixed on 2026-09-10 while two seats were open: refused seats consume the reserve in task order, not in the order refusals were discovered, and the two open seats were assigned A2 → LF16 and A7 → LF1. A4's refusal opens a third seat above A7 in task order, so the open set {A4, A7} now consumes {LF1, LF2} as A4 → LF1 and A7 → LF2.

That moves a substitute that had already been published, and it is the rule working rather than the rule failing. Letting A7 keep LF1 because its exposure was noticed first is discovery order under another name — the operator's authoring sequence deciding which fact enters at which seat, which is the property §7's draw exists to remove. The assignment is a function of three things only: which seats are open, task order, and the reserve order draw.mjs fixed. Nothing was re-drawn; no fact left or entered the reserve; the S1 reserve is seven deep with three entries now spoken for and four remaining (LF10, LF4, LF13, LF8).

JOURNAL/123's measurement is unaffected, and it is worth restating why it was made. That session established, by measurement, that A3 grades LF3 and not LF1 — an artifact carrying both an adapter and datasourceUrl still fails at 7.0.0 and 7.10.0 — because without it two of the twelve seats would have probed one belief. LF1 still enters the set; it enters at seat A4 rather than at seat A7. The measurement was about the set, not about the seat number, and it holds.

State

A1, A2 and A3 re-gated on the same twenty-three rungs: all three admitted, every profile string byte-identical. A4 is not in the manifest's tasks array — a refused task never sits there with a note on it — and keeps its fact id in tools/benchmark/tasks/prisma/A4.lf15.reference.mjs, A4.lf15.stale.mjs, prompts/sent/benchmark-prisma-a4-lf15-refused.txt and A4_LF15 in tools/benchmark/tasks/prisma.mjs, so the refusal re-runs. That is the convention BM1's A2/LF4 set and BM2's A2/LF14 followed.

Nothing in the dataset moved: no battery ran, no fact was written, no draw was re-read. Counts unmoved at 161 runs / 167 findings (160 chargeable) over 8 libraries — the correct result for a session that admitted no task and published no number. No claim of benefit is made anywhere; the benchmark still has no result, and the claims policy is unchanged.

What is left of BM2: eight drawn Class A assertions, A4's substitute (LF1) and A7's substitute (LF2), the six Class N tasks, BM2's predictions, then the arms. Every other item in this lane is one of the eight asks for Sam: D2's four and D3's four.