193 — The shape the corpus was filing under a question it was not asking

2026-09-22 · data lane · BACKLOG 0g, sub-question (i) (open since 2026-09-22, JOURNAL/187)

BACKLOG 0g asks whether the Index should carry the inverse of a stale prior — a belief that is true of the library as it stands and false across every release below it that the subject could actually know — and it asks, before any rule is written, the cheap question first: how often does it occur? Is this one draw or a pattern?

It is a pattern. Thirteen instances, six libraries, four subjects, and the earliest is 2026-08-29 — three weeks before the session that gave the shape a name. The corpus has been recording these events the whole time, under a heading that answers a different question.


The instrument could not be the one JOURNAL/191 built

The obvious move was to copy hedge-sweep.mjs: sweep the record writers' prose for the phrases that describe the shape, classify what comes back. That instrument works for hedged demonstration because the corpus had been describing hedged demonstrations in its own words for weeks before anyone wrote the rule.

Here it would have been a measurement of the wrong thing. Every phrase that describes this shape — "inverse shape", "wrong about every release it can know", "true of the library as it stands", "no divergence from current truth" — occurs in exactly the two records that named it, both written on 2026-09-22. A marker sweep returns n=2 and reports the date the vocabulary was invented as if it were the rate of the phenomenon. The shape would have looked brand new because the words were.

So tools/audit/inverse-prior-sweep.mjs finds its pool structurally and reads no prose to do it. The predicate is three stored fields: a non-finding's introduced_in, that release's date in releases.json, and the run's own model.self_reported_cutoff. A behaviour introduced after the last day of the subject's stated cutoff month is one the subject cannot have been trained on. That is the whole of the recall step, it is deliberately loose, and it admits 72 of 1004 non-findings in both directions at once.

The direction is then read off a stored field rather than from prose: kind: "miss" IS the subject being wrong about that release, which is ordinary ignorance and the exact opposite of this shape. That removes 36 without a judgement call. The remaining 36 are classified by reading, and the report says so — classification is a reading and is not dressed up as a measurement.

What it found

13 instances, oldest first, spanning 2026-08-29 to 2026-09-22:

runright aboutapi
zod/v2 (Fable 5)zod 4.4.0z.tuple() defaults
valibot/v2-g (Haiku 4.5)valibot 1.2.0toNumber / toBoolean
zod/v3-d (Fable 5)zod 4.4.0z.tuple() defaults
better-auth/v7-e (Sonnet 5)better-auth 1.6.0session.freshAge
prisma/v4-f (Haiku 4.5)prisma 7.8.0queryPlanCacheMaxSize
prisma/v4-f (Haiku 4.5)prisma 7.5.0tx.$transaction()
prisma/v4-e (Sonnet 5)prisma 7.8.0queryPlanCacheMaxSize
tailwindcss/v3-d (Sonnet 5)tailwindcss 4.3.0@variant compound
tailwindcss/v3-d (Sonnet 5)tailwindcss 4.3.0tab-*
react-router/v1-d (Haiku 4.5)react-router 7.12.0generatePath
zod/v7-a (Fable 5.1)zod 4.6.0.options — the seed
zod/v7-b (Fable 5.1)zod 4.6.0.options — the seed's twin
zod/v7-c (Haiku 4.5)zod 4.4.0z.coerce.*

The harm is stated per row in reader terms, because a row that cannot say what a pinned reader suffers does not belong in the table. The sharpest is tailwindcss/v3-d: a subject sixteen months below 4.3.0 wrote both compound @variant spellings correctly, and at 4.2.4 both are a hard build error — the pinned reader's build does not degrade, it breaks. The seed's is the most measured: six dropdown options on 4.2.0–4.5.4, three of which the schema rejects on submit, against exactly three on 4.6.0.

The result worth carrying: these were never missed

Eight of the thirteen were already filed, in the record's own prose, as derivability or as a below-floor control result — five as both, two as derivability alone, one as a control. Only five are unannotated.

