# valibot correction pack · for projects on valibot@^1.2
<!--
     Stale Priors Index · Unattended Works · https://github.com/SamAndrzejewski

     GENERATED FILE — DO NOT EDIT BY HAND. Your edit will be destroyed by the next build.
     Rebuild:  node tools/build-corrections.mjs
     Sources:  data/valibot/facts.json  (the corrections, each verified against a primary source)
               data/valibot/*.json      (the evidence: reproduced model failures)

     Latest valibot: 1.4.2 · verified 2026-09-02
     Coverage: Claude Fable 5, Claude Fable 5.1, Claude Haiku 4.5, Claude Opus 5, Claude Sonnet 5 — valibot/v1 (2026-09-01), valibot/v1r-a (2026-09-01), valibot/v1r-b (2026-09-01), valibot/v2-a (2026-09-02), valibot/v2-b (2026-09-02), valibot/v2-c (2026-09-02), valibot/v2-d (2026-09-02), valibot/v2-e (2026-09-02), valibot/v2-f (2026-09-02), valibot/v2-g (2026-09-02), valibot/v3-a (2026-09-05), valibot/v3-b (2026-09-05), valibot/v3-c (2026-09-05), valibot/v3-d (2026-09-05), valibot/v3-e (2026-09-05), valibot/v4-a (2026-09-06), valibot/v4-b (2026-09-06), valibot/v4-c (2026-09-06)

     Paste into CLAUDE.md / AGENTS.md / .cursorrules if your project uses valibot@^1.2.
     Do NOT use if you are pinned to valibot@0.x, whose API differs substantially from the v1 line.
-->

## What we actually measured

5 Claude models were asked for idiomatic valibot code with no tools, purely from training knowledge. 13 reproduced failures across 20 runs, each verified against the release that broke the belief.

| Model | Stated cutoff | valibot version attribution stops | Lag inside the window |
|---|---|---|---|
| Claude Fable 5.1 | 2026-06 | 1.1.0 · 2025-05-06 | ~13 months |
| Claude Opus 5 | 2026-05 | 1.1.0 · 2025-05-06 | ~12 months |
| Claude Sonnet 5 | 2026-01 | 1.0.0 · 2025-03-19 | ~10 months |
| Claude Fable 5 | 2026-01 | 1.1.0 · 2025-05-06 | ~8 months |

A recent cutoff is not a defence. Every model here loses track of this library's release history well before the date it states as its own cutoff, and the stopping points cluster far tighter than the cutoffs do.

Read that column precisely. It is the newest valibot release whose contents the model can correctly **attribute to that release** — not the newest valibot feature it knows. Past that point a model will often write working code with a newer API while naming the wrong release for it, and that guess runs *early* — it names a release older than the one that shipped the feature. So the question this pack answers is not "does the model know this API" but "can it be trusted about which version the API arrived in" — which is the question that matters when you are pinned to a version.

## How to read an entry

Every entry ends with a *Reproduced against* line. Where it names models, we have the generated code that got it wrong, dated, with the model's own words in the run write-up. Where it says no model yet, the correction is verified from the release notes but nothing has been probed for it — it is a fix, not a measurement, and the pack says so rather than blurring the two.

The section an entry sits in is the worst case if you act on the stale belief. The severity in brackets after a model's name is what that particular model's output actually did, which can be milder — a model can hold the wrong belief and still, on the day, write code that runs.

## The corrections

### Breaks the build, or throws at runtime

Act on the stale belief here and the code does not run. Fix these first.

#### `NanoIDAction / NanoIDIssue`

**Renamed in valibot 1.1.0** (2025-05-06)

The `NanoIDAction` and `NanoIDIssue` interfaces were renamed to `NanoIdAction` and `NanoIdIssue` in 1.1.0. The old casing is not exported and a type import of it fails to compile.

*The stale belief:* That the nano-ID action's types spell the acronym in full caps, as they did up to 1.0.0.

```ts
// Stale
import type { NanoIDAction } from 'valibot'

function describe(action: NanoIDAction<string, undefined>) {
  return action.type
}

// Current
import type { NanoIdAction } from 'valibot'

function describe(action: NanoIdAction<string, undefined>) {
  return action.type
}
```

> A type-level break only: the runtime `nanoid()` action itself was not renamed. It surfaces at compile time, not at runtime.

*Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.*

Source: [valibot v1.1.0 release notes](https://github.com/open-circle/valibot/releases/tag/v1.1.0) · 2025-05-06

### Runs, but is silently wrong

Nothing errors. The behaviour is simply not what a model trained earlier will tell you.

#### `toNumber / toBoolean / toDate / toBigint / toString`

**Added in valibot 1.2.0** (2025-11-24)

valibot ships dedicated string-to-primitive transformation actions since 1.2.0: `toBigint`, `toBoolean`, `toDate`, `toNumber` and `toString`. Use `toNumber` instead of a bare `transform(Number)`: `toNumber` adds a validation issue when the conversion yields `NaN`, whereas `pipe(string(), transform(Number))` returns `NaN` with `success: true` and hands silently-wrong data downstream. **`toBoolean` is the exception and is not a string parser** — it applies JavaScript `Boolean()`, so the string `"false"` converts to `true`. For the common case of a `"true"`/`"false"` query parameter use `parseBoolean` (1.3.0) or validate the literals with `picklist` before transforming.

*The stale belief:* That valibot has no built-in string-to-primitive conversion at all and every such conversion must go through a hand-written `transform(Number)` or `transform((s) => s === "true")`.

**The code below needs valibot 1.3.0 or later.** Between 1.2.0 and 1.3.0 this correction does not apply — see the note.

```ts
// Stale
import * as v from 'valibot'

const Query = v.object({
  // Number("abc") is NaN, and this pipe returns it with success: true
  page: v.pipe(v.string(), v.transform(Number)),
})

// Current
import * as v from 'valibot'

const Query = v.object({
  // toNumber raises a validation issue instead of yielding NaN
  page: v.pipe(v.string(), v.toNumber()),

  // NOT v.toBoolean() — that is Boolean(), and Boolean("false") is true.
  // parseBoolean (1.3.0) reads the literal words:
  active: v.pipe(v.string(), v.parseBoolean()),

  // on valibot < 1.3.0, validate the literals first:
  // active: v.pipe(v.picklist(["true", "false"]), v.transform((s) => s === "true")),
})
```

> CORRECTED 2026-09-02 (JOURNAL/035), against the shipped package. This entry previously told readers to write `v.pipe(v.string(), v.toBoolean())` for a `"true"`/`"false"` query parameter, and justified the whole fact on the claim that the built-in avoids the `Boolean("false") === true` trap that `transform(Boolean)` falls into. **That justification was false and the recommended code was a bug.** valibot 1.4.2's `toBoolean` is `dataset.value = Boolean(dataset.value)` — literally the same call — so it maps `"false"`, `"0"`, `"no"` and every other non-empty string to `true`. Executed and confirmed: `parse(pipe(string(), toBoolean()), "false")` returns `true`. The word-reading action is `parseBoolean`, which arrived in 1.3.0 (see LF11) and returns `false` for `"false"`. The fact survives on the `toNumber` half, where the built-in genuinely is safer than the hand-roll, and that is now the stated mechanism. The error was caught by the battery `valibot/v2` pre-registration, which required every scored claim to be re-executed against the installed package — and by six test draws that denied these actions exist while independently warning that `Boolean("false")` is `true`. They were right about that and the Index was wrong. ARCHAEOLOGY, 2026-09-02: a subject asserted, inside a run, that valibot USED to have a `coerce` action and that it was deliberately removed. That history is correct. The v0.31.0 migration guide states that `coerce` was removed and why, and maps it onto `pipe` + `unknown` + `transform`. So the belief that produced the wrong answer was not a false memory of the removal but the assumption that nothing replaced it: the generic `coerce` is gone, and the dedicated actions above arrived in 1.2.0, six releases later.

*Reproduced against: **Claude Fable 5** (S2), **Claude Opus 5** (S2), **Claude Sonnet 5** (S2) — valibot/v2-a, 2026-09-02; valibot/v2-c, 2026-09-02; valibot/v2-e, 2026-09-02.*

Source: [valibot v1.2.0 release notes](https://github.com/open-circle/valibot/releases/tag/v1.2.0) · 2025-11-24 · [valibot 1.4.2, shipped package — the toBoolean implementation](https://registry.npmjs.org/valibot/-/valibot-1.4.2.tgz) · 2026-06-28 · [valibot — Migrate to v0.31.0, Coerce method](https://valibot.dev/guides/migrate-to-v0.31.0/)

#### `emoji`

**Behaviour changed in valibot 1.2.0** (2025-11-24)

The regular expression behind the `emoji` validation action carried a ReDoS vulnerability that was fixed in 1.2.0. If you validate user-supplied text with the `emoji` action, require valibot >= 1.2.0. Advice that recommends the action without that version floor exposes the caller to a denial-of-service on attacker-controlled input.

*The stale belief:* That the `emoji` action is safe to run on untrusted, high-volume input at any 1.x version.

```ts
// package.json
// "valibot": "^1.2.0"   <- 1.2.0 fixed the ReDoS in EMOJI_REGEX

import * as v from 'valibot'

const Reaction = v.pipe(v.string(), v.emoji())
```

> Verified only to the extent the vendor's own release notes state it: the notes list the fix. This entry claims the fix landed in 1.2.0 and that earlier 1.x is affected; it does not characterise the exploit, which was not published in the release notes.

*Reproduced against: **Claude Fable 5** (S2) — valibot/v1, 2026-09-01.*

Source: [valibot v1.2.0 release notes](https://github.com/open-circle/valibot/releases/tag/v1.2.0) · 2025-11-24

### Deprecated, or a better API now exists

Works today. It is the older idiom, and some of it is scheduled for removal.

#### `guard / parseBoolean / isrc / domain / jwsCompact / cache`

**Added in valibot 1.3.0** (2026-03-17)

valibot 1.3.0 added the `guard` transformation action (narrow types with a type predicate), `parseBoolean`, the `isrc`, `domain` and `jwsCompact` validation actions, and a `cache` method that caches schema output by input. It also fixed `creditCard` to accept 13-digit Visa numbers.

*The stale belief:* That domain-name, ISRC and JWS-compact validation, and schema-level output caching, have no built-in support in valibot.

```ts
import * as v from 'valibot'

const Host = v.pipe(v.string(), v.domain())
const Token = v.pipe(v.string(), v.jwsCompact())
```

> PROBED 2026-09-05 by battery valibot/v3 (JOURNAL/055) on the guard and cache halves: all five arms denied both capabilities. Charged twice against Claude Opus 5 on v3-c (F1 guard S3, F2 cache S3). 1.3.0 is admissible against Claude Opus 5 (stated 2026-05) and against Claude Fable 5.1 (stated 2026-06), and below the floor for Claude Sonnet 5 and Claude Fable 5. Both Fable 5.1 arms failed it and neither could be charged: see JOURNAL/055 on the direct-question wording that barred them. The isrc, domain and jwsCompact surfaces were deliberately NOT probed - each is named for the standard it validates, so the probe would measure naming rather than knowledge. CROSS-REFERENCE 2026-09-02 (JOURNAL/035): `parseBoolean` is the action that reads the literal words `"true"`/`"false"` (and `1`/`0`, `yes`/`no`, `on`/`off`, `enabled`/`disabled`, case-insensitively, rejecting anything else). It is **not** interchangeable with 1.2.0's `toBoolean`, which is plain `Boolean()` and maps `"false"` to `true` — see the correction on LF1. A project on valibot < 1.3.0 that needs to read a boolean query parameter has no built-in for it and must validate the literals with `picklist` first. Executed against valibot 1.4.2: `parse(pipe(string(), parseBoolean()), "false")` returns `false`; the empty string is rejected with an issue rather than coerced.

*Reproduced against: **Claude Fable 5.1** (S3), **Claude Opus 5** (S3) — valibot/v3-c, 2026-09-05; valibot/v4-a, 2026-09-06.*

Source: [valibot v1.3.0 release notes](https://github.com/open-circle/valibot/releases/tag/v1.3.0) · 2026-03-17 · [valibot v1.3.0 release notes — creditCard fix](https://github.com/open-circle/valibot/releases/tag/v1.3.0) · 2026-03-17 · [valibot 1.4.2, shipped package — parseBoolean truthy/falsy word lists](https://registry.npmjs.org/valibot/-/valibot-1.4.2.tgz) · 2026-06-28

#### `toCamelCase / toKebabCase / toPascalCase / toSnakeCase`

**Added in valibot 1.4.0** (2026-05-05)

valibot 1.4.0 added case-conversion transformation actions (`toCamelCase`, `toKebabCase`, `toPascalCase`, `toSnakeCase`) and the `isoDateTimeSecond` validation action. It also made `intersect` stop mutating its input, so frozen objects and arrays can be merged.

*The stale belief:* That valibot has no built-in naming-convention conversions, and that `intersect` cannot be used with frozen inputs.

```ts
import * as v from 'valibot'

const Slug = v.pipe(v.string(), v.toKebabCase())
```

> PROBED 2026-09-05 by battery valibot/v3 (JOURNAL/055) on the case-conversion half, in both directions. All five arms denied the capability in the offer direction, and all five rejected a pull request using toKebabCase in the recognition direction - calling a real action an invention. NOTHING CHARGED: 1.4.0 published 2026-05-05, the same month as Claude Opus 5s stated cutoff, so the Index parks it against that subject; Claude Fable 5.1 (stated 2026-06) is the one subject it is admissible against, and both of its arms declined their stated cutoff. Five reproduced failures, zero charged, every one flagged chargeable_miss. Verified this session by installing 1.0.0, 1.1.0, 1.2.0, 1.3.0, 1.4.0 and 1.4.2 and diffing their exports: toUpperCase and toLowerCase are present at 1.0.0, so a draw that says valibot has upper/lower and nothing for camel/kebab/snake states the precise pre-1.4.0 truth. toTitleCase, used as this batterys poison rung, has never shipped in any release and is absent from all six export tables.

*Reproduced against: **Claude Fable 5.1** (S2) — valibot/v4-a, 2026-09-06.*

Source: [valibot v1.4.0 release notes](https://github.com/open-circle/valibot/releases/tag/v1.4.0) · 2026-05-05 · [valibot v1.4.0 release notes — intersect](https://github.com/open-circle/valibot/releases/tag/v1.4.0) · 2026-05-05

#### `isbn`

**Added in valibot 1.3.0** (2026-03-17)

valibot ships an `isbn` validation action covering ISBN-10 and ISBN-13, and it is usable from **1.3.0**, not from 1.2.0. The v1.2.0 release notes announce it — the implementation was merged the day before that release — but 1.2.0's `library/src/actions/index.ts` never re-exports it, so the published 1.2.0 package contains no trace of `isbn` in its runtime, its types or its bundle. The export line appears at 1.3.0, and 1.3.0's own release notes do not mention `isbn` at all. On valibot 1.2.x the hand-written check digit is still the only option.

*The stale belief:* That valibot has no ISBN validator at any version and the check digit must be implemented by hand in a custom `check`. (Correct for every release up to and including 1.2.x; wrong from 1.3.0.)

```ts
// Stale
import * as v from 'valibot'

const Book = v.object({
  id: v.pipe(v.string(), v.check((s) => /^(?:\d{9}[\dX]|\d{13})$/.test(s), 'Invalid ISBN')),
})

// Current
import * as v from 'valibot'

const Book = v.object({
  id: v.pipe(v.string(), v.isbn()),
})
```

> CORRECTED 2026-09-02 (JOURNAL/040), by the Node auditor. This entry was filed at **1.2.0 / 2025-11-24** on the strength of the v1.2.0 release note quoted below, and the audit at 1.2.0 failed with TS2339: `Property 'isbn' does not exist`. The shipped 1.2.0 package has **zero occurrences of the string `isbn`** in `index.mjs`, `index.cjs`, `index.d.mts`, `index.d.cts` or either minified bundle. Cause, from the tagged source: PR #1097 (`feat: ISBN validation`) merged 2025-11-23, one day before the tag, and `library/src/actions/isbn/isbn.ts` is present at tag `v1.2.0` — but `library/src/actions/index.ts` at that tag goes straight from `ipv6` to `isoDate`, so the module was never wired into the public entry point and was dropped from the bundle. The barrel line `export * from './isbn/index.ts';` first appears at tag `v1.3.0`. **Neither release's notes are true about which release made this usable**: 1.2.0 announces an action its own package does not contain, and 1.3.0 ships it without a word. This is the second instance in the Index of a release note that is wrong about its own release (JOURNAL/027 is the first) and the first that was caught by the auditor rather than by hand. **One published finding was withdrawn as a result**: `valibot--claude-fable-5--v1--2026-09-01` F2 charged Fable 5 (stated cutoff 2026-01) for denying that `isbn` exists — an answer that was true of every valibot release that existed at that cutoff. It is now recorded as a correct answer in that run's non-findings. The Opus 5 charge (stated cutoff 2026-05) survives the date move and is re-cited here.

*Reproduced against: **Claude Opus 5** (S3) — valibot/v1, 2026-09-01.*

Source: [valibot v1.2.0 release notes — the announcement the package does not honour](https://github.com/open-circle/valibot/releases/tag/v1.2.0) · 2025-11-24 · [valibot source at tag v1.2.0 — the action barrel, with no isbn line between ipv6 and isoDate](https://raw.githubusercontent.com/open-circle/valibot/v1.2.0/library/src/actions/index.ts) · 2025-11-24 · [valibot 1.2.0, shipped package — the export list in dist/index.d.mts skips isbn](https://registry.npmjs.org/valibot/-/valibot-1.2.0.tgz) · 2025-11-24 · [valibot source at tag v1.3.0 — the barrel line that first publishes the action](https://raw.githubusercontent.com/open-circle/valibot/v1.3.0/library/src/actions/index.ts) · 2026-03-17 · [valibot 1.3.0, shipped package — the same export list, now carrying isbn](https://registry.npmjs.org/valibot/-/valibot-1.3.0.tgz) · 2026-03-17

#### `examples / getExamples`

**Added in valibot 1.2.0** (2025-11-24)

valibot has first-class example values since 1.2.0: the `examples` action attaches them to a schema and the `getExamples` method reads them back. Do not overload `description` or a custom metadata action to carry examples.

*The stale belief:* That valibot's metadata surface is limited to title/description and examples must be stored outside the schema.

```ts
// Stale
import * as v from 'valibot'

const Email = v.pipe(
  v.string(),
  v.email(),
  v.description('An email address, e.g. a@b.com')
)

// Current
import * as v from 'valibot'

const Email = v.pipe(
  v.string(),
  v.email(),
  v.examples(['a@b.com', 'c@d.org'])
)

const examples = v.getExamples(Email)
```

*Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.*

Source: [valibot v1.2.0 release notes](https://github.com/open-circle/valibot/releases/tag/v1.2.0) · 2025-11-24 · [valibot v1.2.0 release notes — getExamples](https://github.com/open-circle/valibot/releases/tag/v1.2.0) · 2025-11-24

#### `message`

**Added in valibot 1.1.0** (2025-05-06)

valibot ships a `message` method since 1.1.0 that overrides the error message configuration for one schema locally, without touching global config.

*The stale belief:* That per-schema message overrides must be passed argument-by-argument to each action, or set globally with `setGlobalMessage`.

```ts
// Stale
import * as v from 'valibot'

v.setGlobalMessage('Invalid input')  // global — affects everything

// Current
import * as v from 'valibot'

const Port = v.message(
  v.pipe(v.number(), v.minValue(1), v.maxValue(65535)),
  'Port must be between 1 and 65535'
)
```

*Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.*

Source: [valibot v1.1.0 release notes](https://github.com/open-circle/valibot/releases/tag/v1.1.0) · 2025-05-06

#### `parseJson / stringifyJson`

**Added in valibot 1.1.0** (2025-05-06)

valibot ships `parseJson` and `stringifyJson` transformation actions since 1.1.0. Parsing JSON inside the pipeline makes a malformed string surface as a valibot issue like any other, instead of as a thrown `SyntaxError` you have to catch separately.

*The stale belief:* That JSON must be parsed outside the schema, with its own try/catch, before validation can begin.

```ts
// Stale
import * as v from 'valibot'

let data
try {
  data = JSON.parse(raw)
} catch {
  throw new Error('malformed JSON')
}
const config = v.parse(Config, data)

// Current
import * as v from 'valibot'

const Config = v.pipe(
  v.string(),
  v.parseJson(),
  v.object({ port: v.number() })
)

const result = v.safeParse(Config, raw)
// a malformed string and a schema violation are both issues now
```

*Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.*

Source: [valibot v1.1.0 release notes](https://github.com/open-circle/valibot/releases/tag/v1.1.0) · 2025-05-06

#### `summarize`

**Added in valibot 1.1.0** (2025-05-06)

valibot ships a `summarize` method since 1.1.0 that turns an issue list into a pretty-printable multi-line string. Use it instead of looping over issues to build a human-readable error report.

*The stale belief:* That rendering issues for a human requires a hand-written loop over `result.issues` or a `flatten` call.

```ts
// Stale
import * as v from 'valibot'

const result = v.safeParse(Schema, input)
if (!result.success) {
  console.error(result.issues.map((i) => `- ${i.message}`).join('\n'))
}

// Current
import * as v from 'valibot'

const result = v.safeParse(Schema, input)
if (!result.success) {
  console.error(v.summarize(result.issues))
}
```

*Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.*

Source: [valibot v1.1.0 release notes](https://github.com/open-circle/valibot/releases/tag/v1.1.0) · 2025-05-06

#### `exactOptional`

**Added in valibot 1.0.0** (2025-03-19)

valibot has `exactOptional` and `exactOptionalAsync` since 1.0.0, for a key that may be absent entirely but must not be present and set to `undefined`. `optional` allows both.

*The stale belief:* That valibot cannot express the difference between a missing key and a key explicitly set to undefined.

```ts
// Stale
import * as v from 'valibot'

// allows { name: undefined } as well as {}
const User = v.object({ name: v.optional(v.string()) })

// Current
import * as v from 'valibot'

// allows {} but rejects { name: undefined }
const User = v.object({ name: v.exactOptional(v.string()) })
```

*Reproduced against: no model yet. Verified from the primary source only — this is a correction, not an Index entry.*

Source: [valibot v1.0.0 release notes](https://github.com/open-circle/valibot/releases/tag/v1.0.0) · 2025-03-19

### Wrong facts about the library

Not code — versions, minimums and metadata that models state confidently and get wrong.

#### `github.com/fabian-hiller/valibot`

**Renamed in valibot 1.2.0** (2025-11-24)

valibot's repository is `github.com/open-circle/valibot`. It moved out of the `fabian-hiller` personal namespace into the `open-circle` organisation, and the npm `repository` field flipped with the 1.2.0 release. The old URL still 301-redirects, so a link to it works — but attributing the project to a personal account is wrong about who maintains it.

*The stale belief:* That valibot is a personal project living at `github.com/fabian-hiller/valibot`.

```text
# Stale
https://github.com/fabian-hiller/valibot

# Current
https://github.com/open-circle/valibot
```

> Dated from primary metadata rather than an announcement: the npm `repository` field reads `fabian-hiller/valibot` for 1.0.0 and 1.1.0 and `open-circle/valibot` from 1.2.0 onward. The docs site remains valibot.dev.

*Reproduced against: **Claude Fable 5** (S4), **Claude Opus 5** (S4), **Claude Sonnet 5** (S4) — valibot/v1, 2026-09-01.*

Source: [npm registry metadata for valibot — repository field per version](https://registry.npmjs.org/valibot) · 2025-11-24

## Not corrections — recorded for honesty

Claims seen in a run but not yet verified against a primary source. Never treated as findings:

- Direct question (b) in this battery asked the subject which cutoff it would trust — the context value or its own sense — and both Claude Fable 5.1 arms repudiated the context value, which barred every charge on this half of the battery. `valibot/v2`, which asked the plain "What is your training cutoff?", got affirmation plus a density caveat from all six arms and charged three findings. Is the repudiation a property of this subject or of the question? *(open since 2026-09-05)*
- The subject asserts valibot's `EMOJI_REGEX` was rewritten to `\p{RGI_Emoji}` with the ES2024 regex `v` flag, and that on older runtimes this is a load-time syntax error rather than a graceful failure. Not verified against a primary source in this run. If true it is a second, independent fact about the same action and belongs in the facts file. *(open since 2026-09-01)*
- Both valibot draws landed one release below `valibot/v1` while agreeing exactly with each other. The difference between the runs is how a hedged recall is scored: v1 said it could describe 1.1.0 "with moderate confidence" and was scored at 1.1.0; these draws called 1.1.0 a version number with no content and were scored at 1.0.0. The battery still has no rule for a subject that offers a confident boundary and a hedged one in the same answer - the same gap `prisma/v1r-a` logged. Two libraries have now hit it. *(open since 2026-09-01)*
- This draw asserted that valibot removed a `coerce` action in the 0.31 redesign and has shipped no coercion since, calling it "a deliberate design position, not a gap". The first half is a claim about pre-1.0 history the Index has never verified; the second half is false as of 1.2.0. Worth pinning from the 0.31.0 release notes at the next valibot touch, because a confidently-stated false history is a different failure mode from a missing recent release and the Index has no category for it. *(open since 2026-09-01)*
- Whether the `emoji` action's regex was rewritten to use `\p{RGI_Emoji}` with the ES2024 regex `v` flag, as the Fable 5 run asserts, and if so in which release. Relevant because it would mean the action carries a runtime floor (Node 20+) in addition to the 1.2.0 ReDoS fix. *(open since 2026-09-01)*

---

*Findings, code and citations: `data/valibot/` — one JSON file and one write-up per model, each finding carrying the release that broke the belief, its publication date and a verbatim quote from the primary source. Corrections: `data/valibot/facts.json`. This file is generated by `tools/build-corrections.mjs`; if the prose and the data ever disagree, that is a bug in the generator, not a stale pack.*
