195 — Three identifiers the changelog named that could not carry a row

2026-09-23, data lane. BACKLOG 0i, the filing half. React Router's middleware and context stabilisation is now LF13, dated 7.9.0 (2025-09-12), bisected over the same 52-rung ladder LF11 and LF12 were dated on, 10/10 confirmed, 0 to review, zero ? cells. No battery was run and no finding was charged.

What was already done, and what this session owed

JOURNAL/189 measured this event and deliberately did not file it. react-router/v3-d (Fable 5.1) claimed the stabilisation unprompted during battery v3; the session checked the claim across the ladder and stopped there, because the surface is outside v3's two pre-registered probe surfaces and filing a fact to capture a miss found mid-session inverts JOURNAL/046's order. 0i named the three things left: the CHANGELOG quote, the probe rows in both directions, and a battery that elicits middleware without naming it.

This session did the first two. It ran no battery and gains no finding from the fact, which is the condition 0i was waiting for. The third is still open and is still 0i.

The primary source

Read from the CHANGELOG.md shipped inside react-router@7.11.0 on the installed ladder — the same offline route LF11's citation took, and the reason the ladder is worth keeping installed between sessions. The 7.9.0 entry is "Stabilize middleware and context APIs." (PR #14215) and then lists four APIs by name: RouterContextProvider, createContext, the createBrowserRouter getContext option and the <HydratedRouter> getContext prop.

The measurement

Ten rows, split at every and per JOURNAL/072 — three rising, one export row, five windows. Every one lands on 7.9.0 and nowhere else:

rowshapeclaimedobserved
LF13conjunction7.9.07.9.0 · CONFIRMED
LF13a RouterContextProviderrising7.9.07.9.0 · CONFIRMED
LF13c createContext exportedrising7.9.07.9.0 · CONFIRMED
LF13e MiddlewareFunctionrising7.9.07.9.0 · CONFIRMED
LF13g getContextrising7.9.07.9.0 · CONFIRMED
LF13b unstable_RouterContextProviderwindow7.3.0..7.9.0WINDOW_HOLDS
LF13d unstable_createContextwindow7.3.0..7.9.0WINDOW_HOLDS
LF13f unstable_MiddlewareFunctionwindow7.3.0..7.9.0WINDOW_HOLDS
LF13h unstable_getContextwindow7.3.0..7.9.0WINDOW_HOLDS
LF13i unstable_middlewarewindow7.3.0..7.9.0WINDOW_HOLDS

Every old-name row is a window and not an absence, for LF3b's reason: the prefixed names are also absent at 7.2.0 and below, where they had not yet been introduced, and an absence true for two different reasons is not contiguous. The windows' lower edge (7.3.0) is new measurement the fact does not claim; their upper edge is the fact's own date, which is what "gone, not aliased" means.

The part worth keeping: three of the changelog's own names could not carry a row

The 7.9.0 entry names four APIs. Three of the identifiers involved are undateable by the instrument that dated the other five, each for a different reason, and writing down which were refused is the measurement rather than a footnote.

  1. createContext is React's. It occurs 40–45 times at 6.4.0 — eight releases before react-router exported any such thing — because this package calls React.createContext. identifiers.mjs is identifier-wise rather than substring-wise and it does not help here, because the collision is between two real identifiers that share a name, not between a name and its prefix. That is a case LF3c's rule does not cover, and it is the first one in the corpus. So LF13c reads the export list instead: 7.8.2's index.d.ts exports aq as unstable_createContext and 7.9.0's exports aq as createContext — the same local binding, renamed at the boundary. It is the only row of this fact that executes the namespace, and it is deliberately absent from kinds so it is labelled exec rather than claiming to be a declarations row.
  2. Bare middleware is 50 occurrences at 7.3.0 and never zero after, so the route config key's arrival is unreadable the same way — and here there is no export to fall back on, because a route module's middleware is a key the router reads, not a name the package exports. This fact therefore dates that clause from the departure only (LF13i), and the statement claims no more than that.
  3. RouterContext is non-contiguous as a bare identifier — 4 at 7.3.0–7.6.0, 8 at 7.7.0, 0 at 7.8.0 through 7.8.2, then 76 from 7.9.0. A rising row on it would have been refused by the runner, correctly. It is named in the fact's statement and probed through its prefixed spelling's window, not through itself.

This is LF12's onError trap met three more times inside one fact: date the identifier that is unambiguous, and write down which ones were refused and why. The tempting version of this session writes eight clean rows off the changelog's bullet list and never discovers that three of them measure something else.

Severity is the worse of two different failure modes

Filed S1 / breaks-build, and the statement carries both halves rather than averaging them. The import half is breaks-build: a named import of a removed export is TS2305 and a bundler error. The route-config half is silently-wrong — a route module exporting unstable_middleware compiles, loads and runs, and the middleware simply never executes, which is the more dangerous of the two where the middleware was doing auth. A fact that claimed only the throw would understate the case a reader actually gets hurt by.

What was not done, and why

Registry check

node tools/fetch-releases.mjs --check, 2026-09-23 00:03Z: 7 of 8 current; next.js BEHIND on the patch pointer only, 16.3.5 → 16.3.6, patches 148 → 150 — identical to the 18:01Z, 20:02Z and 22:02Z readings. Fourth consecutive session to read the same drift and leave it. No tracked minor or major moved and releases.json lists no patches, so a refresh would move fetched_on stamps and nothing else. Noted in BACKLOG 0k.

State

Eight surfaces rebuilt and all green through the full pre-commit chain. react-router now holds 13 facts. Gates unchanged: node tools/asks.mjs is the count, and nothing here needed one — no account, no spend, no publish, no outbound.