A backup is never changed by a new install, a restore downloads first, and a restore tells the truth (2026-10-25)
Brief: Sunday 2026-10-25, up to 12 h, commit only. Operator rulings D47 and D48 (2026-10-25 08:38, 09 §3 decisions
256, 257). Box: scratch guest 9202 on demo-hp (ssh hp), controller 0.342.0 for the BEFORE proofs (its restore,
unit and kept-data code is byte-identical to e1613ae: no commit between 42cda07 and e1613ae touched
recovery_unit.go, restore_unit.go, restore_dbcreds.go), then 0.343.0-rc.1 built from bd9f4f7 (an -rc tag
is never offered to a household) for the AFTER proofs; 0.342.0 put back at the end.
Safest readings taken (the brief allowed no question)
- Install identity: a new field
install_id(16 random hex), not the data stamps — the stamps say which VERSION wrote the data, not which install. A unit from before D47 has none: then a carried secret that differs on both sides means another install (a reinstall mints new ones); with no differing secret it is this install's (the old behaviour). - Where the set-aside unit lives and how it is removed:
<namespace>/backups/set-aside/<app>/<UTC stamp>/on its own drive (a rename), recorded as a D25 kept copy — listed on the restore page with „Visszaállítás" and „Eltávolítás". The app's remove with „delete its backups too" deletes it too: the D25 / R-1252 H9 rule for kept copies. - A „partial write" = one half (definition or data) written into a unit whose other half belongs to another install. The writer refuses it when the set-aside cannot be done. A definition-only unit of a fresh install (no data yet) is not partial — it is that install's whole unit.
- R-1270 (the brief's own safest reading): a health timeout does not pour the old data back; the data stays, the undo copy is kept (the „kept for support" state a failed put-back leaves — no new retention rule), a late start within 30 minutes turns the record into a success and releases the copy.
- D48 sentences: Docker's „manifest unknown / not found / pull access denied / repository does not exist" reads as „the maker no longer offers it"; everything else (busy, rate limit, timeout, unreachable) as „try again later".
- R-1271: the clock-skew allowance is 10 minutes. A future-dated copy that is the only copy is still offered (it may be the household's own), marked and not recommended. The „another drive" check stays a path check (the brief: an old box's data on a new box is what off-site is for).
- The
.fabimport is not a „unit" path and is not changed here; its gap is a row (R-1279).
Before (9202, controller 0.342.0 = e1613ae for these files) — before/
catalog-sweep-2026-10-24/tools/unitprobe.py tandoor on 9202 (before/_unitprobe/tandoor/): install, one account,
„Mentés most" (unit 07:53:46), remove keeping data and backups, install again, wait for the controller's next capture,
„Visszaállítás".
- R-1269: 08:00:36 „Recovery unit captured for tandoor" — the kept unit's
app.yamlchecksumcbfcb538…→e19d2610…,created_at07:53:46 → 08:00:36, the data files unchanged. Cause atfile:line:felhom-controller/controller/internal/backup/recovery_unit.go:194(e1613ae) — the refresh's only „same definition" test is the pins (frozen), and a reinstall of the same version has the same pins; the writes at:254-258then put the new install'sapp.yaml(its new database password) beside the old data. The restore takes the unit's password (restore_dbcreds.goR-1106 rule) — the new one — over the old data directory. - R-1270: the restore record
ok: true, „A(z) tandoor: 3 adatkötet és az adatbázis visszaállítva — az alkalmazás újraindult." while the app stayedstarting;password authentication failed×44 (app) / ×23 (postgres); the account not there (restore_unit.go:567-569ate1613ae: the health failure is a WARN). - Why a volume app's reinstall asks no kept-data question: the question is about the app's drive FOLDER
(
${HDD_PATH}binds underappdata/,stacks/kept.goOldAppDataPaths;07§6.5, decision 36). Tandoor keeps nothing there; „remove, keep my data" removed its three named volumes (the record'svolumes_removed) and kept only its backup. A gap for the household → R-1278.
After (9202, controller 0.343.0-rc.2 = 1f9c863) — after/
| proof | before (e1613ae) |
after |
|---|---|---|
R-1269 / D47, Tandoor (tools/unitprobe2.py, after/_unitprobe2/tandoor/) |
the refresh rewrote the kept unit's app.yaml; the restore paired the new password with the old data, starting, account gone |
09:13:03 „the recovery unit of an earlier install (77ea…; the install ids differ) is SET ASIDE whole → backups/set-aside/tandoor/20261025T091303Z"; the set-aside unit is install A's unit byte for byte (9 files, sha256 each); „Megőrzött másolatok" offers „Visszaállítás"; restored in 42 s, running, the account reads back, 0 password errors (app and postgres); remove with data leaves nothing, the set-aside folder included |
R-1269 / D47, AdventureLog (after/_unitprobe2/adventurelog/) |
(sweep: the same fault on its re-run) | set aside 09:23:03, byte for byte (8 files), restored, running, the item back, 0 password errors, nothing left |
D48 (tools/pullprobe.py vikunja, after/_pullprobe/vikunja/) |
the first pull came after the stop (code order, restore_unit.go at e1613ae) |
the unit's pin edited to vikunja:0.0.0-felhom-d48-missing → „REFUSED … before anything was touched: … could not be downloaded (the version does not exist any more)"; the household read „…verzióját (vikunja:0.0.0-felhom-d48-missing) nem lehet letölteni: a készítője már nem kínálja. Az alkalmazáshoz nem nyúltunk…"; the container's StartedAt the same before and after (09:29:54.57); the item still there; the original unit back byte for byte → a normal restore worked, the item back |
| R-1270 (same run) | ok: true „…az alkalmazás újraindult." over starting |
the unit's pin edited to busybox:1.36.1 (pulls, exits at once) → after the 90 s wait the record ok: false, not_started: true, „A(z) vikunja: az adatokat visszatöltöttük, de az alkalmazás még nem indult el. Várj pár percet…"; the undo copy kept (restore-undo/vikunja/20261025T093149Z); the original back → a normal restore worked, the item back |
R-1271 (tools/keptprobe.py romm, after/_keptprobe/romm/) |
the future-dated off-site copy chosen over the family's own (sweep) | a forged second-drive copy dated 2026-10-28 06:39 beside the app's own unit: the question named „saját mentés, 2026-10-25 10:38", no future flag; the own unit moved away for a moment: the forged copy alone was offered with use_future: true and „Figyelem: ennek a mentésnek a dátuma (2026-10-28 07:39) a jövőben van…"; with the own unit back, „use my kept data" loaded tier 1 (backups/primary/romm, 09:38:55Z), the item back |
Two findings of the live runs, fixed without a row (each red-proved): (1) run 1 of the Tandoor proof
(after/run1-list-hidden/) found the restore page listing NO kept copy on 9202: the „Megőrzött másolatok" section sat
inside the off-site card, and 9202 has no off-site — so a box without off-site never listed a D25 copy either. Fixed in
1f9c863 (one named template, two call sites, parity fixtures unchanged); rc.2 then listed it. (2) The R-1270 run's
kept undo copy outlived the app's remove with its backups; fixed in 1f82959 (the remove deletes
backups/restore-undo/<app>), proven by its test only — the copy on 9202 was removed by hand (2.6 MB, mine).
after/run1-probe-bug/ is a probe of mine that crashed on its own bug before touching anything.
The file:line causes (at e1613ae): R-1269 backup/recovery_unit.go:194 (the frozen pins test) and :254-258
(the writes); R-1270 backup/restore_unit.go:567-569, the same WARN at offbox_reconstitute.go (the off-site path),
tier2_restore.go (the file restore) and restore.go (the fallback); D48 restore_unit.go:497 (the stop) before
:552 (the first compose up, the DB-only start); R-1271 backup/kept_load.go:179-184 (KeptNewer: the newer date
wins, future or not) and :97 (the „another drive" check compares HDD_PATH, a mount path).
Not covered and filed: R-1278 (a volume app's reinstall does not offer its kept backup), R-1279 (the .fab import
removes the app's volumes before its pull).
Observation, NOT-A-FINDING: 9202 logs „immich: definition REFUSED by the allow-list" at every start — it was there
before this run's image (an earlier session's Immich on /mnt/sizing-bench); not this run's.
Teardown
- Machine: 9202 only — my throwaway installs (Tandoor ×3, AdventureLog, Vikunja, RomM) each removed through the
product with their data; the two empty folders my runs left (RomM's
appdata/romm, the emptybackups/set-aside/) and the one kept undo copy (above) removed by hand after checking they held nothing else; the0.343.0-rc.1/.2images removed from its Docker; the controller back on 0.342.0 (/etc/felhom-controller-image); the apps found running (Immich, Paperless-ngx, the file browser, traefik) running. No VM, no LXC created; Tester 1 and the thin pool untouched. - Host: DooPlex — the session's 9202 password file in the session scratchpad shredded at the end. The rc images stay in the registry as test tags (never offered to a household).
- Hub: provisioned nothing (9202 has no hub). ep0: nothing.