Archived 15 entries (Recent decisions 14, Tried and abandoned 1) oldest-first to archival-memory.md; 5 held back on the open-deferred-work guard and 164 on the 14-day guard, so the index stays over the soft cap at 477 lines. An over-cap file that keeps live decisions beats a scannable one that lost a belayed item. Four new detail files cover the day: the ops log and its four self-inflicted failure modes, the Booth's two dead controls and the four-iteration layout probe, the Gitea org grant plus the dead claude-bot token that had been misreporting permissions, and the disk triage that rescued a LoRA adapter from a directory this box sweeps at three days. lv-mccarthy's run outcome remains unverified after two days and is the first line of the in-flight section and step 1 of the handoff.
46 lines
2.8 KiB
Markdown
46 lines
2.8 KiB
Markdown
# `[2026-09-21]` The Booth gained blur and a closed keep round trip — after shipping two controls that did nothing
|
||
|
||
**Shipped** (2e7fd71, 271cb11, 751eecb, 07c9cb2): per-item cosmetic blur
|
||
(`.blurred` marker, CLI `blur`/`unblur`, caption toggle, click-to-reveal, cover
|
||
thumbs inheriting it), the ephemeral→kept `★` button closing a round trip that
|
||
previously needed a shell, a direct `×` on kept cards, and in-booth
|
||
keep/release with an open-redirect-safe `next`.
|
||
|
||
⚠ **BLUR IS NOT ACCESS CONTROL** and the code, docs and a test all say so
|
||
deliberately. A blurred item is still served at its own URL, still in the zip.
|
||
`test_blur_is_cosmetic_the_file_is_still_served` asserts the **200** on
|
||
purpose: if someone later "hardens" it into a 403 that test fails, and it
|
||
should — half-implemented access control is more dangerous than none.
|
||
|
||
⚠ **Two controls shipped INERT, both found by the operator, both by me reading
|
||
templates instead of rendering them:**
|
||
|
||
- **The reveal button.** Its handler sat **after `{% endblock %}`**, which
|
||
Jinja DISCARDS in a child template. The button rendered; the handler never
|
||
reached the browser. Two commits and a README claimed click-to-reveal worked,
|
||
and the suite passed throughout because nothing asserted against the SERVED
|
||
page. Guards added and **confirmed to fail on reintroduction**.
|
||
- **The kept-card `×`.** Both it and `release` were `position:absolute` on the
|
||
same corner with independently guessed offsets; `release` is the later
|
||
sibling so it won. Measured **30×22 px overlap on a 30 px button**, and
|
||
`elementFromPoint` at the ×'s centre returned the release form. Unclickable
|
||
from the moment it shipped. Replaced with one flex row positioned once.
|
||
|
||
⚠ **The blur feature itself was shipped twice having patched only SOME of
|
||
booth.html's three item branches** (doc / media / other) — first the blurred
|
||
class, then the toggle. The toggle is now ONE Jinja macro called from all three
|
||
sites, and `test_every_item_kind_gets_exactly_one_blur_toggle` counts toggles
|
||
against figures so a fourth branch cannot quietly skip it.
|
||
|
||
⭐ **`scripts/layout-probe.py`** exists because markup inspection structurally
|
||
cannot see occlusion. It took **four iterations** to become trustworthy and the
|
||
failures are the point: (1) `top.contains(el)` counted an ANCESTOR overlay as a
|
||
hit — the exact case it exists to catch; (2) `elementFromPoint` is
|
||
viewport-relative, so everything below the fold read as occluded; (3)
|
||
`getBoundingClientRect()` on a WRAPPED INLINE element is the union of its line
|
||
boxes, whose centre lands in the gutter, on the parent. Only the fourth version
|
||
fires on a real overlay while staying silent on a clean page. **Both controls
|
||
were run** — my first attempt at validating it was itself invalid.
|
||
|
||
See [[2026-09-21-ops-log-and-the-instruments-that-lied]].
|