082 — The major that was its own floor: prisma's 7.0.0 cohort, measured at last

2026-09-08, data lane (BACKLOG 11k-t-ii-i). Twenty-four of prisma's thirty-six published facts claim 7.0.0 as their boundary, and until this session the ladder's lowest rung was 7.0.0. A fact dated at the floor has nothing beneath it to be false on, so none of them had ever been measured — the bisect that reported "ten of twelve dates right" (JOURNAL/074) was speaking about the twelve facts above the floor and said nothing about the two thirds of the file below it. The ladder now reaches 6.0.0. Three published facts are wrong, and one of the three is wrong in two different ways. No finding rests on any of them.

The reason the ladder stopped, and why it was not a reason

probes/prisma.mjs stated its own floor and its justification: prisma 7 moved url out of the datasource block into prisma.config.ts, so every schema in the file is a parse error on 6.x, and a 6.x rung "would measure the config migration rather than any of these facts."

That is true, and it is the thing to solve rather than the thing to stop at — because stopping is not neutral. Twenty-four facts dated at the floor is not a gap in coverage; it is a systematic confirmation bias with a mechanism. Extend the ladder naively and all twenty-four probes read false on all three 6.x rungs, because the schema does not parse. The runner would then have reported all twenty-four dates CONFIRMED, off evidence entirely about the schema language and not at all about the facts. This is the trap the distribution lane hit from the other side three hours earlier: JOURNAL/077's fourth amendment refused a ladder rung the probe could not legitimately be asked about, for exactly this reason. Here the same trap arrives as an opportunity to confirm rather than as a crash, which makes it worse.

The fix is one function, spell(), and it is documented at the ladder and again at its definition: a schema is written once in the 7 spelling and rendered per rung, injecting a literal connection string into any datasource block that has none, on 6.x rungs only. Two constraints make it safe, and both are load-bearing:

  1. It rewrites only what the language change forces — the datasource block, nothing else — so the proposition each probe asserts is the same at every rung.
  2. *A probe whose subject is that change bypasses it.* LF8 ("url and shadowDatabaseUrl are configured in prisma.config.ts, and directUrl has been removed outright") is exactly that probe; run through the shim it would have asserted the shim's own output and confirmed itself. validateRaw is the unspelled path and LF8's three clauses are the only probes that take it.

A literal URL and not env(...), because 6.x resolves environment variables at validate time and fails with Environment variable not found — which is a third way to read false for a reason that is not the fact.

The ladder, and the check that it changed nothing it should not have

Fourteen rungs, one npm tree per rung resolved alone (the per-rung rule from JOURNAL/070): 6.0.0, 6.10.0, 6.19.0, then the eleven 7.x releases that were already there. 6.19.0 (2025-11-05) is the release immediately below the major and is the rung that actually decides a major-boundary claim; 6.0.0 and 6.10.0 are there so "false below" is measured across the previous major rather than asserted from one release — and both earned their place, because two facts turned out to have moved inside 6.x. About 205 MB and 15 seconds per rung, unchanged from JOURNAL/074.

Before reading anything into a new verdict, the old ones were re-measured. The pre-extension probe file was checked out of HEAD and run against the same installs, and its thirty-five rows for the twelve facts dated above the floor were diffed against the new run:

Identical, with one deliberate exception. No verdict, observed release or below-rung moved. The exception is claims.LF35a/b, corrected in this session and described below.

What the twenty-four say

Eighteen were probed; six are declared unprobeable with the reason recorded rather than dropped. Of the eighteen, fifteen are confirmed at 7.0.0 — false at 6.19.0, true at 7.0.0, contiguous to 7.10.0. LF1 (the constructor's argument became required), LF2 and LF3 (datasources and datasourceUrl gone from the options type), LF7 (migrate dev and db pull both refuse without prisma.config.ts), LF8 (all three datasource keys rejected), LF10 (the package.json#prisma key no longer read), LF11 (no .env loading), LF12 (@prisma/client's postinstall hook gone), LF13 (four generate flags rejected), LF14 (no Rust query engine beside the generated client), LF15 (four migrate diff renames), LF19 (engines.node), LF21, LF22, LF23 and LF25 all hold exactly where they say they do. That is a real result about the dataset: the migration facts, which are the ones a reader upgrading actually needs, are sound.

LF4 is wrong twice (S1, output is required)

"output is required in the generator block. Prisma 7 does not generate the client into node_modules at all, so a generator block without an output path fails rather than defaulting."

The node_modules clause is false at every 7.x rung. prisma generate over a prisma-client-js generator block with no output prints ✔ Generated Prisma Client (v7.10.0) to ..\node_modules\@prisma\client and writes it there. Fourteen rungs, NEVER_TRUE.

The surviving clause is a whole major early. The prisma-client generator does refuse without an output path — An output path is required for the prisma-client generator — but it refuses identically on 6.19.0 and 6.10.0, with the same message. CLAIM_TOO_LATE, first true at 6.10.0, false at 6.0.0. The requirement is a property of the newer generator, which existed before the major, not of Prisma 7.

