What Claude Opus 5 misses about react-router, uncharged — battery v4-d, tested 2026-09-23

Run react-router--claude-opus-5--v4-d--2026-09-23

Summary

The boundary-demonstration arm, and it came out the way battery prediction 3 said it would. Handed two tasks that name neither middleware nor context, this subject produced the stabilised API unprompted — and opened with a rename table it was not asked for, mapping all five unstable_ spellings to their 7.9.0 forms, with both ends of the window right. It charges nothing and never could: 7.9.0 is this subject's own measured boundary, which charge-windows.mjs scores known. What the arm buys instead is provenance. v3-c stated this boundary the day before and hedged its own 7.9.0 entry as "Low confidence"; this draw demonstrated the same boundary at both ends — 7.9.0 stop, 7.10.0 gap — through a different instrument, one that never mentions the mechanism v3 asked about directly. So the known cell was genuinely known, which is the first test of that direction of JOURNAL/066's corollary and the one open question this record carries. One true claim it made that this Index does not carry: the stabilised API at 7.9.0 sits behind future.v8_middleware. Verified this session against the shipped packages (0 occurrences at 7.8.2, 62 at 7.9.0, 0 at 8.4.0, gating the runtime shape of context and not the export names, so LF13 is confirmed rather than corrected). Deliberately not filed — it is outside this battery's pre-registered surfaces, and a session does not file a fact it would gain from.

SubjectClaude Opus 5 claude-opus-5, Anthropic
Invoked asAgent tool, model alias "opus"; prompt sent verbatim from prompts/sent/react-router-v4.txt (sha256 b0eb07c3997498158330d42686cb1d84b6afd01afecf98df26cc4ff55a9c05c0). Pre-registered in prompts/react-router.md § v4 as arm `-d`, the boundary-demonstration arm, run single. 7.9.0 is `known` for this subject (`charge-windows.mjs` prints `o`), so this arm CHARGES NOTHING by construction and was designated so before it was spawned.
Cutoff the model states2026-05
Newest react-router release it could place7.9.0 · 2025-09-12 (~8 month lag)
Oldest react-router release it could not place7.10.0 · 2025-12-02 (so this run brackets the subject’s boundary to 2025-09-12 – 2025-12-02)
In its own words"Most recent release whose contents I can actually describe: 7.9.0, approximately September 2025 — the middleware stabilization release. Everything after that is progressively vaguer, and past roughly late 2025 I'd be guessing. That gap — cutoff May 2026, confident description only to ~Sept 2025 — is real and I want to be explicit about it rather than paper over it. Knowledge thins out well before the cutoff date."
How the bracket was readBOTH ENDS STATED, AND BOTH REPRODUCE react-router/v3-c EXACTLY. Stop end 7.9.0 (published 2025-09-12), dated by the arm as "approximately September 2025" — right to the month. Gap end stated in direct question (c): "First release I know only as a version number: 7.10.0. I'm fairly confident it exists... but I cannot describe a single thing that shipped in it. Everything from 7.10 onward is a blank to me." 7.10.0 published 2025-12-02. v3-c gave 7.9.0 / 7.10.0 the day before, from a DIFFERENT instrument — v3's prompt named the unstable_ stabilisation mechanism outright in its direct question (e); v4's does not mention middleware, context or any unstable_ spelling anywhere in its tasks. Two batteries, two instruments, one day apart, identical boundary at both ends. AND THIS ONE IS DEMONSTRATED WHERE v3-c's WAS ONLY STATED, which is what this arm was drawn for. v3-c labelled its own 7.9.0 entry "Low confidence. I associate it with continued RSC work and middleware moving toward stable naming, but I can't pin a specific headline feature." This draw pinned it: it opened with an unprompted rename table mapping all five unstable_ spellings to their stabilised forms, attributed the change to 7.9.0, and then wrote the stabilised API correctly through both tasks. The schema records provenance as stated for both ends, because the arm did state both and the vocabulary has only stated and derived — there is no demonstrated value, so the demonstration is recorded here in prose and not as a field. The recorded boundary does not move at all; what this draw adds is the evidence behind it. (stop end stated, gap end stated)
Library at test timereact-router 8.4.0 (npm), verified 2026-09-23
Batteryreact-router/v4-d · 2 tasks, 4 direct questions · probe window 7.9.0 to 7.9.0
Tool uses during test0 (a run with any tool use is void — we measure training knowledge, not retrieval)
Tested2026-09-23
Findings0, of which 0 chargeable

Findings

None. Every task in this battery produced code that works on the current release, and every direct question was answered correctly. A run with nothing to charge is kept in the Index at full weight: it is the control that makes the other runs mean something, and it is the evidence for what this model does not need correcting on. What the subject actually said is recorded below.

What it got right, and near misses

Recorded so the run cannot be read as a hit list. A model that is right for an obsolete reason is recorded here, not as a finding.

