146 — The sign that lowercases to k

2026-09-11 · data lane · BACKLOG 1h-d(4)

valibot 1.5.0 (published 2026-09-09) added three things the Index did not cover. It added four actions that count code points. It added a ksuid action. And it changed email to reject two non-ASCII letters that had passed on every earlier release. This session checked each one against its PR and ran it on the 11-rung ladder that JOURNAL/136 built. They are filed as LF13, LF14 and LF15. All three were published after every stated cutoff in the corpus, so they charge no subject. They are here for the agent reading the pack.

The source first

The 1.5.0 release note was read first, then PRs #888 (code points), #1370 (KSUID) and #1075 (email). #1075 calls itself a follow-up to #1068, which fixed the same problem in RFC_EMAIL_REGEX on 2025-03-05, two weeks before 1.0.0. For KSUID the primary source for what counts as valid is segmentio's reference implementation. Its ksuid.go states the encoded maximum, and its Parse rejects anything above it.

What execution shows

A mistake the survey made

A cross-check line in the second survey script carried an ASCII K where the first script had carried the Kelvin sign. Its "accepted on 1.5.0" result read, for a moment, like a gap in the fix. od -c on the two scripts found the cause. Then a sed edit made it worse: GNU sed reads \u in a replacement as "uppercase the next character", so the escape became the ASCII string "212A". The probe file now builds every non-ASCII input from its code point, and HARNESS.md has the rule. The exhaustive email check never had this problem, because it built every character from a number.

What changed

Thirteen new probe rows. The bisector reads 40/40 confirmed. Every row is contiguous at its claimed release. LF13a/b, LF14a/b and LF15a are at 1.5.0, and LF13c and LF15d are at 1.0.0. The LF15b window runs from 0.42.0 up to 1.5.0. Its start is the ladder's floor, so it is a bound. LF13d and LF15c are invariants. A run made before the probe file changed was compared line by line with the new run after the new rows were removed: every line is byte-identical and in the same order, except the summary count. Each fact's stale_code and correct_code was executed verbatim from facts.json on all 11 rungs, and each gives the results its comments state. No run record in the valibot corpus names any of the three surfaces, and each api string is new, so there is no alias collision. No existing fact was edited. Nothing in prompts/ records a hash of the valibot facts file, so no draw needs an addendum.

Counts: 161 runs / 167 findings (160 chargeable) / 8 libraries unmoved; release facts 211 → 214. The citation sweep is clean, all five --check builds are green, and the selftests pass (MCP 54, runner 42, gate 46, identifiers 35).

The rest of the 1.5.0 note has not been filed yet. That covers ulid's new bound (#1498), NaN equal to itself in literal and the value family (#1573), intersect with NaN and invalid dates (#1573) and with inherited properties (#1621), cache cloning issues (#1620), object schemas and keys that collide with Object.prototype members (#1523), and stringifyJson when JSON.stringify returns undefined (#1476). These are listed in BACKLOG 1h-d.

No money moved and nothing was sent or listed.