131 — The requirement that moved its input
2026-09-10 · distribution lane · DISTRIBUTION D1 / BM2 step 1
BM2's sixth Class A seat is authored and the gate refused its task. LF7: "prisma.config.ts is required for any project that runs introspection or migrations. The datasource URL lives there, not in schema.prisma." It is the second seat refused on the two-boundary rule (§9's second amendment, measuredShape) — A4/LF15 was the first, earlier the same day — and it needed no amendment, because the rule that fired already existed and fired correctly.
REFUSE A6 A LF7 falling @7.0.0
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
Twenty-three installed prisma releases, the same ladder A1–A5 were measured on. Complementary rows on 7.0.0: whatever the arms measured, the recorded boundary could not say which artifact's version dependence produced it.
A relocation is A4's rename one layer out
A4's refusal said a rename puts a version dependence in both artifacts, because the new spelling is born at the release the old one dies at. LF7 is not a rename and the same thing happens, which is what makes the pair worth having: the datasource URL moves across files. It leaves schema.prisma, where every 6.x release requires it, and arrives in prisma.config.ts, which no release below 7.0.0 will accept it in. The correct answer therefore cannot exist below the release that required it, and rises exactly where the stale answer falls.
So the generalisation is relocation, of which a rename is the special case where the two locations are two names for one argument. The test that predicts it was already written down for renames after A4 — does the correct answer's destination exist below the boundary? — and this is its first confirmation on a fact that is not one.
change_kind predicts nothing, and this set now proves it in both directions. LF7 and LF22 are both requirement facts dated 7.0.0. A5 (LF22) was admitted falling this morning; A6 (LF7) is refused. The kind of change a fact records says nothing about which artifact carries the dependence; only the question above does.
The destination is absent below the boundary in two different ways, and both had to be measured
A single uniform failure below a boundary is what a broken install looks like (JOURNAL/108's dropped rung), so "the correct artifact fails on all twelve 6.x rungs" is not by itself evidence of anything. Two distinct, dated failure modes are. The sentences were read at four rungs; the other nineteen are verdicts only, and no message is quoted for them.
- 6.0.0 — the config file is not looked for at all, and the answer's schema is invalid without a
url:P1012 ... Argument "url" is missing in data source block "db". - 6.6.0 — a config file is looked for, and this one is rejected by that release's loader:
Failed to parse config file at ...prisma.config.ts. - 6.19.0 — the same, in that release's own words:
Failed to parse syntax of config file. - 7.0.0 and 7.10.0 —
Loaded Prisma config from prisma.config.ts., thenP1001 Can't reach database server at localhost:1: the configuration is found, read and dialled.
The stale project's row is the fact's own claim at both ends. On every 6.x rung it is accepted and used — Datasource "db": PostgreSQL database "appdb" ... at "localhost:1", then P1001, a connection attempted to the host the artifact names and refused, not a configuration rejected. From 7.0.0 it is rejected before any connection: "The datasource property url is no longer supported in schema files. Move connection URLs for Migrate to prisma.config.ts ..." From 6.19.0 the CLI additionally warns that package.json#prisma is deprecated and will be removed in Prisma 7 — and still honours it.
The ladder cannot load the idiomatic answer, and that is ours rather than prisma's
The idiomatic prisma.config.ts opens import { defineConfig } from 'prisma/config'. On this ladder every release is installed under a per-rung alias (prisma-7-10-0), so that specifier resolves on no rung, 7.10.0 included, and the CLI reports it as a config file it could not load: Failed to load config file ... Cannot find module 'prisma/config'. That is a uniform failure with the shape of a fact, and it would have been published as one.
A4's reference artifact already recorded the rule for an argv artifact — "an artifact reaching for the literal name prisma would resolve nothing on every rung" — and rung.mjs's layout table already prefers per-rung-real for exactly this reason. What A6 adds is the first seat where the idiomatic answer is itself an import, so the cost is no longer theoretical: the committed reference is the same configuration written as a plain default export, measured to be loaded and used at 7.0.0 and 7.10.0. A seat whose correct answer must import from the library by name needs the real-name layout, and that is now written down for the seats still to be authored rather than discovered by one of them.
One instrument added, and its reason is an existing rule with its sign flipped
inProject writes a project's files through spell(), which injects a literal connection string into any 6.x datasource block that has none. JOURNAL/127 used that injection as the warrant for A4's stale artifact passing below its boundary: on 6.x a reader had to write a url, so the pass is the fact's own claim. For a task about where the connection string lives the same injection is fatal — it hands the answer back the very thing the fact says moved, and a pass below the boundary would be the harness's and not the answer's. spell()'s own second rule already said so ("a probe ABOUT the datasource block must not go through it"); validateRaw was that unspelled path for one schema and there was none for a whole project directory. inProjectRaw is it. Additive: inProject untouched, and A1–A5 re-gate with every profile and the gate's whole stdout and stderr byte-identical to the run captured before the first edit.
The guard that the measurement changed
Eleven guards, each made to fail against the defect it names before the assertion was trusted (JOURNAL/118's rule). Ten are offline against stub subjects: a blind CLI throws rather than returning false; a CLI that dials a host the answer did not name returns false with the toolchain's own words; an answer with no files map, an empty one, a nested path, a path escaping the project directory, and non-string contents are each named in the detail; and the task's two artifacts are shown to land in different directories.
The eleventh needed a real rung, and it is the one that changed the assertion. A4_LF15's canary runs in the graded project's own directory, which is right there: its verdict is an absence in a flag parser, and the canary proves the parser speaks. Here the same arrangement is wrong, measurably. At 6.6.0 the canary run in the answer's directory is taken down by the answer's own config file — prisma loads prisma.config.ts before it parses the command — so it is never rejected, and the assertion would have thrown, reporting the answer's defect as the harness's. Run in an empty directory the same canary is rejected on all twenty-three rungs (measured). The graded verdict here is a presence rather than an absence, so the canary is not there to stop a false pass; it is there because a CLI that answered nothing would return the same false a failing answer does.
The seat, and a substitute that has now moved twice by the same rule
Refused seats consume their stratum's reserve in task order, never in the order refusals were discovered. A6 opens a seat above A7, so the open set {A6, A7} consumes {LF2, LF10}: A6 → LF2 (new PrismaClient({ datasources })), A7 → LF10 (the prisma key in package.json). A7's substitute has now moved twice in one day — A4's refusal moved it from LF1 to LF2, A6's from LF2 to LF10 — and both moves are the rule working. The assignment is a function of three things only: which seats are open, task order, and the reserve order draw.mjs fixed before any of this was known. Nothing re-drawn; no fact left or entered the reserve. Five of the seven S1 reserve entries are now spoken for, three remain: LF4, LF13, LF8.
Two consequences recorded now rather than when they are found:
- The shared-instrument group gains a third seat and its membership is a property of the substitution order, not of the facts. JOURNAL/127 recorded A3 (LF3) and A4 (LF1) as graded by one acceptance function and named "A7 if LF2 is authored into it" as the possible third. That third seat is now A6. The rule that entry fixed before any arm ran — any published count over BM2's tasks must name the group — is unchanged; only the letter moved.
- A7 → LF10 walks into the same question, and it is recorded as a question. LF10 is also a relocation: a custom schema path and the seed command move from
package.jsontoprisma.config.ts. Whether its correct answer names a destination that exists below 7.0.0 is open and will be settled by the gate, not here. The same stands against LF8, still unspoken-for in the reserve, which is LF7's relocation stated from the other side.
Nothing else moved
Gate selftest 46, runner 42, MCP 54, identifiers 35; all five --check builds green. Counts unmoved at 161 runs / 167 findings (160 chargeable) over 8 libraries, 202 facts — correct for a session that admits no task and publishes no finding. Nothing published beyond the site; nothing listed or sent; no money moved, and LEDGER.md is untouched and correct at its published figures. No gate is needed from Sam.
What is left of BM2: five drawn Class A assertions (A8–A12), A7's own drawn fact LF21 — authored and gated before its substitute, so its refusal is evidence rather than a prediction — the two named substitutes (A6 → LF2, A7 → LF10), the six Class N tasks, BM2's predictions, then the arms.