238472b8ed
ROADMAP R-43/R-44 → SHIPPED with what actually landed:
- R-43: ReconstituteFromOffsite — safety dump → stop → files overwritten to
the snapshot version → start → the snapshot's own dump replayed from the
SCRATCH unit (the live unit is still never overwritten). Invariants:
nothing is ever deleted, and the undo is verified on disk before the act.
- R-44: every run, manual AND nightly, refreshes dumps + units BEFORE the
capture, so each snapshot is a coherent {DB@T, files@T} pair stamped with
offsite_run_id + dumps_at. Nightly ordering is now structural rather than a
coincidence of two scheduler entries at 02:30 and 04:15.
DIAG doc gains a "fixed in v0.148.0" header pointing at both.
Capability map deliberately NOT flipped: the DB half now exists but is PARTIAL,
not PROVEN-LIVE — shipped and deployed with no live acceptance behind it. The
customer-restore row stays MISSING, now blocked only on the evidence run rather
than on missing capability, and R-3 stays DRAFT.
Still open: the 00-capability-map.md:61 ruling — did CAMPAIGN-6D's "immich
end-to-end from offsite alone" exercise the DB half, or only the file half?
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P9Nn14TWGzKoqAJAiVwC2s
72 lines
4.2 KiB
Markdown
72 lines
4.2 KiB
Markdown
# REPORT — DIAGNOSE immich offsite restore (felhom.eu side: docs only)
|
|
|
|
> Written as `REPORT-diag-immich-restore.md`, **not** the shared `REPORT.md`, per the CLAUDE.md
|
|
> convention — `REPORT.md` is overwritten and currently holds the 2026-07-18 website refresh.
|
|
> No code shipped in this run; findings only.
|
|
|
|
**Date:** 2026-07-19 · **Box:** demo-felhom (felhom-pve guest 9201), controller 0.146.0, immich v3.0.3
|
|
|
|
> **CLOSED IN CODE 2026-07-19 — controller v0.148.0.** Findings 1 and 2 shipped as R-43 (offsite
|
|
> reconstitution: safety dump → stop → overwrite files → start → replay the snapshot's dump) and
|
|
> R-44 (every run dumps before it captures; manifests carry `offsite_run_id` + `dumps_at`). Deployed
|
|
> to demo 9201, healthy. **The §9 live acceptance has NOT run**, so no capability-map flip: the
|
|
> offsite row is PARTIAL, the customer-restore row stays MISSING, R-3 stays DRAFT. Implementation
|
|
> detail lives in `felhom-controller/REPORT.md`.
|
|
|
|
## What ran
|
|
|
|
A diagnosis of "immich offsite restore succeeds but photos do not reappear". No product code was
|
|
changed: no restore/backup logic, no labels, no flashes, no `restic prune`/`forget`, no snapshot or
|
|
escrow changes.
|
|
|
|
## Outcome
|
|
|
|
The restore did not fail. **It was never invoked on missing data, and could not have worked
|
|
if it had been.**
|
|
|
|
1. Viktor deleted the 11 photos in the immich UI to test offsite restore. A UI delete means
|
|
**trash**, not deletion — no file left the disk. Both „csak a hiányzó fájlok" runs merged
|
|
**0 files**, correctly, and flashed success. The test proved nothing.
|
|
2. A *valid* test would also have failed: **no offsite path loads a database.** All three buttons
|
|
are file-only. Files would return; the library would stay empty.
|
|
3. The shipped dump is additionally stale by design — from the 02:30 local run, never refreshed
|
|
before a manual push. Probed: **`asset: 0`, `user: 0`, `album: 0`**.
|
|
|
|
**Photos:** left in trash at Viktor's instruction (recovery not wanted). All 11 files verified
|
|
present on disk and all 11 rows intact, so an ordinary un-trash recovers them until immich's
|
|
30-day auto-purge.
|
|
|
|
**Answer to "can a customer trust same-day offsite?"** For a DB-indexed app: **no — files come
|
|
back, content does not.** The backup half is honest; the restore half cannot reconstitute the app.
|
|
|
|
## Decisive evidence
|
|
|
|
- `updatedAt` == `deletedAt` on all 11 asset rows ⇒ **no restore operation touched the DB.**
|
|
- Unit dump `immich-postgres.sql`, 51 954 452 B, mtime **02:30 CEST** ⇒ `asset: 0 / user: 0 /
|
|
album: 0`. The 52 MB is entirely immich's shipped geodata reference tables. It predates the admin
|
|
user (07:56:25) and the photos (07:57).
|
|
- **Latent hazard:** had a full restore loaded that dump, it would have written an empty DB over the
|
|
live one, destroying the trashed rows that were the only surviving recovery path.
|
|
|
|
## Files written
|
|
|
|
| File | Change |
|
|
|---|---|
|
|
| `documentation/audits/DIAG-immich-restore-2026-07-19.md` | new — timeline, evidence, source mechanism table, 7 findings |
|
|
| `documentation/backlog/ROADMAP.md` | **R-43** (P2-HIGH, offsite restore cannot restore a DB) + **R-44** (P2-HIGH, manual push ships unrefreshed dump) |
|
|
| `documentation/architecture/00-capability-map.md` | customer-restore row **stays MISSING**, gains the finding + a method note for R-3; offsite-restore row flagged *scope contested* |
|
|
|
|
## Needs Viktor
|
|
|
|
1. **Capability-map ruling (line 61).** The offsite-restore row claims PROVEN-LIVE citing
|
|
"immich end-to-end from offsite alone" (`CAMPAIGN-6D`). That phrase is contested by this
|
|
diagnosis. I flagged it rather than downgrading a proven row — did 6D's accept leg exercise the
|
|
DB half, or only the file half?
|
|
2. **Optional real red-proof.** Emptying the trash would create genuine data loss and convert the
|
|
dump-probe inference into a live proof. Offered, **not run** — irreversible, and the probe
|
|
already settles it.
|
|
3. **Unreconciled: the 704.6 MiB figure.** Measured 126 MB total on the library storage. If
|
|
704.6 MiB came off a controller Storage page, that gap is its own defect.
|
|
4. **Orphaned pre-v3 tree** `dccc13fe…` (~55 MB across upload/thumbs/encoded-video) stranded by the
|
|
immich 2→3 redeploy — worth a sweep policy for major redeploys.
|