Commit Graph

3 Commits

Author SHA1 Message Date
admin 97249099d6 docs: DIAG round 2 — H1 confirmed, H4 found; two standing rulings landed
VERDICT. H1 confirmed: the reconstitution never ran. /backup/offbox/reconstitute
was never hit (reconstituted/safety-dump/replay line counts all 0); the operator
clicked the old missing-only button, which merged 34 files and left the DB
untouched. H2 rejected (the full path never executed; staging used the correct
snapshot 49e7cb46). H3 rejected (no replay happened; DB was genuinely asset:0).

R-44 is exonerated and working: 49e7cb46 carries offsite_run_id 20260719T102851Z
and its dump probes to asset:11 / user:1 — a properly coherent pair, against
round 1's asset:0 / user:0.

H4 (NEW, the more important result). Phase-3 recovery ran the real sequence and
the v0.148.0 path executed correctly — safety dump, stop, start, replay — then
the replay ABORTED: relation "clip_index" already exists. Proven to the second:
  10:58:25 controller begins replay
  10:58:33 immich-server "Reindexing clip_index" -> "Reindexed clip_index"
  10:58:35 dump's CREATE INDEX clip_index fails, exit 3
The replay races the app's own schema repair, because reconstitution starts the
stack before replaying (ImportDump needs a live container). The photos survived
only because pg_dump emits COPY data before CREATE INDEX — luck, not design. The
same start-then-replay shape is on the LOCAL path, so it is a class defect.

Recovery: PARTIAL and STOPPED as instructed. All 11 assets are back and visible
by every DB criterion (status=active, deletedAt null, all files resolve), but the
operation reported failure and immich reports schema drift. Not clean acceptance
evidence; no second attempt made; safety dump read only.

Findings -> R-47 (the replay race), R-48 (restore controls separable only by
layout — the proven cause of this incident), R-49 (1.1 GB of a 1.2 GB immich
backup is ML model cache + a postgres data-dir tar duplicating the .sql dump +
immich's own nightly dump; recorded, not changed).

RULINGS LANDED.
  - 00-capability-map.md:61 -> PARTIAL, scope-corrected: 6D's destruction hit the
    FILE TREE only; the DB survived in its named volume, so "end-to-end from
    offsite alone" overclaimed scope.
  - The 704.6 MiB "discrepancy" -> CLOSED, not a defect: it was immich's own
    Tarhely widget, never a controller page. Same for round 2's 650MiB->1.4GiB.
  - customer-restore row: partial evidence recorded, NOT flipped.

Diagnosis only — no code, label or layout changes; no forget/prune.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P9Nn14TWGzKoqAJAiVwC2s
2026-07-19 13:04:58 +02:00
admin 238472b8ed docs: R-43 + R-44 shipped in controller v0.148.0 (live acceptance still pending)
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
2026-07-19 12:27:11 +02:00
admin f3d1ba3062 docs: DIAGNOSE immich offsite restore — findings + ROADMAP R-43/R-44
Viktor deleted 11 immich photos to test offsite restore; both place runs
merged 0 files and flashed success. Two-layered root cause:

- A UI delete means TRASH, not deletion — no file left the disk, so there
  was genuinely nothing missing to restore. The test proved nothing.
- A valid test would also have failed: no offsite path loads a database.
  All three buttons are file-only (offbox_restore.go:171-232, :346-421).
  Files return; the library stays empty. The only DB replay is
  RestoreFromRecoveryUnit, reachable solely from the LOCAL restore panel.

Compounding: the manual push never refreshes dumps (offbox_handlers.go:
203-227) — today's unit dump is from 02:30 and probes to asset:0 / user:0 /
album:0, predating both the admin user and the photos. Had a full restore
loaded it, it would have written an empty DB over the live one, destroying
the trashed rows that were the only surviving recovery path.

Answer to "can a customer trust same-day offsite?" for a DB-indexed app:
no — files come back, content does not.

No product code changed. Photos left in trash (recovery not wanted).
Capability map: customer-restore row stays MISSING by finding, not by
absence of attempt; offsite-restore row flagged scope-contested pending
a ruling on whether CAMPAIGN-6D exercised the DB half.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P9Nn14TWGzKoqAJAiVwC2s
2026-07-19 08:47:34 +02:00