Whole-branch review by Fable, and what it changed — 3363262
Done per AGENTS.md's highest-capability rule, read as one diff. It found one blocking defect and two instances of this repo's own recurring shape. All fixed; gate green, drive 44/44, CI running.
BLOCKING — my Markdown fix was incomplete, in the way its own commit message warned about
74320cb's title says "a newline in a run can no longer inject Markdown into an export". It could. I taught escapeMarkdown where a line begins and then asked i == lineStart — the first character on a line, not the first non-space. CommonMark allows a block marker up to three spaces of indentation and all of them interrupt a paragraph:
"intro\n # one space then hash" -> a real heading
"intro\n # three spaces then hash" -> a real heading
"intro\n - one space then bullet" -> a real bullet
"intro\n 1. one space then list" -> a real ordered listAnd two characters were never escaped in any position:
"intro\n===" -> a setext H1, which promotes the paragraph ABOVE it
"intro\n~~~\nswallowed" -> a code fence that interrupts the paragraph and
then eats every following line of the documentThe fence is the worst of them. It does not restyle a line; it swallows the rest of the file.
The thing worth recording is not the bug, it is that I described it and then shipped it. That commit message names this repo's recurring failure — a check that reports success while measuring something adjacent to the question — and the fix underneath it was true of the cases I tested and false of the sentence I wrote. Five test cases all shaped "newline then marker at column zero" agreed with each other and none of them asked the question the commit claimed to have answered.
Fixed by tracking "anything but spaces seen on this line yet". Any run of spaces counts as still-at-line-start rather than counting to three — over-escaping renders correctly, which is the trade the function's own header already made. = and ~ are escaped at the start of a line only, so a = b is untouched.
One detail I got wrong in the other direction and Fable's report let me correct: I first expected \=\=\=. Only the first character needs escaping, because an escaped = means the line is no longer a setext underline. \=== is the whole fix, and three backslashes would have bought what one bought.
Recorded rather than fixed: four spaces is an indented code block
No escaping prevents it — the block is made by the whitespace, not by a character a backslash can go in front of. The text survives verbatim, which is the module's actual promise, but renders as code. Fixing it means rewriting the author's own leading whitespace, which is a different decision from escaping and not one to take in passing. TestMarkdownIndentedRunLinesBecomeCodeBlocks records it so it stays a decision rather than becoming somebody's discovery.
Two more checks that could not see their own failure
That makes four on this branch, which is worth stating plainly: this pass set out to fold in checks and ended up finding that a third of the interesting ones could not fail.
- "a query matching nothing says so" tested that some text appeared in the status element. The palette writes two different strings there —
data-emptywhen nothing matched,data-failedwhen the fetch threw — so the check passed just as well when the search was broken and the person was being told so. It compares against the element's owndata-emptynow. Confirmed red by making the empty case report the failure copy:it says "Search is unavailable right now."; the empty-result copy is "No documents match". - The 320px checks never asserted the viewport was 320. They measured against
documentElement.clientWidth, which reads 320 only because rastrillo's vendored topbar emits a viewport meta — nothing in this app does. Lose it on a module upgrade and Chrome lays out at 980px,clientWidthreads 980, and both checks pass while measuring a desktop-width page. That is the check I added tonight to catch exactly this class, carrying the flaw it was written to prevent. It asserts the viewport now, and a mismatch says "this check measured nothing" rather than reporting a comfortable pass.
Also from the review
list.html's locale caveat had the threshold and the symptom wrong. Because the field gives way first and the button never shrinks, a wide label eats the field long before anything overflows: ~200px leaves ~80px of field, ~270px a sliver, and only past ~280px does anything cross the edge. So the first failure a wide catalog produces is a search box too narrow to read what you typed — a usability problem, not a 1.4.10 breach. Stated as the sequence it actually is. ([docs-create-form]'s existing comment states the same caveat as a bare "about 270px", which is the second half of that sequence.)caretChecksis wrapped ingroup()too. The toolbar section is still inline and still aborts the run when it cannot select a word — named as a follow-up in the comment rather than moved, because relocating a hundred lines of working checks at the same time as fixing them is how a harness stops being trustworthy.- A correction to 55a4ac0's own message: it says "twenty checks". The palette group is 19. 19 + 2 reflow + 23 existing = 44, which is what the drive prints.
What the review checked and did not find
Recording this because "what a review covered" is worth as much as what it objected to:
- The CSS fix is real, not moved — verified against the pinned
rastrillo@v0.22.0ui/tokens.css:[rst-input]'swidth: 100%loses to flex-basis on the main axis, our two-attribute selector outranks its one, no!importantin the file, and[rst-page]'s padding makes the 288px column arithmetic right. The reasoning that the create form was a casualty of the search form's min-content floor is correct. - NFC is genuinely orthogonal to accent folding. NFC never drops a combining mark, so
cafecannot matchcafé. Its singleton decompositions never interact with the punctuation-stripping loop except on spaces, which are spaces on both sides. NFC is not NFKC, so ligatures and compatibility forms are untouched. - The multi-byte reasoning in the first fix did hold:
rangealways yields rune starts,\nis one byte, sos[lineStart:i]never starts mid-rune. Checked with"é\n# after multibyte"and"日本\n1) after cjk". "the exact title ranks first", the derived-query logic, the no-JS search checks, and the stale-message checks are all genuine — each asserts the thing its name claims.
Still yours, unchanged
Nothing in the review touches the four decisions waiting on you: the copy review, #16's merge-method question, accent folding, and whether the drive joins CI. The last one is worth a little more after tonight than it was: the drive now carries the only 320px coverage in the repo, and this round proved it can be wrong in a way only a deliberate break reveals.
— claude~paul@keymail.dev, session "discussions triage overnight"