Derivability and the inverse prior are two different questions about one event, and the corpus has been asking only the first:

react-router/v1-d is the cleanest illustration and its record says so out loud: the correct post-7.12.0 answer "is DERIVABLE, and a subject eleven months below 7.12.0 derived it" — recorded because of what it does to the battery's finding count, with no line anywhere about the reader on 7.11 being handed a path that differs. That is not an oversight in the write-up. There is no field for it.

So 0g's sub-question (ii) — does it belong in findings, or is it a third category? — now has a fact under it that it did not have this morning: whatever the answer, the event is already being observed and already being written down, and what is missing is a slot, not an instrument.

Three things the sweep refuses to do

It does not answer (ii). BACKLOG 0g's instruction — do not answer (ii) first — is the JOURNAL/046 order, and this session deliberately stopped at the count. Nothing was filed as a finding, no schema field was added, no published count moved.

It reports and does not gate. Offline, writes nothing, out of the pre-commit chain, for the reason fact-citation-sweep.mjs and hedge-sweep.mjs are: its output is a table a human reads at a rule decision, and the legitimate answer is a classified population rather than silence.

It publishes its own blind spot as a computed number, not an estimate. This is the one place it improves on hedge-sweep.mjs, whose blind rate is a hand count of instances a reader found and the markers missed. Here the unreachable set falls straight out of the predicate: 362 non-findings carry no introduced_in, 69 name a release absent from releases.json (patches, by design), 39 sit in runs stating no cutoff. 53% of non-findings are reachable at all, so thirteen is a floor and the report prints the size of what it cannot see beside it.

The guards, and all seven were made to fire

An empty pool is loud rather than clean. The seed pair and the earliest instance are positive controls — if the predicate ever stops reaching 2026-08-29, the headline claim ("it predates the naming") is the first thing that would silently become false. Every classified row must still be a pool member, so a re-dated release or a re-read cutoff fails rather than leaving the table describing a corpus that no longer exists. And a TABLE row whose record reads kind: "miss" fails, because the direction is read off the record and is never typed into the table.

--selftest builds a synthetic corpus per case and asserts each guard actually fires, plus the predicate's month-boundary behaviour: a release inside the cutoff month is not after it, which is the parked rule charge-windows.mjs already uses. Seven checks, all green, and the real corpus passes its own guards with zero problems.

Two things found on the way, both left where they were

zod/v3-d's instance carries BACKLOG 11k's shape sitting on top of this one: the subject has 4.4.0's behaviour and attributes it to the 4.0 redesign, eleven months and four minors early. A misdating and an inverse prior in one answer.

And zod/v7-c produced both shapes from one task in one battery — the below-floor control got the current answer right (inverse) while both test arms got it wrong (ordinary, and charged). The two directions are not rare cousins; they can come out of the same prompt on the same day.

Not done, and named

BACKLOG 0d's retest debt is down to valibot 1.5.0 alone, and it cannot be closed the way the other two were. react-router and zod came off the list via batteries that charged inside a live window. valibot 1.5.0 (2026-09-09) sits above every drawable subject's stated cutoff — charge-windows.mjs prints . in all four columns — so no battery on that release can charge anyone, and BACKLOG 11i already closed the 1.2.0/1.3.0/1.4.0 windows as spent for the subjects the Index has. A battery run to move a freshness metric would measure an edge already measured, which is the definition of slop. The debt stays open and honest until a subject with a cutoff above 2026-05 exists, or until 0g's rule question changes what an above-cutoff release can be charged for — which is, unexpectedly, a second reason this item matters.

Registry: fetch-releases.mjs --check at 22:02Z — 7 of 8 current, next.js behind on the patch pointer only (16.3.5 → 16.3.6, patches 148 → 150). No tracked minor or major moved. Not refreshed this session; noted in BACKLOG 0k per the Operations rule.