4.6 KiB
REPORT — Cleanup bundle: email-wipe guard + carried hygiene — controller v0.137.0
Summary
Four closing-the-loop items from the backup-redesign arc + 6D. One code fix (Part 1, shipped v0.137.0), three operational/doc items executed inline.
Part 1 — empty-email notification save guard (CODE, v0.137.0) — SHIPPED
Problem: settingsNotificationsHandler dropped a trimmed-empty notification_email into the
prefs and pushed it to the hub (SyncPreferences), overwriting the customer's provisioning-seeded
alert address — a customer saving any notification change with a blank email field silently wiped
their own hub-side alert delivery (the 2026-07-15 demo incident, restored by hand in 6D
P3-DELIVERY).
Fix: after computing the trimmed email + enabled events, refuse the save when
email == "" && len(enabledEvents) > 0 — return before SetNotificationPrefs and any hub sync,
re-render with the Hungarian error "Adj meg egy értesítési e-mail címet – bekapcsolt értesítésekhez szükséges egy cím, ahova küldhetjük őket.", and repaint the just-submitted
checkboxes (render-only overlay on notificationsPageData's NotificationPrefs). The legitimate
empty-email + zero events clear-all still proceeds. SyncPreferences / the hub / the
seed-migration are untouched. Deliberately no HTML required attr (it is unconditional and
would block the legitimate clear-all — the server-side guard is the precisely-conditional floor).
Tests + red-proof (web/notifications_guard_test.go, real temp-file Settings): guard-fires
(stored email survives the refused save), legitimate clear-all proceeds, normal save persists.
Red-proof: neutering the guard → the stored email is wiped to "" (the incident) → the test fails.
Full go build/vet/test ./... green.
Deploy + live: built + pushed felhom-controller:0.137.0, deployed to guest 9201 (Up, healthy;
selfupdate: Current version 0.137.0 is up to date). The protected asset is confirmed present — the
demo customer's notification email nagyfenyvesi.viktor@gmail.com is set. The authenticated UI
click-through needs the customer-owned claim password (CC does not hold it), so the server-side guard
is validated by the endpoint-equivalent unit test + red-proof (the CLAUDE.md live-validation proxy).
Part 2 — duplicate recovery-unit cleanup (HYGIENE) — 1 removed, 3 STOPPED
Recovery units are <drive>/backups/primary/<app>/; the controller's tie-break selects the newest by
manifest CreatedAt, else dir mtime (backup/offbox.go:558-607, first-in-order wins on a CreatedAt
tie). On felhom-flash:
- Removed
/mnt/felhom-drives/felhom-flash/backups/primary/immich(44M) — CreatedAt2026-06-23T10:02:35Zvs the livefelhom-usbcopy2026-07-15T17:41:20Z→ confirmed older, never selected. Prefix asserted (*/felhom-flash/backups/primary/*) beforerm -rf. - STOPPED (not deleted):
felhom-flashaudiobookshelf, komga, romm — their manifest CreatedAt is identical to thefelhom-usbcopy (2026-06-23T10:02:35Z), so the controller's tie-break is drive-order-dependent and I cannot confirm the flash copy is the non-selected/older one. Per the STOP discipline, left for a manual byte-identity check / disposition (not this micro-task).
Part 3 — campaign6 orphaned autofs (OPERATOR ACTION) — safe clear attempted, left for Viktor
/mnt/felhom-drives/campaign6 is a bare empty leftover directory (nobody:nogroup) — not a live
mount (not a mountpoint, absent from the mount table, no autofs config / systemd unit / fstab entry).
A safe non-disruptive rmdir (refuses non-empty dirs + mountpoints) was refused with Permission
denied even as root (an autofs-ghost / immutable artifact). No live mount was disturbed (mount count
89→89; all 8 drive mounts intact). Not escalated to chattr/force (beyond a safe clear). Left for
Viktor's demo-host reboot window — CC did not reboot.
Part 4 — 6D audit doc tag (DOC) — committed
Added the matching track-only disposition line to the campaign6 autofs LOW finding in
felhom.eu/documentation/audits/CAMPAIGN-6D-2026-07-15.md (consistency with the duplicate-recovery
LOW). Commit dee72cd.
Queue after this bundle
- Pending operator (Viktor): campaign6 autofs clears on the next demo-host reboot; the tied-CreatedAt
felhom-flashaudiobookshelf/komga/romm duplicates await a manual disposition. - Deliberately not here (correctly deferred): Peti-return runbook (hardware-gated); P4-DEEP timing + P-TIER2 deep-4 (pre-broad-launch resilience); agent 0.88 publish (6D P-DAY0 shows the manifest already vouches 0.88/golden-0.136 — likely closeable, verify separately).