Files
booth/persistent-memory.d/2026-09-23-the-bug-hunt-panel-and-five-vacuous-falsifiers.md
vh 1826d19a1f memory: the bug-hunt panel, the raw-first fragment trap, and five vacuous falsifiers
The mechanic worth keeping: browsers match a URL fragment against element ids
RAW first and percent-decoded only second, so a raw rel on both the anchor and
the id is ambiguous rather than merely unencoded — and encoding one side only
relocates the collision.

The count worth keeping: five falsifiers in one unit were green under the exact
change they forbade, three arms finding the same one independently. A
guard-strength pass is the highest-value part of a panel on a diff that is
already well tested, because the findings sit in the gaps the comments are most
confident about.
2026-09-23 00:06:26 -07:00

3.9 KiB

The bug-hunt panel found six defects and five vacuous falsifiers

2026-09-23 · booth

Cross-frontier panel (Gróa/Hulda/Regin/Kimi) on U7's diff, althing thread 01M368G2Y0JMTJ2T7M3JMTXV5Z. Landed at 397ea89. Four of the six fixes are for defects no test in this repo could have caught, and the guard-strength sections did something the findings alone would not have.

⚠ The mechanic worth keeping: browsers match a fragment RAW FIRST

The group anchor and the tile id were BOTH the raw rel. That reads as "merely unencoded" and it is not — it is ambiguous, because the HTML spec's scroll-to-fragment tries an exact match on the raw fragment and only THEN on the percent-decoded one. So with a b.png and a%20b.png in one booth, the first's href resolves to the fragment item-a%20b.png and the raw pass matches the SECOND file's id. The jump lands on the wrong artifact — invariant 6's misfiled-judgment failure, arriving through a path invariant 6 never looked at.

The fix has to move BOTH sides. Encoding the anchor alone just relocates the collision. Both now use Item.url (quote(rel, safe="/")), which is injective here (a b → a%20b, a%20b → a%2520b) and is the convention booth_flag has always used. The panel's agreed fix (quote(name, safe='/') on the anchor) was half of it; the correction went back to them.

The blast radius nobody had measured

One non-UTF-8 filename 500s the INDEX for every booth, not just its own page. A 0xff byte reaches CPython as a surrogate, quote raises on it outside any per-item handler, and booth_items feeds list_booths as well as the gallery. Same shape as 2026-09-22-lenient-reader-blast-radius: the per-item read looks local and is not. Such a file cannot be linked, served or zipped, so it is now skipped like a dotfile.

⚠ FIVE VACUOUS FALSIFIERS IN ONE UNIT

The count that matters. Three arms independently found that test_every_group_anchor_lands_on_a_rendered_tile survived v[0] → v[-1]: it asserted the href occurred as SOME id on the page, which stays true while pointing at the wrong one. Hulda's guard table added two more (the informativeness guard survived sizes[-1]; the group count survived len(v) + 1). Two more were mine, found after:

  • the zero-hit filter test used the shared gallery fixture, which has a flagged item — so it passed without ever reaching the empty-filter state it names;
  • the escaping test asserted over the whole page and went red on a code comment containing the string it forbade.

A guard-strength pass is the highest-value part of a panel on a well-tested diff. Regin's "unusually well-tested already" and Kimi's "the commentary was accurate everywhere except where it didn't mention encoding at all" are both true and point at the same thing: the findings were in the gaps the commentary was confident about.

Accepted known risks, documented rather than implied

  • No cap on rail row count. 1,000 groups of two renders 1,000 rows and passes the median guard. Largest live booth is 66 items; picking a cap without a booth that needs one is the invented work the roadmap gate prevents.
  • Item.group sits mid-dataclass. Two arms flagged the positional-construction break and both correctly tagged it robustness with the caller outside the bundle. There is no such caller — Item( appears at exactly one site, keyword-only. Category-5 triage: not adopted, grep recorded.

Held for design-dev, not fixed

.rail is sticky with no scroll-margin, so a fragment jump parks the target — and the :target outline meant to show where it landed — UNDER the rail. Real, one line, and in the stylesheet he is rewriting from scratch. Routed to him.

Seat miss, reported back

Two arms flagged that Heid's canon G1 says Flask while the service is FastAPI — carried from an earlier booth-round template. Hulda handled it by reading the bundle rather than the canon.