diff --git a/REPORT.md b/REPORT.md index 8189628..34b0478 100644 --- a/REPORT.md +++ b/REPORT.md @@ -31,7 +31,7 @@ demonstration of R-156 and of its fix. 41 fixture tests driving `check()` (the f calls); every rule red-proofed. Registered in `CLAUDE.md` and `REUSE.md`. **Enforcement is convention, not CI** — the catalog repo -has no CI of any kind. Raising that is proposed as R-160. +has no CI of any kind. Raising that is proposed as R-161. ## Method notes worth carrying forward diff --git a/audits/persistence-sweep-2026-08-02/README.md b/audits/persistence-sweep-2026-08-02/README.md index 5ac80d9..e67c306 100644 --- a/audits/persistence-sweep-2026-08-02/README.md +++ b/audits/persistence-sweep-2026-08-02/README.md @@ -632,7 +632,21 @@ the very finding this session was commissioned to act on. **R-156 is the reason and it is not in the register.** Whoever files the entries below should carry R-156 and R-157 across at the same time. -### R-158 — wishlist's data lands in an ANONYMOUS volume: never backed up, orphaned by a redeploy +**And it happened again, to this document, while it was being written.** The first draft of this +section numbered its proposals R-158…R-161 on the strength of a register grep showing R-155 as the +highest filed. Mid-session the parallel session pushed +`audits/SPIKE-recovery-unit-space-2026-08-02.md` and `audits/CAMPAIGN-10-closeout-2026-08-02.md`, +both of which **use R-158** for an unrelated finding (recovery-unit space ceiling on mp1) — and +neither adds it to `ROADMAP.md` or `OPEN-ITEMS.md`, which still stop at R-155. So a grep of the +register was true when it was run and stale within hours, and two sessions minted the same number +for different findings on the same day. + +These proposals are therefore renumbered **R-159…R-162**, and the number to claim should be taken +at filing time, not at drafting time. The register being the only source of truth is precisely what +is not happening: **R-156, R-157 and R-158 are all live in audit documents and none of them is +filed.** + +### R-159 — wishlist's data lands in an ANONYMOUS volume: never backed up, orphaned by a redeploy **FIXED HERE** (`templates/wishlist/docker-compose.yml`); filed to record the class. @@ -655,7 +669,7 @@ immich ever writes there is invisible to backup. Suggested standing rule for `RE must mount every path in its image's `Config.Volumes`, or state why not.* Checkable statically only if the image is pulled, which is why it lives in the runtime gate. -### R-159 — gramps-web persisted three paths and wrote to none of them +### R-160 — gramps-web persisted three paths and wrote to none of them **FIXED HERE** (`templates/gramps-web/docker-compose.yml`). @@ -669,7 +683,7 @@ Severity above papra's: papra loses documents a customer uploaded, which they ma elsewhere. gramps-web loses the family tree — the artefact the customer *built inside the app*, of which no other copy exists by construction. -### R-160 — the gate exists, and nothing automated runs it +### R-161 — the gate exists, and nothing automated runs it The check R-156 asks for now exists (`scripts/check-volume-persistence.py`, §7). Its enforcement level is **convention**: the catalog repo has no CI of any kind (`.gitea/workflows`, `.github`, @@ -688,7 +702,7 @@ buildable from this repo: Interim position, recorded in `CLAUDE.md`: run it when a template's `volumes:` block or image tag changes, and at the start of every catalog campaign. -### R-161 — `docker diff` is the only witness, and its failure mode is quiet +### R-162 — `docker diff` is the only witness, and its failure mode is quiet A limitation, not a defect. The gate's power comes from `docker diff` excluding mounted paths, which makes "in the writable layer" mechanically decidable — an implementation detail of the overlay