What Claude Fable 5.1 gets wrong about valibot — battery v6-b, tested 2026-09-24

Run valibot--claude-fable-5-1--v6-b--2026-09-24

Summary

The blind twin, and it converged on the primary almost exactly: same one-word "accept", same three wrong cells in the table, same designated advice to keep email() and avoid rfcEmail, same boundary at 1.1.0, same wrong arrival release for rfcEmail. The duplicate rule exists because derivability and reasoning outcomes move between draws; here nothing moved, which makes the belief a stable property of the subject rather than an artefact of one sampling. Charged as F1.

SubjectClaude Fable 5.1 claude-fable-5-1, Anthropic
Invoked asAgent tool, model alias "fable", general-purpose subagent, instructed to use no tools; blind twin of v6-a, concurrent, same prompt file
Cutoff the model states2026-06
Newest valibot release it could place1.1.0 · 2025-05-06 (~15 month lag)
Oldest valibot release it could not place1.2.0 · 2025-11-24 (so this run brackets the subject’s boundary to 2025-05-06 – 2025-11-24)
In its own words"The latest version I can name is 1.1.0. I have a weak sense that a 1.2.0 exists (later in 2025), but I cannot describe its contents. The most recent release whose contents I can actually describe is 1.1.0, roughly May 2025."
How the bracket was readP6 HELD, and the twins agree to the version number: both 1.1.0, both naming 1.2.0 as the first release known only as a number, both dating 1.1.0 to roughly May 2025. A born-duplicated pair whose boundary readings coincide exactly. CORRECTED 2026-09-28 (JOURNAL/326): knowledge_stops_on read 2025-05-21; 1.1.0's registry date is 2025-05-06. knowledge_gap_starts_on was null although 1.2.0 is a tracked release; set to its registry date, 2025-11-24. With one end null this bracket never entered knowledge_boundary. (stop end stated, gap end stated)
Library at test timevalibot 1.5.0 (npm), verified 2026-09-22
Batteryvalibot/v6-b · 3 tasks, 4 direct questions · probe window 1.0.0 to 1.5.0
Tool uses during test0 (a run with any tool use is void — we measure training knowledge, not retrieval)
Tested2026-09-24
Findings1, of which 1 chargeable

Findings

F1 · The twin reaches the same false claim by the same route: rfcEmail carries the same iu case-folding quirk and is of no use against the collision — it rejects both code points on all nine releases that ship it

S2silently-wrong · rfcEmail · invariant · chargeable

An invariant finding: false on every release that ships the action, so no introducing release exists for a stated cutoff to sit below and the fairness arithmetic does not apply (HARNESS, JOURNAL/046). Executed on all nine rungs 1.0.0-1.5.0. charge-windows.mjs puts valibot 1.0.0 at o for this subject — inside charge. This is a blind twin and it charges on its own reading; the duplicate rule exists so that a reasoning outcome is not reported from one draw.

What the model believes

One-word answer to TASK 2(a): "accept". Table 2(b) marked the same three addresses accept that every shipping release rejects. The designated recommendation, 2(c) verbatim: "No, rfcEmail is no use against the TASK 1 collision. It changes which syntax is accepted (it is a looser, more RFC-faithful grammar ...), not which code points are accepted, and it carries the same iu case-folding quirk. If anything it widens the accepted set, which is the wrong direction for a value you are about to use as a unique key." And: "For the incident I would ship email() plus the explicit printable-ASCII check and toLowerCase() shown above." The stated mechanism: "valibot's lint config requires the u flag on every regex, and my recollection is that this one is also /.../iu."

What it wrote
import * as v from 'valibot'

// The twin's designated advice, identical in substance to v6-a's: keep email(),
// add a hand-written ASCII guard, do not switch to rfcEmail() because it
// "widens the accepted set".
const Email = v.pipe(v.string(), v.email())
v.safeParse(Email, '\u212Aelvin@example.com').success   // true on 0.42.0-1.4.2
What works on valibot 1.5.0
import * as v from 'valibot'

const Email = v.pipe(v.string(), v.rfcEmail())
v.safeParse(Email, '\u212Aelvin@example.com').success   // false on all nine 1.x rungs
v.safeParse(Email, '\u017Fmith@example.com').success    // false on all nine 1.x rungs
v.safeParse(Email, 'User.Name@Example.COM').success     // true on all nine 1.x rungs
Impact

Same as the primary's, and the fact that it is the same is the point: two blind draws of the same subject reached the identical false claim by the identical route, so the reader who asks twice is confirmed rather than corrected. A developer checking a suspicious answer by re-asking gets the same wrong recommendation with the same confident mechanism attached.

Scope note

The surface is rfcEmail, specifically whether it accepts U+017F LATIN SMALL LETTER LONG S and U+212A KELVIN SIGN. As v6-a: the charge is the designated conjunction — rfcEmail is looser on these inputs and therefore useless against the incident. The subject's untested claims about RFC 5322 grammar are reported, not graded. This arm's only material difference from its twin is the stated provenance of the u flag belief ("valibot's lint config requires the u flag on every regex" against the twin's "valibot's convention"), which changes nothing about the charge.

Verified against

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
missemail TASK 1(a): "No". Same reading as the twin, with EMAIL_REGEX reconstructed to the same shape and the spec machinery named more precisely still — "when both u and i are set, \w and [a-z] are matched after simple case folding, and CaseFolding.txt folds ſ to s and K to k". Correct through 1.4.2, false at 1.5.0. (1.5.0 published 2026-09-09, three months above this subject's stated cutoff of 2026-06. Pre-registered below-floor derivability cell.)
correctnormalizedEmail TASK 3, poison rung refused: "v.normalizedEmail does not exist in valibot on any release I know of." It also named the real normalize and its argument set, identified the borrowed name's actual origin ("The name is borrowed from validator.js (normalizeEmail)") and gave the same NFKC warning as its twin: "putting it in front of the key derivation institutionalises the collision instead of preventing it." Correct on every count.
missrfcEmail DIRECT QUESTION (d): "rfcEmail first shipped in 1.1.0 (~May 2025), as best I can state it. Moderate confidence on the version; I am confident it was after 1.0.0." It shipped in 1.0.0. Both twins are wrong by one minor and both explicitly exclude the true answer — the twin said "it was not in 1.0.0", this one "I am confident it was after 1.0.0". The confident half of each answer is the false half. (Excluded from this battery's charge by the pre-registration; belongs to BACKLOG 11k (the misdating rule, still unwritten).) [chargeable miss — produced only by a belief question the battery does not score as a finding; absent from the finding count]
contextemail TASK 1(b): printable-ASCII guard plus email() plus toLowerCase(), and again no reach for rfcEmail — P1 falsified on this arm too. One detail its twin did not produce: it deliberately omitted the u flag from its own guard regex and said why ("No u flag on purpose: astral code points become surrogate pairs and fail"), which is a correct piece of reasoning about the same flag whose behaviour it got wrong on rfcEmail.

Sources

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