diff --git a/persistent-memory.d/2026-09-23-the-bug-hunt-panel-and-five-vacuous-falsifiers.md b/persistent-memory.d/2026-09-23-the-bug-hunt-panel-and-five-vacuous-falsifiers.md new file mode 100644 index 0000000..938fb1a --- /dev/null +++ b/persistent-memory.d/2026-09-23-the-bug-hunt-panel-and-five-vacuous-falsifiers.md @@ -0,0 +1,77 @@ +# 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. diff --git a/persistent-memory.md b/persistent-memory.md index dafd36d..1774033 100644 --- a/persistent-memory.md +++ b/persistent-memory.md @@ -83,9 +83,18 @@ _As of 2026-09-22:_ including a known-vacuous falsifier it must catch. **When you write a `*Falsifiable:*` line, add its row and run it** — a falsifier nobody has run is a claim, not a test. -- 🔶 **A bug-hunt panel is IN FLIGHT** — heid thread `01M368G2Y0JMTJ2T7M3JMTXV5Z`, - dispatched 2026-09-22 21:31 PDT over the U7-groups diff. If its reply has not - been consumed, drain `/althing:inbox` and triage before treating U7 as closed. +- ✅ **THE BUG-HUNT PANEL LANDED AND IS TRIAGED** (`397ea89`): six defects fixed, + two accepted known risks, one held for design-dev. **660 green, 20/20 + mutation-proved, deployed, 21/21 booths 200.** + → `persistent-memory.d/2026-09-23-the-bug-hunt-panel-and-five-vacuous-falsifiers.md` +- ⚠ **BROWSERS MATCH A URL FRAGMENT RAW FIRST, decoded only second.** So a raw + rel on BOTH the anchor and the id is not "unencoded", it is AMBIGUOUS, and the + jump can land on the WRONG artifact. Encoding one side just moves the + collision — **both sides must use `Item.url`.** Same detail file. +- ⚠ **FIVE VACUOUS FALSIFIERS IN U7 ALONE**, three arms finding the same one + independently. A guard-strength pass is the highest-value part of a panel on a + well-tested diff; the findings sit in the gaps the code comments are most + confident about. - 🛑 **STANDING RULING — NO ANNOUNCEMENTS OUT OF THIS REPO, AND THE OPERATOR SENDS THE EVENTUAL ONE HIMSELF** (operator, 2026-09-22). Verbatim: *"no announcements until the entire arc is done, and even then i'll do it myself."* @@ -122,6 +131,7 @@ _As of 2026-09-22:_ ## Recent decisions +- `[2026-09-23]` ✅ **The bug-hunt panel found six defects and five vacuous falsifiers** — READ BEFORE BUILDING ANY FRAGMENT ANCHOR (browsers match raw before decoded, so both sides must be encoded), and before trusting a well-commented diff's guards → `persistent-memory.d/2026-09-23-the-bug-hunt-panel-and-five-vacuous-falsifiers.md` - `[2026-09-22]` ✅ **v1.0.0b1 — the v1 target staged as a beta, and a version that was two copies** — READ BEFORE DERIVING A VERSION FROM `importlib.metadata` HERE; it reports a different artifact, and `booth/__init__.py` turns out to be stdlib-only → `persistent-memory.d/2026-09-22-v1-staged-as-a-beta-and-a-second-copy-of-the-version.md` - `[2026-09-22]` ✅ **U7 landed — and the number that justified it did not reproduce** — all seven v1 units are in; READ BEFORE TRUSTING A MEASUREMENT INSIDE A CONTRACT, and before assuming a degeneracy guard covers the degeneracy you actually have → `persistent-memory.d/2026-09-22-u7-landed-and-a-table-that-did-not-reproduce.md` - `[2026-09-22]` ⚠ **A mutation harness certified a broken test, twice, for two reasons** — no green baseline, and the pyc cache silently reverting same-size mutations; READ BEFORE WRITING ONE → `persistent-memory.d/2026-09-22-a-mutation-harness-that-certified-a-broken-test.md`