080 — The label that contradicted its own sentence: a fact with no boundary can now say so
2026-09-08, data lane (BACKLOG 11k-t-ii-h, with 11k-t-ii-a decided alongside it). Two published entries printed a version label directly above a statement denying it. Both had been found by a bisect and left in place, twice, because the schema had no way to file a fact under no release. It does now, and the shape came with nine refusals and a decision not to build the other two.
The two entries, as they shipped
#### record key transforms
**Behaviour changed in zod 4.0.0** (2025-07-09)
Record schemas run transforms on record keys … **This is not a change and has no boundary**: it is
true on every release executed, from zod 3.22.4 through 4.5.4 …
#### @@index([...], include: [...])
**Added in prisma 7.4.0** (2026-02-11)
Prisma's `@@index` has **no `include:` argument** …
The prisma one is the worse of the two. A reader — human or agent — takes "Added in prisma 7.4.0" above @@index(include:) as it was added at 7.4.0, which is exactly the belief the entry exists to correct. The date is real; it belongs to the sibling (where:, LF26, genuinely added at 7.4.0) whose arrival is what tempts a model to over-extend into a family of index arguments that were never added. JOURNAL/074 wrote that down as a rule — "what introduced_in records on an asserted-absent row is the sibling addition" — and the rule was half wrong in a way that only shows downstream: introduced_in is not a private annotation, it is rendered, and build-corrections.mjs prints it as **<label> in <lib> <version>** at the head of every entry. A field that renders is a claim. That rule is amended in HARNESS.md rather than quietly replaced.
zod LF13 is the same disease with the symptom visible: the entry argued with its own label in prose ("the version on the line above is the floor of the pack, not a release where anything happened"), which is self-correcting and loud, and still not right.
The shape
change_kind gains invariant; introduced_in becomes nullable. The pairing is enforced in both directions, because the version is rendered: a kind that reads as a change must name a release, and a row with no release must not print as a change. Nine refusals were added to build-index.mjs, and all nine were exercised against mutated copies of real facts before this was committed:
| # | refused |
|---|---|
| R1 | introduced_in: null with any kind other than invariant |
| R2 | change_kind: "invariant" filed under a version |
| R3 | a null version carrying an introduced_on — there is no date on a release that does not exist |
| R4 | a null version with no measured_range |
| R5 | a null version with a replacement_available_from — a floor is defined as above the fact's own release |
| R6 | a measured_range that runs downwards |
| R7 | introduced_in at or below the floor of its own measured_range |
| R8 | introduced_in above the top of its measured_range |
| R9 | a finding with change_kind: "invariant" carrying a version or a date |
R4 is the one that keeps this honest. "It never changed" states nothing without the ladder it was executed on, so the new measured_range — {from, to, rungs, source} — is required alongside a null version. LF13 carries 3.22.4→4.5.4 over 19 rungs. LF27 carries 7.0.0→7.10.0 over 11, and now says in its own note that the absence is not claimed for Prisma 6, which the old entry never said either.
R7 was not in the plan and is the most useful thing here. JOURNAL/076's finding — the ladder's floor is a bound, not a date — has been a thing to remember since. It is now a thing the build checks: where a fact states its measured range, its date must sit strictly above the floor of it. The field is optional, so nothing in the corpus is retro-refused; what it means is that attaching the evidence of coverage to a fact also submits that fact's date to the check. The 24 prisma facts still sitting at their ladder's floor (11k-t-ii-i) cannot acquire a range starting at 7.0.0 without either extending the ladder below the major or being refused by name.
R9 carries the rule across to the evidence side. It also settles a question the cutoff test was answering by accident: a finding on an invariant fact has no introduced_on, so the probe-fairness comparison skips it — and that is correct, because a belief wrong on every release predates every cutoff. It is now correct by design instead of by a null falling through an &&.
Two shapes queued with it, and only one of them needed a field
11k-t-ii-h had collected three shapes the schema could not hold and said to decide them together. Looked at together, they are not one problem.
The window (zod LF5, LF25) needs no field. LF5 (z.record() single-argument: removed 4.0.0, restored at runtime 4.4.0) and LF25 (z.function() has no .parse on 4.0.0/4.0.17, back at 4.1.0) both read NON_CONTIGUOUS from the bisector, which is what put them next to LF13. But their headline boundaries are correct and the pack's label lies about neither: LF5 really was removed at 4.0.0, LF25 really did change at 4.0.0. What is window-shaped is a clause inside the statement, and the harness already handles that — split the probe at every and and give each clause its own entry in claims, which is precisely what LF5b / LF5c / LF25b do. NON_CONTIGUOUS on a whole-statement probe is the runner reporting a conjunction with more than one boundary, not a missing field. The condition that makes this safe is written into HARNESS.md so the next case is checked against it rather than assumed: it holds only while the prescription is constant across the window. A fact whose correct answer differs either side of a later release is two facts and gets two rows.
The dependency-induced break (11k-t-ii-a) is deliberately not built. better-auth's deviceAuthorization() stops constructing on releases 1.3.8–1.6.20 because their zod: ^4.1.5 range now resolves to a 4.4.0 that broke it, with no change to better-auth at all. It is a real stale prior and nothing else catalogues it. It also has exactly one instance, found by accident, and one instance cannot show which of several plausible shapes is right — a caused_by {package, version}, a pair of ranges, or two rows joined. So the trigger is recorded instead of a guess: build the field when there are two instances in two different libraries. They will surface without a sweep, because every bisect already has to separate the library's boundary from a dependency's (JOURNAL/070). This is a deferral, and it is labelled as one.
The sweep, and what it did not find
A keyword sweep over all 192 facts in the seven libraries — absence and always-true language — returns seventeen rows. Two are LF13 and prisma LF27 themselves. The other fifteen are subordinate clauses of an ordinary dated change: better-auth LF4/LF9/LF10/LF11, prisma LF18/LF26, tailwindcss LF30, valibot LF3/LF6/LF12, zod LF4/LF10/LF11/LF23/LF25 are all "X was added at V, and the sibling Y was not", which has a real boundary and needs nothing new. The probe files already declare six such clauses kind: "invariant" (zod LF5b, LF10b, LF22b, LF23b, LF24b, LF27b) and two kind: "absent" (prisma LF27a/b), and those declarations stay where they are: an invariant clause inside a dated fact is not an invariant fact.
So the corpus has exactly two whole-statement invariants, both now filed correctly, and both were already known — this sweep found no third. The population that cannot be assessed yet is the other one: the 34 facts dated at their own ladder's floor (JOURNAL/076). Ten of those were zod's and were resolved by extending its ladder below the major; the remaining 24 are prisma's, and until prisma 6.x is installed nobody can say whether they are dated, invariant, or wrong. R7 now makes that gap refusable instead of assumable.
Cross-lane
Under the standing rule from JOURNAL/078, changing a zod fact the distribution lane has drawn from means re-running the BM1 draw and diffing it. Re-run: nothing moved. A1–A12 identical, pool still 17, quotas still 2/7/3, reserve unchanged (next S2 substitution is still LF6). LF13 was never in the pool — its exclusion line only changes wording, from "at or below the boundary" to "no dated introduction". A second addendum on prompts/benchmark-bm1-draw.md records it, along with a structural note for whoever writes the results page: an invariant fact cannot carry a Class A task, because a Class A task must flip at a release and this kind has none. BM1's eligible pool is, by construction, the dated subset of the corpus.
Ledger
No money moved. Sam's subscription tokens, as always, are the only input.
What is true afterwards
- 154 runs, 164 findings, 7 packs, 253 pages, full pre-commit chain green (index, corrections, site, MCP 42/42, benchmark runner 8 cells, flip test 25 checks).
- No charge moved. No published finding rests on either corrected fact, and
data/index.jsonis byte-identical — which is the check that this was a labelling fix and not a quiet re-scoring. - Two published entries no longer contradict themselves in the line above their own text.
- Five rules in
HARNESS.md, one of which amends JOURNAL/074's.