KindAPINote
correctmiddleware / createContext / RouterContextProvider / getContext LF13 CORRECT, DEMONSTRATED, AND UNPROMPTED — AND THIS ARM COULD NOT HAVE CHARGED EITHER WAY. Neither task names middleware, context or any unstable_ spelling. The arm opened its reply with a rename table it was not asked for, mapping every affected symbol across the boundary: unstable_createContext → createContext, unstable_RouterContextProvider → RouterContextProvider, unstable_middleware → middleware, Route.unstable_MiddlewareFunction → Route.MiddlewareFunction, unstable_getContext → getContext, attributing the change to "RR 7.9+" against an "unstable_ era (RR 7.3 → 7.8)". Both endpoints are right: the prefixed spellings occur at 7.3.0 through 7.8.2 and nowhere at 7.9.0 and above. It then wrote the stabilised names throughout both tasks — createContext, RouterContextProvider, the middleware route export, getContext on createBrowserRouter and as a <HydratedRouter> prop — and added the migration note in the correct direction: "If you're on anything below 7.9, prefix every symbol below with unstable_." IT ALSO FLAGGED ITS OWN UNCERTAINTY ON THE RIGHT AXIS AND WAS RIGHT ANYWAY: "I am confident about the feature and its shape; I am moderately (not fully) confident that 7.9.0 is the exact minor where the rename landed." The minor is 7.9.0. NOTHING IS CHARGED AND NOTHING WOULD HAVE BEEN. 7.9.0 is this subject's own measured boundary, so charge-windows.mjs scores the cell known — admissible but non-charging — and the arm was designated non-charging before it was spawned. Had it written unstable_ spellings, that would have been recorded here with chargeable_miss: false and the same reasoning; a fairness rule is not relaxed mid-session to catch a miss (JOURNAL/031).
correctfuture.v8_middleware A TRUE CLAIM THIS INDEX DOES NOT YET CARRY, VERIFIED THIS SESSION AND DELIBERATELY NOT FILED. The arm gated the stabilised API behind a future flag — future: { v8_middleware: true } in react-router.config.ts and in createBrowserRouter options — and flagged the flag's spelling as one of the two things it was least sure of. It is right, and LF13 says nothing about it. Measured against the shipped packages this session, identifier-wise: v8_middleware occurs 0 times at 7.8.2, 62 times at 7.9.0, and 0 times at 8.4.0. Reading the 7.9.0 declarations, the flag gates the runtime SHAPE of context — "When future.v8_middleware is not enabled, this is undefined... When future.v8_middleware is enabled, this is an instance of" RouterContextProvider — and it disappears at 8.x, where the v8 behaviour is the default. THIS CONFIRMS LF13 RATHER THAN CORRECTING IT, which was checked rather than assumed. LF13 claims the EXPORTS were renamed unconditionally at 7.9.0, and they were: 7.9.0's index.d.ts carries createContext, RouterContextProvider and MiddlewareFunction and none of the unstable_ spellings, with no flag involved. The flag governs what context is at runtime, not what the package exports. Both statements are true and they are about different things. NOT FILED AS A FACT THIS SESSION, ON PURPOSE. It is outside v4's pre-registered probe surfaces — the grading function grades identifier spellings against LF13 and nothing else — and filing a fact off an observation made mid-battery is JOURNAL/046's order inverted, which is the same rule BACKLOG 0i obeyed when it declined to file LF13 from v3-d. Carried to BACKLOG as a candidate for a session that gains no finding from it.
correctroute module unrecognised export TASK 2(c) CORRECT, AND THE MOST COMPLETE OF THE FOUR ANSWERS. "NO", then the mechanism and three named consequences: the Vite plugin's server-export stripping "only knows a fixed list", so an unrecognised export survives into the client bundle; if it references server-only code its imports are no longer tree-shaken, so .server modules or Node built-ins get pulled into the client graph — "you get a confusing bundling error pointing at a module you never intended to ship, or worse, a secret in the client bundle"; and a route module exporting non-component values alongside its default component can invalidate Fast Refresh. It named the failure mode in the same words this Index uses: "silent-until-weird". All four arms of this battery answered NO, including the below-floor control, which makes the cell derivable and is why battery prediction 5 failed.
correctversion ladder (poison rung 7.19.0) POISON RUNG DECLINED, WITH THE RIGHT REASONING. Direct question (d) on 7.19.0: "I do not believe this was published, at least not as of anything I know. Extrapolating the 7.x cadence (roughly one minor a month, 7.9 in Sept 2025), 7.19 would land somewhere around mid-to-late 2026 — at or past my cutoff. I have no knowledge of it. Treat as: probably not real yet, possibly real and simply beyond me." Named and not described; the ladder stands (JOURNAL/052). This is the arm that interpolated the cadence rather than pattern-matching the number, which is what a poison rung inside a dense cadence is for (JOURNAL/061).
missversion ladder (8.4.0) DENIES 8.4.0 AS FABRICATED, AND 8.4.0 IS REAL — BARRED BY THE FAIRNESS RULE, AND THE REASONING IS THE INTERESTING PART. "8.4.0 — I do not believe this was ever published. I have no knowledge of a React Router v8.0.0 shipping, let alone a 8.4.0. The v8_middleware future-flag name strongly implies v8 was on the roadmap, and it's plausible v8.0 shipped sometime in 2026 — but 8.4.0 specifically would be several minors into a major I can't confirm exists. I'd call this fabricated unless you show me otherwise." 8.0.0 published 2026-06-17 and 8.4.0 published 2026-09-15, both above this arm's stated 2026-05 cutoff, so the fairness rule bars the charge on both. WHAT MAKES IT WORTH RECORDING: the arm derived the existence of a planned v8 from a flag name it recalled correctly, reasoned to "plausible v8.0 shipped sometime in 2026", and then declined the specific number. That is a correct inference from a correctly recalled artefact, stopping at exactly the edge of what it could support — one release month before the major it inferred actually shipped. A denial is not an invention (JOURNAL/044), and this one is better calibrated than the two Sonnet 5 arms' denials of the same number.

Open questions from this run

Sources

Battery specification: prompts/react-router.md in the studio repo. Every finding above also carries its own citation.