{
  "$schema": "../../schema/run.schema.json",
  "run_id": "better-auth--claude-sonnet-5--v7-e--2026-09-06",
  "supersedes": null,
  "replicate_of": null,
  "library": {
    "name": "better-auth",
    "ecosystem": "npm",
    "latest_version_at_test": "1.7.3",
    "latest_version_verified_on": "2026-09-06",
    "latest_version_note": "Read from https://registry.npmjs.org/better-auth this session (`dist-tags.latest` -> 1.7.3). Every claim this battery charges was re-checked against the installed 1.7.3 package as well as against 1.6.0, so the corrections are about what is true now and not only about what changed at the target release."
  },
  "model": {
    "id": "claude-sonnet-5",
    "label": "Claude Sonnet 5",
    "vendor": "Anthropic",
    "invoked_as": "Agent tool, model alias \"sonnet\"; prompt sent verbatim from prompts/sent/better-auth-v7.txt, no tools available to the subject",
    "self_reported_cutoff": "2026-01",
    "cutoff_basis": "\"The harness reports my training cutoff as January 2026. I'll note that for a small, fast-moving package like better-auth, my confident/dense knowledge likely thins out well before that date.\" The date matches the value this subject has stated on 26 of its 27 prior runs, so the instability recorded in JOURNAL/031 and /045 did not recur here. Nothing in this battery turns on it: 2026-01 is before better-auth 1.6.0 (2026-04-06), so this arm is below the floor and was pre-registered as a control that never charges. The attribution of the date to \"the harness\" was volunteered, not asked for - the prompt asks only \"What is your training cutoff?\", verbatim from `prompts/sent/valibot-v4.txt` (BACKLOG 11j(a)).",
    "believed_latest_version": "cannot state one",
    "believed_latest_quote": "\"I can't state a specific 'latest version' with confidence... The most recent state of the library whose actual contents I can describe with any real confidence is roughly the early 1.x line... I'd place that very roughly in the 2024–early 2025 window, but I hold that loosely.\"",
    "knowledge_stops_at_version": "1.0.0",
    "knowledge_stops_on": "2024-11-23",
    "knowledge_gap_starts_at_version": "1.1.0",
    "knowledge_gap_starts_on": "2024-12-20",
    "cutoff_lag_months": 14
  },
  "test": {
    "date": "2026-09-06",
    "battery": "better-auth/v7-e",
    "battery_spec": "prompts/better-auth.md",
    "prompt_file": "prompts/sent/better-auth-v7.txt",
    "tasks": 7,
    "direct_questions": 3,
    "elicits_code": true,
    "tool_uses_during_test": 0,
    "probe_window": {
      "from": "1.6.0",
      "to": "1.7.3"
    },
    "self_test": true,
    "saturated": false,
    "status": "open",
    "retested_on": null
  },
  "sources": [
    "https://registry.npmjs.org/better-auth",
    "https://registry.npmjs.org/better-auth/-/better-auth-1.5.0.tgz",
    "https://registry.npmjs.org/better-auth/-/better-auth-1.6.0.tgz",
    "https://registry.npmjs.org/better-auth/-/better-auth-1.7.3.tgz",
    "https://github.com/better-auth/better-auth/releases/tag/v1.6.0"
  ],
  "findings": [],
  "non_findings": [
    {
      "kind": "correct",
      "summary": "Task 1, and the result that matters most in this arm: \"No\" - the **current**, post-1.6.0 answer, from a subject whose stated cutoff is 2026-01 and whose measured boundary on this library sits far below the release that changed it. It gave the reasoning too: \"the freshness check (`session.freshAge`, default `60 * 60 * 24`, i.e. 24 hours) is measured from when the session was created (`createdAt`), not from recent activity.\" Correct on the anchor, correct on the default, and correct on the outcome, for a behaviour introduced three months after its cutoff. Task 5(a) repeated it: `createdAt`. **This is a derivability result and it is what a below-floor control is for.** Per JOURNAL/031, a derivable outcome discounts a pass and does not excuse a failure - so `v7-a`'s pass on the same question cannot be read as recall, while `v7-c`'s and `v7-d`'s failures still charge. Two caveats keep it honest: task 1 is binary, so a control agreeing is also a coin landing; and this draw's own boundary answer places its describable knowledge at the early 1.x line, i.e. before the pre-1.6.0 `updatedAt` behaviour was well documented - it may never have held the belief it would have had to un-learn.",
      "api": "session.freshAge (measured from session.createdAt)",
      "introduced_in": "1.6.0"
    },
    {
      "kind": "miss",
      "summary": "Task 2: \"No\", with the absence claimed (\"I don't recall the `emailOTP` plugin shipping a built-in 'reuse the existing code on resend' option\") and a cache wired into `sendVerificationOTP` rather than `generateOTP` - a variant that sends the cached code but leaves the database row holding the newly generated one, so verification would reject the code the user was sent. The draw flagged the risk itself: \"I'm not confident enough in the plugin's internals to promise this exactly matches its OTP-storage semantics.\" Every one of the six draws missed this option.",
      "api": "emailOTP({ resendStrategy })",
      "introduced_in": "1.6.0",
      "chargeable_miss": false,
      "why_not_a_finding": "The subject's stated cutoff is 2026-01 and `resendStrategy` shipped 2026-04-06, so the option did not exist when this subject was trained. The fairness rule bars the charge and the arm was pre-registered as a below-floor control. Not counted as a chargeable miss for the same reason."
    },
    {
      "kind": "miss",
      "summary": "Task 6: \"No\" - \"My recollection is the `twoFactorClient` plugin takes a callback (`onTwoFactorRedirect`)... not a plain path string it navigates to on its own.\" Correct for its own era, and it did **not** reproduce the history inversion that three of the other draws produced: it made no claim that a string option had ever existed and been removed.",
      "api": "twoFactorClient({ twoFactorPage })",
      "introduced_in": "1.6.0",
      "chargeable_miss": false,
      "why_not_a_finding": "Below the floor: `twoFactorPage` shipped 2026-04-06 and this subject states 2026-01."
    },
    {
      "kind": "correct",
      "summary": "Task 3, the control: \"No\", and it named the current implementation as the reason - \"my recollection is the check is hardcoded against `createdAt`\". Task 5(b) `freshAge: 0`, correct. The control holds in this arm.",
      "api": "session.freshAge anchor option (does not exist)",
      "introduced_in": null
    },
    {
      "kind": "correct",
      "summary": "Task 4, the floor probe: `customSession` with a computed `isPro` field. The shortest correct answer of the six and it passed, so this arm is informative as a control.",
      "api": "customSession",
      "introduced_in": "1.0.0"
    },
    {
      "kind": "context",
      "summary": "Task 7: declined rather than denied - \"I don't have reliable, specific knowledge of a release number here\" - and correctly separated `cookieCache` (a cache over a store) from the `jwt` plugin, while noting it could not confirm either eliminates the session store. Stateless session management is 1.4.0, which is above this subject's describable boundary. Belief data, never scored.",
      "api": "stateless sessions",
      "introduced_in": "1.4.0"
    }
  ],
  "summary": "A below-floor control, pre-registered as one, and it did the job a control exists to do: it answered the battery's primary probe **correctly**, from three months below the release that made that answer correct. That discounts `v7-a`'s pass on the same question - a derivable outcome kills a pass, not a failure - and leaves the two Fable 5.1 failures charged. It missed both named 1.6.0 options, which is expected and barred from charging by the fairness rule, and it was the only draw of the six to deny `twoFactorPage` without also asserting it had once existed and been removed. Its boundary answer on this library is lower than this subject's previous readings: it could not name a describable release above the early 1.x line."
}