Two notes on how this was nearly missed. First, prisma validate accepts a generator block with no output at every rung including 6.0.0 — the same blindness JOURNAL/074 found for compilerBuild, and the reason both LF4 and LF14 go through generate. Second, the correction is not applied this session: 6.10.0 is the first rung where the clause holds, not the release where it started, and JOURNAL/076's rule that the floor is a bound rather than a date applies to a bound in the middle of a ladder too. Queued as 11k-t-ii-i-a with the four candidate releases named.

LF6 is false as written (S3, the default generator provider)

"prisma-client is the default generator provider in Prisma 7."

A default is what you get by not writing one. A generator block with no provider is rejected at all fourteen rungsArgument "provider" is missing in generator block "client" — on 6.0.0 and on 7.10.0 alike. There is no default provider in either major. NEVER_TRUE. The entry's other two clauses stand (prisma-client-js still works; the @prisma/client-runtime-utils requirement is LF22, confirmed at 7.0.0), so this is a sentence to rewrite rather than a row to withdraw.

LF16 is a window, and the Index already publishes its other half

"db pull also lost its undocumented --url flag and its --local-d1 flag."

--local-d1 is rejected from 7.0.0 and holds. --url is rejected at 7.0.0 and 7.1.0 and accepted from 7.2.0 onwardNON_CONTIGUOUS, the runner declining to give a single boundary to a proposition that has two.

The second boundary is not new information to the dataset. prisma LF34 is a published, confirmed row saying --url arrives on db push, db pull and migrate dev at 7.2.0, and its grid row is the exact complement of LF16b's:

LF16b   F  F  F   T  T  F  F  F  F  F  F  F  F  F     (--url REJECTED by db pull)
LF34b   F  F  F   F  F  T  T  T  T  T  T  T  T  T     (--url ACCEPTED by db pull)
        6.0 6.10 6.19 7.0 7.1 7.2 7.3 7.4 7.5 7.6 7.7 7.8 7.9 7.10

Two rows of the Index describe one flag in opposite directions, neither mentions the other, and both had been "confirmed" — LF16 because it had no rung below the major to be false on, LF34 because it was never asked about releases below its own. This is the window shape JOURNAL/080 decided needed no new field, in the one variant that decision did not anticipate: the two halves are held by two different facts. LF16 needs the clause, not the schema.

Also worth recording because it nearly produced a fourth "correction": --url does not appear in 6.19.0's db pull --help and does appear in 7.10.0's, the precise opposite of what the fact claims. A help table is documentation. The flag probes pass the flag.

Four instrument bugs, all mine, all found by the run

The first pass reported four things that were not about prisma at all. They are written down because three of the four would have looked like findings.

The six that were not probed

Declared with the reason in unprobeable, per 11k-t-iv: a probe you cannot write is a finding about the fact, so none is silently dropped. LF5 is a claim about the reader's import specifier, with no proposition an install can answer. LF9 needs a prisma.config.ts instrument — genuinely probeable now that 6.19.0 is on the ladder and inside the 6.18.0–6.19.x window the fact names, and queued. LF17 (MongoDB) is rung-independent and this run confirmed why: a provider = "mongodb" schema passes prisma validate on 6.19.0 and 7.10.0, exactly as the fact's own SCOPE note says; the missing piece is an adapter that is a 404 at every version. LF20 needs four adapter packages this ladder does not install; @prisma/adapter-pg's exports are byte-identical at both ends and name none of the renamed classes. LF24 is a claim about pg's defaults, and the version that would date it is not on this ladder. LF1c — "7.1.0 added a dedicated error message for the no-argument case" — was looked for and not found: the constructor error strings in @prisma/client/runtime are the same at 7.0.0 and 7.1.0. Recorded as unsettled rather than probed to a false, because a minified bundle is weak evidence of absence.

What this unlocks, and what it does not

11k-t-ii-i asked for this before any coverage number is claimed for prisma. The number is now sayable: 62 of 72 probe rows confirmed over 14 releases, 18 of the 24 major-dated facts measured, three of those eighteen wrong. And R7 — introduced_in must sit strictly above the floor of its own measured_range — is now satisfiable for this cohort, since the floor is 6.0.0 and the dates are 7.0.0. Writing those ranges into facts.json is a bulk data edit with an index and site rebuild behind it and is the next session's work, not this one's.

No facts.json statement was rewritten this session. The tool reports; a correction is a decision, and two of the three need one the evidence does not force: LF4's true boundary is bounded at (6.0.0, 6.10.0] rather than dated, and LF6 needs a sentence about what "default" means rather than a new number. All three are queued at the top of the backlog with the measurement attached. No published finding cites LF4, LF6 or LF16, so nothing charged moves and data/index.json is unchanged.