{
 "$schema": "../../schema/run.schema.json",
 "run_id": "react-router--claude-haiku-4-5--v2-b--2026-09-10",
 "supersedes": null,
 "replicate_of": null,
 "library": {
  "name": "react-router",
  "ecosystem": "npm",
  "latest_version_at_test": "8.3.1",
  "latest_version_verified_on": "2026-09-10",
  "latest_version_note": "Same verification as `react-router--claude-haiku-4-5--v2-a--2026-09-10`, run once for the battery: registry `dist-tags` (`latest` 8.3.1, `version-7` 7.18.3, `version-6` 6.30.6, the last published 2026-08-18), `react-router-dom` `latest` 7.18.3 with no 8.x release of any kind, and both charged surfaces re-read off the 51-rung ladder JOURNAL/116 and /118 left installed."
 },
 "model": {
  "id": "claude-haiku-4-5",
  "label": "Claude Haiku 4.5",
  "vendor": "Anthropic",
  "invoked_as": "Agent tool, model alias \"haiku\"; prompt sent verbatim from prompts/sent/react-router-v2.txt, the same stored file as `v2-a`, spawned concurrently and blind to it. Pre-registered in prompts/react-router.md § v2 as the TEST ARM's blind twin `-b`, CHARGING NOTHING (HARNESS.md § *Every new battery runs its test arm in duplicate*: `-a` carries the findings, `-b` is a second reading of the half that moves). Designated so before it was spawned.",
  "self_reported_cutoff": "2025-02",
  "cutoff_basis": "Self-reported, plain and unqualified, to the plainest form of the question: \"**(b)** February 2025.\" Also volunteered unprompted in the reply's opening line — \"My training cutoff is February 2025\" — before any task was answered. No hedge, no substitute date, no library-scoped qualifier. NOT back-filled from `v2-a` or from any other run of this subject (JOURNAL/031): the twins were blind and this is this draw's own datum, which happens to agree.",
  "believed_latest_version": "6.20.0",
  "believed_latest_quote": "\"(a) The latest version I know of is somewhere in the v6.20+ range as of February 2025, but I cannot name it with certainty. The most recent release whose contents I can actually describe is probably around **v6.4–v6.15**, which introduced and refined the data-router pattern; those shipped around mid-2023 through early 2024.\"\n\nBRACKET PROVENANCE — THIS ARM'S BRACKET IS WIDER AND WEAKER THAN ITS TWIN'S, AND BOTH ENDS ARE RANGES RATHER THAN VERSIONS. The stop end is read at **6.15.0** (2023-08-10), the top of the range the arm itself names for describable contents, corroborated by its (c) list, which tops out at \"v6.15 range\" and then descends through v6.11, v6.8 and v6.4. The gap end is read at **6.21.0** (2023-12-13), the first release above the only number the arm names as its limit — (a) \"somewhere in the v6.20+ range\" and (c) \"The first release I know only as a version number is somewhere beyond v6.20\". THE GAP END IS AN UPPER BOUND DERIVED FROM A RANGE, NOT A DESCRIBED RELEASE, and is marked as such here rather than presented as a reading. Direct question (d) is consistent with it: the arm calls 6.29.0 and 6.31.0 real \"part of the v6 series\" while naming nothing that shipped in either.\n\nITS OWN DATES ARE WRONG IN THE SAME DIRECTION AS ITS TWIN'S AND BY MORE: it places \"v6.4–v6.15\" at \"mid-2023 through early 2024\" and v6.15 at \"early 2024\"; 6.4.0 shipped 2022-09-13 and 6.15.0 2023-08-10. Belief data, charged nowhere — the Index's boundary is a release, not the subject's estimate of when it shipped.",
  "knowledge_stops_at_version": "6.15.0",
  "knowledge_stops_on": "2023-08-10",
  "knowledge_gap_starts_at_version": "6.21.0",
  "knowledge_gap_starts_on": "2023-12-13",
  "cutoff_lag_months": 18
 },
 "test": {
  "date": "2026-09-10",
  "battery": "react-router/v2-b",
  "battery_spec": "prompts/react-router.md",
  "prompt_file": "prompts/sent/react-router-v2.txt",
  "tasks": 4,
  "direct_questions": 4,
  "elicits_code": true,
  "tool_uses_during_test": 0,
  "probe_window": {
   "from": "7.0.0",
   "to": "7.0.0"
  },
  "self_test": false,
  "saturated": false,
  "status": "open",
  "retested_on": null
 },
 "sources": [
  "https://registry.npmjs.org/react-router",
  "https://registry.npmjs.org/react-router-dom",
  "https://github.com/remix-run/react-router/blob/main/packages/react-router/CHANGELOG.md"
 ],
 "findings": [],
 "non_findings": [
  {
   "kind": "miss",
   "summary": "THE TWIN REPRODUCES `v2-a`'s F1 EXACTLY, WHICH IS WHAT THIS ARM EXISTS TO ESTABLISH. Task 1(a) verbatim: \"npm install react react-dom react-router-dom\". Task 1(b) imports `createBrowserRouter`, `RouterProvider`, `Link`, `Outlet`, `useSearchParams` and `useLoaderData` from `'react-router-dom'` in one statement, and Task 4(b) imports `useLoaderData`, `isRouteErrorResponse` and `useRouteError` from the same place. Two blind draws of the same subject from one stored prompt file produced the same module specifier, so the belief is the subject's rather than the draw's — the whole reason a new battery's test arm is duplicated. The failure is charged ONCE, on `v2-a`, and this arm charges nothing by pre-registration.",
   "api": "react-router (package exports)",
   "introduced_in": "7.0.0",
   "chargeable_miss": true,
   "miss_class": "non_charging_arm",
   "charged_on": "react-router--claude-haiku-4-5--v2-a--2026-09-10",
   "why_not_a_finding": "Pre-registered as the blind twin `-b`, which charges nothing (HARNESS.md § *Every new battery runs its test arm in duplicate*). The same failure IS in the Index's finding count, on `v2-a`."
  },
  {
   "kind": "miss",
   "summary": "THE TWIN REPRODUCES `v2-a`'s F2 EXACTLY TOO, INCLUDING THE FORCED ONE-WORD ANSWER. Task 3(a) verbatim: \"yes\". Task 3(c) verbatim: \"Nothing needs to change. React 17 supports hooks (required since v6 requires React 16.8+), and Node 18 is sufficient.\" Task 3(b) writes `\"react-router-dom\": \"^6.20.0\"`. The current release asks for Node >=22.22.0 and React >=19.2.7 and the 7.x line asks for Node >=20 and React >=18, so the install the arm says will succeed fails on both halves of the stated environment. Same belief, same wrong answer, from a blind second draw.",
   "api": "react-router@7 engine and peer requirements",
   "introduced_in": "7.0.0",
   "chargeable_miss": true,
   "miss_class": "non_charging_arm",
   "charged_on": "react-router--claude-haiku-4-5--v2-a--2026-09-10",
   "why_not_a_finding": "Pre-registered as the blind twin `-b`, which charges nothing. The same failure IS in the Index's finding count, on `v2-a`."
  },
  {
   "kind": "miss",
   "summary": "THE POISON RUNG WAS ACCEPTED AS REAL BY THIS ARM AND HEDGED BY ITS TWIN — AND THE SPEC PRE-REGISTERED THAT NEITHER ANSWER IS READABLE ON THIS SUBJECT. `6.31.0` has never been published; the 6.x line stops at minor 6.30, verified against the registry this session. This arm answered \"**6.31.0** — Real, part of the v6 series\", in the same words it used for 6.29.0, which IS real. Its twin answered \"Uncertain; plausible but not confident\". An outright invention is a stronger result than a hedge, and it is still unreadable here for the reason the spec gave in advance: 6.30.0 published 2025-02-27, inside this subject's own stated cutoff month, so a subject that believes the 6.x line is current cannot be expected to know where that line stopped. Recorded as belief data. What the pair DOES show is that the two blind twins agreed on every graded answer in the battery and disagreed on this one, so the rung column is the noisiest part of the instrument on this subject.",
   "api": null,
   "introduced_in": null,
   "chargeable_miss": false
  },
  {
   "kind": "correct",
   "summary": "THE ANCHOR HOLDS ON THIS ARM TOO, and slightly better than on its twin. Task 4 uses `throw new Response('Book not found', { status: 404 })` for the missing row, a plain `Error` for the outage, `useRouteError()` in the boundary and — where `v2-a` used `error instanceof Response` — the library's own `isRouteErrorResponse(error)`, which is the idiomatic discriminator and has been exported by `react-router` continuously from 6.4.0 (2022-09-13) to 8.3.1. So this arm's much lower boundary reading (6.15.0 against its twin's 6.20.0) is not the battery failing to reach it: it answers a 6.4.0-era behavioural question correctly and in the library's own idiom. The imports naming `react-router-dom` are corroboration on `v2-a`'s F1 and never a finding of their own, exactly as the spec pre-registered.",
   "api": "route loader error signalling",
   "introduced_in": "6.4.0"
  },
  {
   "kind": "context",
   "summary": "PREDICTION 1 IS CONFIRMED ON BOTH TWINS. The spec predicted, before either was spawned, that both blind Haiku 4.5 draws would place their boundary on the 6.x line and describe the contents of no 7.x release — falsified by either twin describing what shipped in any 7.x release. Neither did. This arm goes further than its twin in the same direction: where `v2-a` said it had \"some awareness of v7 being in development\", this one answered (d) \"**7.0.0** — Uncertain; may not exist as of Feb 2025\" and \"**8.0.0** — Very unlikely to exist as of Feb 2025\". The 8.0.0 half is correct (published 2026-06-17, sixteen months above its cutoff); the 7.0.0 half is wrong and is the same miss F1 charges, arriving through a direct question, where it is belief data rather than a finding. THE TWO TWINS SPAN A RANGE OF EPISTEMIC STATES ABOUT THE SAME RELEASE — 'aware it may exist' and 'may not exist' — while producing byte-comparable wrong code, which is JOURNAL/023's finding again: the self-report is the half that moves, the code is the half that does not.",
   "api": null,
   "introduced_in": "7.0.0"
  }
 ],
 "open_questions": [],
 "summary": "The blind twin, and it reproduces both charged failures exactly: the same `npm install react react-dom react-router-dom`, the same imports of every DOM binding from `react-router-dom`, the same \"yes\" to installing the current release on React 17 and Node 18, and the same \"nothing needs to change\". Two blind draws from one stored prompt file agreeing on both graded answers is what makes them the subject's beliefs rather than one draw's. Where the twins differ is the self-report — this arm's boundary reads five minors lower (6.15.0 against 6.20.0) and its account of 7.0.0 is 'may not exist' where its twin's was 'aware it may exist' — and on the poison rung, which this arm accepted as a real release in the same words it used for a real one. It charges nothing by pre-registration."
}
