From 225570623dace359743a7770a4470b905cc8b39e Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Wed, 23 Sep 2026 10:28:52 -0700 Subject: [PATCH] docs: the dotfile list gains .seen, and names the shape a new one should copy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Held until the merge deliberately: this file describes what is deployed, and writing it while the code sat on another agent's branch would have made our canonical convention document describe a service that was not running. Also records a latent bug the R2 work surfaced in code it did not touch. .blurred stores one stripped rel per line, so a rel carrying a leading space or a newline does not round-trip and blurring ' a.png' can blur 'a.png'. .seen was written as a JSON array for that reason, and additionally opens O_NOFOLLOW | O_NONBLOCK with an S_ISREG check so a planted symlink is refused and a FIFO cannot hang the read — the outage this repo has already paid for once. New dotfiles inherit .seen's shape, not .blurred's. --- CLAUDE.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 5ba62d2..1ba629e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -63,12 +63,24 @@ No database. `ls ~/booth-data` tells you everything the service knows. Per-booth operator state is a **dotfile inside the booth**: `.forever` (keep), `.viewed` (last deliberate look — U4's "viewing is activity"), `.blurred` (one -rel per line), `.marks.json` + `.marks.lock` (judgment), `.pins` (link-board pin +rel per line — ⚠ see below), `.seen` (R2: rels looked at full size, a JSON +ARRAY), `.marks.json` + `.marks.lock` (judgment), `.pins` (link-board pin ids), `.uploaded` (upload-booth marker). `booth_items()` skips `name.startswith(".")`, so a new dotfile costs nothing in item counts, galleries or zips. That skip is why the dotfile is the right shape for new operator state — use it rather than inventing a sidecar-per-item. +⚠ **`.seen` is a JSON array where `.blurred` is one stripped rel per line, and +the difference is a latent bug in the older one.** A rel may carry a leading +space or a newline; line-stripped storage does not round-trip it, so blurring +`" a.png"` can blur `a.png` instead. `.seen` was written as JSON for exactly +that reason (design-dev, R2), and it also opens `O_NOFOLLOW | O_NONBLOCK` with +an `S_ISREG` check — a planted symlink is refused and a FIFO cannot hang the +read, which is the outage in +`persistent-memory.d/2026-09-22-size-cap-opened-a-hang.md`. **Any new dotfile +inherits that shape, not `.blurred`'s.** `.blurred` itself is unfixed and +pre-existing. + ### 3. One resolver for item facts `booth.items.booth_items(booth)` is the only place a file is classified, a