fix(CommandPalette): weigh the grapheme-snap ceiling against the value - #388
Merged
Conversation
IgorShevchik
force-pushed
the
fix/grapheme-ceiling-anchored-to-value
branch
from
August 13, 2026 12:26
7d53463 to
16cea6d
Compare
`GRAPHEME_SNAP_MAX_LENGTH` is documented, and was tested, as a bound on the
field text. It was not measured against it: `truncateHTMLFromStart` built its
snapper from `content` — the value after escaping and after `<mark>` insertion —
so the ceiling was reached early, by an amount nothing in the constant hints at.
Escaping has no fixed overhead: `&` expands to five characters, `"` to six.
'a'.repeat(8140) + FLAG.repeat(10) + 'match' // value.length 8185
'&'.repeat(1600) + FLAG.repeat(50) + 'match' // value.length 1805
Both degraded, and both rendered `🇸🇺` with an orphaned regional indicator where
the author wrote `🇺🇸` — a different country, silently. That is the defect #364
describes and #371 exists to prevent, reappearing above a threshold no reader
could predict.
`createClusterSnapper` now takes the length to weigh separately from the string
to segment, named `fieldTextLength` for what it is. The parameter is required
rather than defaulted: a default is what would let the next derived-string
caller inherit this bug without noticing.
Segmenting a string the ceiling would have excluded is affordable, but not
because the call is cheap in isolation — on a long run of regional indicators it
is not. It is that `Array.from(html)` already paid the larger price on the same
string, unconditionally, on both sides of this fix. End to end the difference is
tens of microseconds either way, within noise. `test/bench/search.bench.ts`
gains a case that reaches the ceiling by escaping rather than by length, so the
claim has a durable measurement behind it rather than a throwaway script.
The two ceiling tests moved off `value.length + MARKUP` onto `value.length`,
which makes `snaps clusters exactly at the ceiling` the plain-text repro — a
value of exactly the advertised length previously degraded. The new case covers
the unbounded half: every fixture in `degraded paths` was free of escapable
characters, so the expansion never reached the ceiling arithmetic.
`.sync/PORTING.md`'s guard entry said the threshold "is crossed 13 characters
earlier than a reading of `value.length` suggests". That described the defect,
not the design, and is corrected here rather than left for the documentation
follow-up — a porter reading it could otherwise restore the bug on purpose.
Closes #387.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LWWrBHgfqGSbeU3V6UuMF8
IgorShevchik
force-pushed
the
fix/grapheme-ceiling-anchored-to-value
branch
from
August 13, 2026 12:39
16cea6d to
8f851dd
Compare
This was referenced Aug 13, 2026
IgorShevchik
pushed a commit
that referenced
this pull request
Aug 13, 2026
…hecked
All three were mine, and all three were checkable — which is how they were
caught.
**"218 tests" was 220.** The figure came from an early planning note and was
carried into the commit message and the PR body without being re-measured
against the final `origin/main` content. Counted: 110 per project, two projects.
**"Every other multi-code-point fixture here already uses escapes" was false.**
The Devanagari pair is written as literal glyphs, and the ZWJ family's joiners
are literal U+200D bytes sitting between escaped emoji — only the flag and the
skin-tone modifier were fully escaped.
Rather than restate the claim more narrowly, the ZWJ joiners are now escaped
too, for a reason the original comment did not name: they are invisible in an
editor, so one could be deleted without anyone seeing. That is a different
hazard from NFC collapse and it applies to that fixture specifically. The
Devanagari pair keeps its glyphs — it is visible, and `normalize('NFC')`
round-trips it unchanged, so neither hazard applies. The comment now says which
reason applies where instead of claiming a consistency that was not there.
The escaped joiners are byte-identical to the literals they replace.
**"752 tests green" had no stated scope**, and none of the obvious readings
reproduce it — not the repository, not `test/utils/` plus `test/components/`,
not the two files this branch changes. It counted `test/utils/` plus
`CommandPalette.spec.ts`, which is a scope nobody could infer. The PR body now
names the command. The same convention was used on #388's "732" and was equally
unverifiable there.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LWWrBHgfqGSbeU3V6UuMF8
8 tasks
IgorShevchik
pushed a commit
that referenced
this pull request
Aug 15, 2026
…nput
`sanitizeSnippet` preserved real `<mark>` tags by swapping them for
`\0markO\0`/`\0markC\0`, escaping everything, then swapping back. NUL is an
ordinary character a snippet can carry, so what decided whether markup was
emitted was a string the input could supply.
A whole sentinel forged a tag outright:
sanitizeSnippet('before \0markO\0 after')
// → 'before <mark> after' — one <mark> out, none in
sanitizeSnippet('\0markC\0\0markO\0')
// → '</mark><mark>' — a close ahead of its opener
Worse, and easier: **six** of the seven bytes, immediately before a *real* tag,
were enough. The placeholder this function inserted for that tag completed the
prefix, and the restore step then found a sentinel spanning the two:
sanitizeSnippet('a\0markO<mark>hit</mark>b')
// → 'a<mark>markO\0hit</mark>b'
The genuine highlight moved, and with text on both sides it landed on text it
was never meant to mark. No crafted sequence — one stray fragment ahead of any
highlight. The first description of this defect, in #391 and in this branch's
first revision, said the input had to carry the sentinel itself. That understated
both the trigger and the consequence; an independent fuzzing pass found the
prefix case.
The function's own doc says the preserved tag is hardcoded *"on purpose: taking
it as a parameter would let a caller pass any tag through to the `v-html` that
renders the result."* The intent was right; the mechanism did not hold it.
Not XSS, and the bound is worth stating because it is what keeps this a content
bug: `escapeHTML` ran before the swap back, so content inside a forged region
stayed escaped, and the emitted tag came from a fixed literal rather than from a
capture group — no attribute could land inside it. Forgeable surface: the two
strings, nothing else. The consequence is spoofed emphasis, relocated highlights
and unbalanced markup reaching `v-html`, in snippets that come from whatever
backend the host application passes to `<ContentSearch>`
(`useContentSearch.ts:141,144`).
Splitting on the real tags removes the guess, and with it the collision. Both
implementations were run over ~2.1M generated inputs by an independent pass:
every divergence traces to this family, and the new one never emitted a tag
other than the two literals nor leaked an unescaped character. The regex has no
quantifiers, and growth is linear to 61MB.
Five tests added, each mutation-checked: dropping the regex capture, dropping the
closing-tag half of the condition, and escaping the tags themselves are all
caught; restoring the old implementation fails exactly the four forgery cases.
One pins the *bound* rather than the bug — a forged tag could never carry an
attribute — so a future rewrite cannot widen that silently.
Pre-existing since `557a5178`, the original port, and untouched by #365, #371
and #388. The function came from upstream unchanged, so `nuxt/ui` very likely
carries it too.
Closes #391.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LWWrBHgfqGSbeU3V6UuMF8
IgorShevchik
pushed a commit
that referenced
this pull request
Aug 15, 2026
…nput
`sanitizeSnippet` preserved real `<mark>` tags by swapping them for
`\0markO\0`/`\0markC\0`, escaping everything, then swapping back. NUL is an
ordinary character a snippet can carry, so what decided whether markup was
emitted was a string the input could supply.
A whole sentinel forged a tag outright:
sanitizeSnippet('before \0markO\0 after')
// → 'before <mark> after' — one <mark> out, none in
sanitizeSnippet('\0markC\0\0markO\0')
// → '</mark><mark>' — a close ahead of its opener
Worse, and easier: **six** of the seven bytes, immediately before a *real* tag,
were enough. The placeholder this function inserted for that tag completed the
prefix, and the restore step then found a sentinel spanning the two:
sanitizeSnippet('a\0markO<mark>hit</mark>b')
// → 'a<mark>markO\0hit</mark>b'
The genuine highlight moved, and with text on both sides it landed on text it
was never meant to mark. No crafted sequence — one stray fragment ahead of any
highlight. The first description of this defect, in #391 and in this branch's
first revision, said the input had to carry the sentinel itself. That understated
both the trigger and the consequence; an independent fuzzing pass found the
prefix case.
The function's own doc says the preserved tag is hardcoded *"on purpose: taking
it as a parameter would let a caller pass any tag through to the `v-html` that
renders the result."* The intent was right; the mechanism did not hold it.
Not XSS, and the bound is worth stating because it is what keeps this a content
bug: `escapeHTML` ran before the swap back, so content inside a forged region
stayed escaped, and the emitted tag came from a fixed literal rather than from a
capture group — no attribute could land inside it. Forgeable surface: the two
strings, nothing else. The consequence is spoofed emphasis, relocated highlights
and unbalanced markup reaching `v-html`, in snippets that come from whatever
backend the host application passes to `<ContentSearch>`
(`useContentSearch.ts:141,144`).
Splitting on the real tags removes the guess, and with it the collision. Both
implementations were run over ~2.1M generated inputs by an independent pass:
every divergence traces to this family, and the new one never emitted a tag
other than the two literals nor leaked an unescaped character. The regex has no
quantifiers, and growth is linear to 61MB.
Five tests added, each mutation-checked: dropping the regex capture, dropping the
closing-tag half of the condition, and escaping the tags themselves are all
caught; restoring the old implementation fails exactly the four forgery cases.
One pins the *bound* rather than the bug — a forged tag could never carry an
attribute — so a future rewrite cannot widen that silently.
Pre-existing since `557a5178`, the original port, and untouched by #365, #371
and #388. The function came from upstream unchanged, so `nuxt/ui` very likely
carries it too.
Closes #391.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LWWrBHgfqGSbeU3V6UuMF8
IgorShevchik
added a commit
that referenced
this pull request
Aug 15, 2026
…nput (#405) `sanitizeSnippet` preserved real `<mark>` tags by swapping them for `\0markO\0`/`\0markC\0`, escaping, then swapping back. NUL is an ordinary character a snippet can carry, so what decided whether markup was emitted was a string the input could supply. A whole sentinel forged a tag outright. Worse and easier: six of its seven bytes immediately before a real tag were enough, because the placeholder inserted for that tag completed the prefix — so `a\0markO<mark>hit</mark>b` came back as `a<mark>markO\0hit</mark>b`, the genuine highlight landing on text it was never meant to mark. No crafted sequence, one stray fragment ahead of any highlight. Not XSS: escaping ran before the swap back, so content inside a forged region stayed escaped, and the emitted tag came from a fixed literal rather than a capture group — no attribute could land inside it. Forgeable surface was the two strings and nothing else. The consequence is spoofed emphasis, relocated highlights and unbalanced markup reaching `v-html`, in snippets that come from whatever backend the host application passes to `<ContentSearch>`. Splitting on the real tags removes the guess, and with it the collision. Independently fuzzed at ~2.1M inputs against both the old implementation and a reference scanner using neither `split` nor `replaceAll`: no bypass, no unescaped character, no tag other than the two literals. The regex has no quantifiers; growth is linear to 61MB and costs 2.15µs against the old 2.09µs at realistic snippet size. Five tests added, each mutation-checked by running it: dropping the regex capture, dropping either half of the condition, escaping the tags themselves and returning the input untouched are all caught, and restoring the old implementation fails exactly the forgery cases. Pre-existing since `557a5178`, the original port; untouched by #365, #371 and #388. Closes #391. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LWWrBHgfqGSbeU3V6UuMF8
8 tasks
IgorShevchik
pushed a commit
that referenced
this pull request
Aug 15, 2026
…erage Each was falsifiable, which is how each was caught. The pattern is the finding: a prose claim about test coverage cannot fail when it stops being true. **"Every constant and every branch above was verified by removing it and watching a named test fail."** #390 found six surviving mutations, three of them constants this bullet covers. Restated as intent, with the procedure spelled out rather than implied — delete, run `pnpm test`, confirm a named test goes red, revert — and with the other three survivors named, since a paragraph rebuilding trust in coverage should not leave half its own evidence unaccounted for. **"The unpaired-surrogate strings are the only input that can catch a surrogate range constant being widened."** True only where the probe sits one code point outside the bound it pins. Two of the four sat `0x100` away and caught nothing. **"A pickaxe returns exactly one commit."** It counts occurrences of the string, not authorship, so `54b93e33`'s jsDoc line joined the list and any future comment naming the parameter will too. Restating the number would only defer the problem; the claim now attributes rather than counts, in all three places it appeared. Two smaller corrections: the `8 of 66` figure appears nowhere in the repository and cannot be re-derived, and `createClusterSnapper` gained a second parameter in #388. Adds one §2 invariant — **`sanitizeSnippet` splits on the tag**. Upstream's placeholder round-trip is what this file was ported from, and it lets a snippet forge `<mark>` out of its own input: six of the sentinel's seven bytes ahead of a real tag suffice, because the placeholder inserted for that tag completes the prefix, moving a genuine highlight onto text it was never meant to mark (#391, fixed in #405). Carries the sibling rule from the function's jsDoc too — the tag is hardcoded so a caller cannot pass any tag through to `v-html` — since a port that generalises the signature breaks the other half of the same guarantee. Two things found while writing it, both worth more than the corrections: `getGraphemeSegmenter()`'s module-level memo is a second cache, distinct from the per-value `segments` view, and was documented nowhere. Collapsing either into per-call construction costs a search box every keystroke and fails no test — the module-level one has no coverage at all. Now named. The four sub-bullets restated numbers that also live in the code comments, and one such figure has already rotted in one of its two homes. They now point at the code rather than copying it, which is why this correction pass removes 17 lines as well as adding. No `src/` change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LWWrBHgfqGSbeU3V6UuMF8
IgorShevchik
pushed a commit
that referenced
this pull request
Aug 15, 2026
…erage Each was falsifiable, which is how each was caught. The pattern is the finding: a prose claim about test coverage cannot fail when it stops being true. **"Every constant and every branch above was verified by removing it and watching a named test fail."** #390 found six surviving mutations, three of them constants this bullet covers. Restated as intent, with the procedure spelled out rather than implied — delete, run `pnpm test`, confirm a named test goes red, revert — and with the other three survivors named, since a paragraph rebuilding trust in coverage should not leave half its own evidence unaccounted for. **"The unpaired-surrogate strings are the only input that can catch a surrogate range constant being widened."** True only where the probe sits one code point outside the bound it pins. Two of the four sat `0x100` away and caught nothing. **"A pickaxe returns exactly one commit."** It counts occurrences of the string, not authorship, so `54b93e33`'s jsDoc line joined the list and any future comment naming the parameter will too. Restating the number would only defer the problem; the claim now attributes rather than counts, in all three places it appeared. Two smaller corrections: the `8 of 66` figure appears nowhere in the repository and cannot be re-derived, and `createClusterSnapper` gained a second parameter in #388. Adds one §2 invariant — **`sanitizeSnippet` splits on the tag**. Upstream's placeholder round-trip is what this file was ported from, and it lets a snippet forge `<mark>` out of its own input: six of the sentinel's seven bytes ahead of a real tag suffice, because the placeholder inserted for that tag completes the prefix, moving a genuine highlight onto text it was never meant to mark (#391, fixed in #405). Carries the sibling rule from the function's jsDoc too — the tag is hardcoded so a caller cannot pass any tag through to `v-html` — since a port that generalises the signature breaks the other half of the same guarantee. Two things found while writing it, both worth more than the corrections: `getGraphemeSegmenter()`'s module-level memo is a second cache, distinct from the per-value `segments` view, and was documented nowhere. Collapsing either into per-call construction costs a search box every keystroke and fails no test — the module-level one has no coverage at all. Now named. The four sub-bullets restated numbers that also live in the code comments, and one such figure has already rotted in one of its two homes. They now point at the code rather than copying it, which is why this correction pass removes 17 lines as well as adding. No `src/` change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LWWrBHgfqGSbeU3V6UuMF8
IgorShevchik
pushed a commit
that referenced
this pull request
Aug 15, 2026
Each was falsifiable, which is how each was caught. The pattern is the finding: a prose claim about test coverage cannot fail when it stops being true. **"Every constant and every branch above was verified by removing it and watching a named test fail."** #390 found six surviving mutations, three of them constants this bullet covers. Restated as intent, with the procedure spelled out rather than implied — delete, run `pnpm test`, confirm a named test goes red, revert — and with the other three survivors named, since a paragraph rebuilding trust in coverage should not leave half its own evidence unaccounted for. **"The unpaired-surrogate strings are the only input that can catch a surrogate range constant being widened."** True only where the probe sits one code point outside the bound it pins. Two of the four sat `0x100` away and caught nothing. **"A pickaxe returns exactly one commit."** It counts occurrences of the string, not authorship, so `54b93e33`'s jsDoc line joined the list and any future comment naming the parameter will too. Restating the number would only defer the problem; the claim now attributes rather than counts, in all three places it appeared. **"Only 16 of ~3200 commits carry an `Upstream:` trailer."** 52 do. Checked two ways — `git log --grep` and a pass over every commit body — and against the tree as it stood when the sentence was written, where it was already 52 of 3179. It was never right, and it is load-bearing: it is the stated reason the trailer convention cannot support an inference about provenance. That conclusion still holds at 52 of 3200; the number does not. Corrected in all three places. Two smaller ones: the `8 of 66` figure appears nowhere in the repository and cannot be re-derived, and `createClusterSnapper` gained a second parameter in #388. The guard list omitted `describe('truncation from the start')`, which pins the surrogate safety of `truncateHTMLFromStart` — a function this same bullet names. Adds one §2 invariant — **`sanitizeSnippet` splits on the tag**. Upstream's placeholder round-trip is what this file was ported from, and it lets a snippet forge `<mark>` out of its own input: six of the sentinel's seven bytes ahead of a real tag suffice, because the placeholder inserted for that tag completes the prefix, moving a genuine highlight onto text it was never meant to mark (#391, fixed in #405). Two things found while writing it, both worth more than the corrections: `getGraphemeSegmenter()`'s module-level memo is a second cache, distinct from the per-value `segments` view, and was documented nowhere. Collapsing either into per-call construction costs a search box every keystroke and fails no test — the module-level one has no coverage at all. Now named. The four sub-bullets restated numbers that also live in the code comments, and one such figure has already rotted in one of its two homes. They now point at the code rather than copying it, which is why this pass removes 31 lines as well as adding. No `src/` change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LWWrBHgfqGSbeU3V6UuMF8
IgorShevchik
added a commit
that referenced
this pull request
Aug 15, 2026
…age (#409) Each was falsifiable, which is how each was caught. The pattern is the finding: a prose claim about test coverage cannot fail when it stops being true. **"Every constant and every branch above was verified by removing it and watching a named test fail."** #390 found six surviving mutations, three of them constants this bullet covers. Restated as intent, with the procedure spelled out rather than implied, and the other three survivors named — two of which are pinned by `describe('key selection')`, credited so the trail does not end nowhere. **"The unpaired-surrogate strings are the only input that can catch a surrogate range constant being widened."** True only where the probe sits one code point outside the bound it pins. Two of the four sat 0x100 away and caught nothing. **"A pickaxe returns exactly one commit."** It counts occurrences of the string, not authorship, so `54b93e33`'s jsDoc line joined the list and any future comment naming the parameter will too. The claim now attributes rather than counts. **"Only 16 of ~3200 commits carry an `Upstream:` trailer."** 52 do, and 52 of 3179 did when the sentence was written — it was wrong on arrival, not stale. It is load-bearing: it is the stated reason the trailer cannot support a provenance inference. The conclusion survives the correction; the number does not. Also: the unreproducible `8 of 66` figure is marked as a one-off measurement, `createClusterSnapper`'s signature gained a second parameter in #388, the guard list omitted `describe('truncation from the start')`, and `getGraphemeSegmenter()`'s module-level memo — a second cache, distinct from the per-value view, covered by no test — was documented nowhere. Adds one §2 invariant: **`sanitizeSnippet` splits on the tag**. Upstream's placeholder round-trip lets a snippet forge `<mark>` out of its own input, so a port that replays upstream reverts #405. Not reported upstream, so the conflict recurs on every port that touches the function. The four sub-bullets that restated numbers also living in the code comments now point at the code instead — one of those figures had already rotted in one of its two homes. Verified by a mutation pass over every constant and branch in the file: 62 mutations, 55 killed, 5 provably equivalent, 2 real gaps, filed as #410 and #411. Running the check this file now prescribes is what found them. No `src/` change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LWWrBHgfqGSbeU3V6UuMF8
8 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Linked issue
Closes #387.
Type of change
Description
GRAPHEME_SNAP_MAX_LENGTHis documented, and was tested, as a bound on the field text. It was not measured against it.truncateHTMLFromStartbuilt its snapper fromcontent— the value after escaping and after mark insertion — so the ceiling was reached early, by an amount nothing in the constant hints at. Escaping has no fixed overhead:&expands to five characters,"to six.Both degraded, and both rendered 🇸🇺 with an orphaned regional indicator where the author wrote 🇺🇸 — a different country, with nothing to signal the loss. That is the defect #364 describes and #371 exists to prevent, reappearing above a threshold no reader could predict from the constant.
Fix
createClusterSnappertakes the length to weigh separately from the string to segment, namedfieldTextLengthfor what it is. The parameter is required, not defaulted tovalue.length: a default is precisely what would let the next derived-string caller inherit this bug in silence.Cost
Segmenting a string the ceiling would have excluded is affordable — but not because the call is cheap in isolation. On a long run of regional indicators it is not, since
containing()walks the run. It is thatArray.from(html)above it already paid the larger price on the same string, unconditionally, on both sides of this fix.Measured end to end, this branch against the old behaviour on identical input:
value.length8185value.length1505Within noise in both directions. An independent A/B through
vitest bench(400+ samples, ~2% RME) reached the same conclusion: 1.1879 ms vs 1.1843 ms on the all-quotes worst case at the ceiling.test/bench/search.bench.tsgainsunder the ceiling, escaped six-fold, which reaches the ceiling by escaping rather than by length, so the claim rests on a durable measurement rather than a throwaway script — the convention that file's own header sets.An earlier revision of this description carried a cost table that was wrong by three orders of magnitude. The benchmark behind it built the
Segmentsview once and reused it across iterations, while the real code builds a fresh view per truncation. Recording that here because the number was quoted in the commit message and the source comment too, and the comment now explains the trap instead of restating a figure.Tests
The two ceiling tests moved off
value.length + MARKUPontovalue.length. That makessnaps clusters exactly at the ceilingthe plain-text repro in its own right — a value of exactly the advertised length previously degraded, verified againstmain.measures the ceiling against the value, not its escaped copycovers the unbounded half. It was missing because no fixture indegraded pathscontained an escapable character, so only the fixed 13-character single-mark overhead was ever exercised.Mutation-checked: reverting the segmenter gate to the derived string, passing
content.lengthat the call site, movingGRAPHEME_SNAP_MAX_LENGTHby ±1, and ignoring the new parameter are each caught by a named test.732 tests green (
test/utils/,test/components/);eslintandvue-tsc --noEmitclean.test/utils/search.spec.tsrun 38 consecutive times on a quiet tree, all green — two reviewers reported intermittent failures in these tests, which reproduced only while a concurrent mutation-testing pass had the file modified, and whose failure signature matches that mutation exactly.Documentation
.sync/PORTING.md's guard entry said the threshold "is crossed 13 characters earlier than a reading ofvalue.lengthsuggests". That described the defect rather than the design, so it is corrected here rather than deferred to the documentation follow-up — a porter reading the old sentence could have restored the bug deliberately.Provenance
The defect was found by an independent review pass over #371 — five reviewers reading the merged code, rather than the authoring session re-reading itself. #371's own description argued its three self-review rounds were not converging; this is what that looked like in practice. The wrong cost figure, the parameter name, the missing default, and the deferred documentation fix were all caught by a second such pass over this branch.
Checklist