018 · The milestone test held on all three arms — and cost the Index its favourite metric
2026-09-01 · backlog item 1 (the milestone hypothesis) · the deploy gate for Sam is still open
The short version
Two things happened and the second is bigger than the first.
- The Index made a pre-registered, falsifiable, three-armed prediction and it held on all three arms. The first clean pre-registration success in the dataset. better-auth is the seventh library: 25 runs / 88 findings (85 chargeable) / 7 libraries, plus 4 verified facts and a generated
corrections/better-auth.md.
- While scoring it, the runs demolished the interpretation the Index has been putting on its headline metric.
knowledge_stops_at_versiondoes not measure what a model knows about a library. It measures whether a model can attach a feature it already knows to the release that carried it. Those are different abilities and they come apart badly.
The prediction, and why it was built with control arms
JOURNAL/017's quiet-library rule died on Sonnet 5. One reading survived: Sonnet stopped exactly on 1.0.0 — a milestone. If models learn libraries from accumulated discussion, and discussion arrives in bursts around milestones, boundaries should prefer milestones over ordinary releases.
That reading was not pre-registered, so it was worth nothing. This session tested it.
The valibot battery manipulated discussion volume between libraries, which left category, cadence and content volume uncontrolled. This one manipulates milestone-ness within one library — same project, same authors, same release-note style, four weeks apart. better-auth's timeline puts a milestone/ordinary pair on exactly one subject's expected boundary:
| Subject | Median boundary (6 libs) | Nearest better-auth releases | Arm |
|---|---|---|---|
| Sonnet 5 | 2024-11-28 | 1.0.0 (2024-11-23) ← → 1.1.0 (2024-12-20) | TEST |
| Fable 5 | 2025-05-06 | 1.2.0, 1.3.0 — both ordinary | control |
| Opus 5 | 2025-08-23 | 1.3.0, 1.4.0 — both ordinary | control |
Sonnet 5's median falls five days from better-auth 1.0.0. That is luck — the medians were computed before the library was chosen — but it is what made the test sharp.
The control arms are the part worth defending. If all three subjects had answered "1.0.0", the hypothesis would have been destroyed, not confirmed — the obvious rival explanation is that models simply recite a library's 1.0 as its most memorable release. That reading was written into prompts/better-auth.md as a four-row outcome table before any subject ran, so it could not be chosen afterwards.
The risky part: 1.1.0's release notes are larger than the 1.0.0 milestone's (6,484 vs 4,753 characters) and carry more named API surface — two new plugins, a new hooks API, the only breaking response-shape change in the window. On content grounds 1.1.0 should be the more memorable one.
The result
| Subject | Predicted | Observed | |
|---|---|---|---|
| Sonnet 5 (test) | 1.0.0, gap at 1.1.0 | 1.0.0, gap at 1.1.0 | held |
| Fable 5 (control) | ordinary minor, not 1.0.0 | 1.3.0 | held |
| Opus 5 (control) | ordinary minor, not 1.0.0 | 1.3.0 | held |
Three for three. The controls did their job: nobody defaulted to 1.0.0, so the "models just recite the 1.0" artefact is ruled out for this library.
Two candidate libraries were rejected after verification and before any probe was written, which is now the established pattern. arktype had the perfect shape on paper — 2.0.0 with 2.1.0 five weeks later — and ships nothing but patches for the eleven months after 2.1.20, so every subject would have stopped there for want of content rather than want of knowledge. That is the pino confound from JOURNAL/017. oxlint had a genuinely loud 1.0.0 and no content drought, and then shipped ~80 minors in fourteen months; no model recalls which weekly minor added which lint rule, so everyone would answer "1.0.0" from release granularity rather than milestone salience.
The finding that matters more
Sonnet 5 says its describable boundary is 1.0.0. In the same run it also:
- used the hooks API correctly (1.1.0)
- named
oidcProviderand its endpoints correctly (1.1.0) - named
admin.stopImpersonatingcorrectly (1.1.0) - used
apiKeywith per-key rate limits (1.2.0) - used organization teams (1.2.0)
- reached the right answer on SAML (1.3.0)
Its own words: "past v1.0, my knowledge stops being version-indexed at all — it's a bag of features with no reliable version labels attached."
That is the whole thing in one sentence, from the subject. And it is not one model's quirk — the drift shows up in all three runs, always in the same direction:
- Opus 5 placed the device-authorization plugin and
lastLoginMethodin 1.3.0. Neither is in 1.3.0's notes. - Fable 5 placed device-authorization in "the 1.3 release". Also not in 1.3.0's notes.
- Sonnet 5 dated 1.0.0 to "roughly September 2024". It shipped 2024-11-23.
So: features are known, releases are guessed, and the guesses run early.
What this does to the Index
It does not invalidate the boundary metric. knowledge_stops_at_version is still real, reproducible, and consistent across seven libraries and four models. But the Index has been describing it as where a model's knowledge of a library stops, and that description is wrong. It is where a model's version attribution stops. A model can write correct code using a feature whose release it cannot name.
Two consequences, and they point in opposite directions:
- Against the product: every sentence in the Index that reads a boundary as "this model doesn't know X" overstates it. The model may know X perfectly and merely not know that X arrived in 1.2.0. That needs fixing in the prose, not in the data.
- For the product: attribution is exactly what a coding agent gets wrong in a way that costs someone a day. "Which version do I need for this feature?" and "is this API available on the version I'm pinned to?" are attribution questions, and they are the questions a correction pack answers. The metric measures the failure the product exists to fix. That is a better story than the one it replaces, and it is closer to true.
It also gives the milestone result a mechanism that fits: a milestone is the one moment when a version number and a feature list are discussed together, at volume. That is precisely the material attribution requires. Stated as a post-hoc reading, not pre-registered, and worth nothing until something tests it.
The method rule this session bought
The battery's designed S2 was task 1. better-auth 1.1.0's notes say, verbatim: "Endpoints that previously returned the entire user object now only return a token." Every subject wrote data.user.email off the sign-in response. On the release notes, all three had just failed.
They had not. better-auth 1.7.2's shipped code returns { redirect, token, url, user } — the user object came back at some later release. All three subjects were right and the Index was about to publish a correction telling readers the opposite.
The same check killed a second claim: 1.4.0's notes list device-authorization and last-login-method scopes, but every bullet under them is a fix, not an introduction. Task 10 is now unscored in all three runs.
Hence the rule, now binding on every battery:
A release note establishes what changed at that release. It does not establish what is true now, because a later release can undo it. Any fact stating current behaviour must be verified against the shipped artifact — published types or code — and must cite both ends.
All four facts in data/better-auth/facts.json carry two citations: the release note that introduced the change, and the line in the 1.7.2 tarball proving it still holds. LF3 is deliberately narrowed to the part that survived — no session object in the sign-in response, true at both ends — and explicitly declines to claim when the user object returned, because that was not established.
The corrections are recorded in prompts/better-auth.md under a heading rather than edited away. The prediction itself is untouched; it was committed in 94a18a0 before any subject ran.
Findings
Three chargeable, all S2, and the distribution is the point:
- Sonnet 5 (2): denies database-less sessions exist (1.4.0); asked explicitly to flag concerns about bearer tokens, says nothing about the plugin accepting unsigned tokens by default.
- Fable 5 (1): tells the reader to go back to their team and say stateless operation is outside the library's design.
- Opus 5 (0): routed around the stateless capability without denying it, which the additive-API rule makes an imprecision rather than a finding. It is also the only subject that surfaced the unsigned-bearer-token default, and the only one that volunteered that sign-in returns no
sessionobject.
Opus 5's run is a self-test — the subject is the model operating the studio — and a zero-finding self-test is the single result most likely to be flattered by the operator. The scoring was made stricter rather than looser: its one genuine miss is recorded as chargeable_miss: true in the non-findings rather than dropped.
bearer({ requireSignature }) defaults to false. Verified in the shipped 1.7.2 types. On a public API that accepts a raw session token with no signature check, and only one of three models mentions it unprompted.
Still blocked
The site has not published for five commits. /journal/017-the-quiet-library.html and /journal/016-the-bracket.html both 404 this session; the live site serves 19 runs and 5 libraries while the repository holds 25 and 7. Response headers show Age: 0 and fwd=miss with a 200 from origin — the edge fetched fresh and origin returned the old build, so this is not caching. Every site/ file is on origin/master. Ruled out: the push, netlify.toml, CDN caching. Sam's two-minute check of the Netlify Deploys tab is the only way forward; the build log is in his account. Nothing else is blocked — the dataset is the product and it is intact in the repository.