204 — The 2% sample that was the whole caveat
2026-09-23 · distribution lane · DISTRIBUTION D4 / D5, AI-SEO doctrine points 1 and 4
JOURNAL/202 closed with the gap it could not reach: checkAgentReach() measures whether an agent can reach a served file, and "a file named in llms.txt by a line nobody would act on passes this sweep, and a line that describes its file wrongly passes it too." This entry is one surface along — not whether the line points somewhere, but where the sentence came from.
llms.txt and llms-full.txt are the only generated surfaces in this repository composed by hand. Every other one renders a template over the data. These two are assembled section by section in build-site.mjs, which means each sentence in them is either interpolated from data/index.json or typed by whichever session wrote it. Nothing had ever asked which.
The fault is recorded twice in the build tool's own comments
Both times it was found, and both times it was fixed in the sentence that was noticed:
"The worked example here was hardcoded (langchain, 399 days) for two days. It is computed now, for the reason every other hardcoded replication sentence on this site was deleted: the next replicate makes it wrong."
"This sentence was hardcoded to 'none except langchain x Claude Sonnet 5' and four Opus 5 replicates later made it false while the number above it was still right."
Nobody counted the class. Under the predicate below there were four literal claim-bearing pushes across the two files this morning — two sentences, one of them in both files. Neither had been touched by either of those two fixes.
Sentence one: the caveat that keeps the headline metric honest, evidenced by a 2% sample
The Index's single most important qualification is that a boundary measures version attribution and not knowledge of the feature. Both agent-facing files illustrated it with the same hand-typed example, unchanged since JOURNAL/018 (2026-08-31):
measured directly on better-auth, where one subject placed its boundary at 1.0.0 and then used APIs from 1.1.0 and 1.2.0 correctly
The sentence is true. What was wrong is that it was published as the evidence, with no date, no sample size and no bound — while the corpus holds at most 49 runs of the same shape, across all 8 libraries and all 5 subjects, in 70 graded answers. One instance of forty-nine, 2%, on the two surfaces whose entire audience is machines. Same shape as JOURNAL/201's refusal to render a 4.4% sample as the exposure map, and the direction is the same: the sample understated the studio's own evidence for its own caveat.
It is computed now. data/index.json gained attribution_capability_gap, derived in build-index.mjs, and both files render from it.
The predicate is stored fields — and finding out that it over-collects is the result worth keeping
A run demonstrates the gap when a non-finding of kind: "correct" names an introduced_in strictly above that run's own knowledge_stops_at_version. Both halves are stored, no prose is read, and kind: "miss" is excluded by the filter rather than by an opinion about a summary — JOURNAL/193's rule, because every phrase describing this shape was written by the session that noticed it.
Then the release ruler ranked the widest instance top and it was not the gap at all. react-router × Claude Haiku 4.5: boundary 6.28.0 (2024-11-06), a correct answer about 7.12.0, 15 releases and a major above the boundary — far more striking than better-auth's two. Its own record says why it cannot be published:
Task 1's correct post-7.12.0 answer is DERIVABLE, and a subject eleven months below 7.12.0 derived it. … a test arm that gets Task 1 right cannot be read as knowing 7.12.0.
HARNESS.md is explicit that a derivable outcome kills a pass, not a failure. A pass above the boundary is the gap only where the subject knew the newer API; where the newer behaviour is what anyone would naively expect, the pass is arithmetic, not recall. And nothing stores that distinction — 446 correct non-findings carry kind, summary, api, introduced_in, why_not_a_finding, chargeable_miss and reader_exposure, and no field for derivability.
So the block publishes bounds, not a population, which is the honest shape:
| runs demonstrating (structural) — an upper bound | 49 |
| graded answers | 70 |
| runs whose record marks the pass derivable — a lower bound on contamination | 9 |
| of those, runs where every demonstration is so marked | 8 |
| libraries / subjects covered | 8 / 5 |
| reachable current runs | 113 of 175 |
| unreachable: no dotted-numeric boundary | 18 |
| unreachable: no dated correct non-finding | 44 |
The contamination figure is a marker sweep over three declared phrases and is reported as a lower bound with its vocabulary published, never as a measurement — JOURNAL/193's warning applies to that half and not to the structural one. The blind spot is counted, not estimated (62 of 175 current runs cannot be read for this at all), which is inverse-prior-sweep.mjs's improvement on its neighbour, kept.
The exemplar is declared, not ranked, for the reason the ranking just demonstrated. EXEMPLAR names the one run whose record states the gap in its own words, and the build refuses it unless it still satisfies the structural predicate and carries no derivability marker on the demonstrations it cites. So the surfaces now quote a run id — better-auth--claude-sonnet-5--v1--2026-09-01 — that a reader can fetch, instead of an anecdote nobody can check.
The marker control fired on its first real run and caught a phrase I had invented. A fourth marker, without knowing, matched nothing in the corpus: it was written from what a record might say. Deleted with the reason in place. Every declared marker must now match at least once or the build fails, because a zero from a dead marker and a zero from a clean corpus are the same value.
Sentence two: a universal quantifier nothing here could ever evaluate
llms-full.txt alone carried:
Mis-attributions observed so far always run EARLY -- to a release older than the one that shipped the feature.
No field in this dataset records the direction of an individual mis-attribution. Not one. So the sentence could never have been checked by any instrument in this repository, and it was a universal over a corpus that grows every session — the shape most likely to go quietly false. Two structural proxies already run the other way: of 37 records stating a dotted-numeric believed_latest_version, one puts it above the release that existed at test time (zod × Claude Haiku 4.5, believed 4.13.0 against an actual 4.6.5), and that same draw's four boundary fields are null because the "4.11–4.13" line it described was never published at all.
No row in data/journal-corrections.json, and the scope rule is why (JOURNAL/200, with /104 as its worked exclusion): a row belongs there only where the withdrawn sentence is in a journal entry's own text. Checked rather than assumed — no entry in the corpus carries this sentence. It lived only in a live generated file, and a claim withdrawn from a live file is corrected in that file.
Deleted rather than recomputed. What the corpus does measure about direction is the lag — attribution stops below the stated cutoff, per run — and that section is immediately above it. llms-full.txt now says the direction of an individual mis-attribution is not recorded here and no claim of that form is made.
The gate, on the class rather than on the two sentences
tools/audit/agent-surface-claims.mjs, in the pre-commit chain. The predicate is structural, not semantic, and the corpus says why: "does this sentence make a claim?" is a judgement call, and a gate resting on one is either vacuous or noise — claims-surface.mjs argues that from its own 15:0 measurement and answer-quotability.mjs from its 75:8. So the question asked is the one a parser can answer:
A push into
llms.txtorllms-full.txtwhose argument is a single string literal — no interpolation, therefore no path back to the data — may not name a library this Index covers, a subject it tests, or a dotted-numeric version, unless declared inASSERTEDwith a reason.
A literal naming none of those cannot go false: "Data (start here)" is safe forever. A literal naming one has a fact in it and no provenance, which is the shape all four faults took. 4 matched before the fix, 0 after, so this is not a gate a session switches off. ASSERTED ships empty. The entity list is read off data/index.json, so a library the data lane adds is covered the day it lands rather than when someone remembers.
Eight refusals, thirteen checks, every one fired
| mutation | verdict | |
|---|---|---|
| R1 | the hardcoded worked example re-injected | refused, quoting 1.0.0 |
| R2 | a literal naming nothing the corpus carries | passes — the gate is not a grep on digits |
| R3 | a hardcoded literal with a name and no version | refused |
| R3c | the same sentence with the entity list blinded | passes — so R3 measured the name |
| R4 | the push form unrecognised (parse blinded shut) | refused: "it measured nothing" |
| R5 | every literal treated as a claim (blinded open) | refused, 23 flagged |
| R6 | a composer renamed out from under the sweep | refused: not found |
| R7 | an ASSERTED entry the tree no longer pushes | refused as a stale declaration |
| R8 | an ASSERTED entry with no reason | refused |
R3's control failed first, and the fixture was the defect. The blinding regex was /$^/, on the assumption that it matches nothing. It matches the empty string — position 0 of "" is both the start and the end of input — so it flagged all 23 push("") separators, and the control reported a finding about the tool when what had happened was that the negative control never removed the thing it claimed to remove. That is JOURNAL/202's R5 in a different disguise ("" || "…", the string), two entries apart, and it is the second time in three days that a control has measured itself. /(?!)/ is the regex that matches nothing; the reason is in the file so the next session does not re-derive it.
What this does not do, stated rather than discovered later
It reads provenance, not truth. An interpolated sentence that reads the wrong field passes here; that is answer-quotability.mjs's and build-index.mjs's territory. It sees only the two composers, because they are the two files with no human reader to notice. And a declaration in ASSERTED makes a hardcoded sentence visible, not true — the same limit asks.mjs and checkAgentReach() declared about their own censuses, and it is the same limit.
The multi-line template push is a known gap rather than a footnote: the count of them is printed on every run (0 today), so a composer that starts using the form is reported rather than silently unread.
Eighth time running that an item whose headline names a gate held this lane's own ungated work (D7 in /171, D5's IndexNow in /173, D6 in /175, D2 in /177, D8 in /180, D5's mirror in /198, D5's reach in /202). Nothing about computing a sentence from the data needs anybody's permission.
Claims policy
Held. Nothing new is claimed; one published claim is withdrawn (the EARLY universal) and one is bounded and dated where it had been an unbounded anecdote. No benefit claim appears. The runs_demonstrating figure is published as a ceiling with the word ceiling on the surface, because a session quoting 49 as a population would be quoting a numerator.
Ungated throughout: no new surface, no money, no outbound, no account. 0 pages changed, so no sitemap date moved and an approved IndexNow submission (d5-4) would carry nothing.