Files
felhom.eu/documentation/audits/DRILL-r356-hot-only-restore-2026-08-22
admin c297b9f85e
gates / gates (push) Failing after 17s
R-356 docs: correct R-107 in the architecture, record the design, refresh STATUS, compress the register
07-backup-architecture.md: three places said no offsite action unpacks the
named-volume tars. R-107 closed in controller v0.218.0; all three corrected with
a dated [FACT], the old sentence kept in the past tense. R-102 is NOT closed and
the correction says so explicitly.

New [DESIGN] paragraph in 6.3: the restore destination is resolved by the same
rule as the capture destination, and the wrong-disk refusal applies to apps that
have a drive to get wrong. Carries the 13/40 measurement.

STATUS.md was internally contradictory - nothing waiting, and one decision
waiting, for something the same page recorded as shipped. 218 -> 102 lines; the
deciding section now says what happens if nothing is done.

R-356 compressed into CLOSED-ITEMS.md; OPEN-ITEMS 327109 -> 325236 bytes.

Drill record and 16 evidence files for the live walk on demo-hp.
2026-08-22 13:26:10 +02:00
..

DRILL — R-356: the off-site restore for an app with no data drive (2026-08-22)

Subject: demo-hp (Tier 0, disposable), guest 9201, controller v0.219.0. Method: endpoint-level. claude-in-chrome is not available on DooPlex, so every action was the exact HTTP endpoint the UI's own form posts to — POST /backup/offbox/run, POST /backup/offbox/restore, POST /backup/offbox/reconstitute — driven with the session cookie and the session CSRF token scraped from the page. No server logic was skipped; only rendering.

What this drill was for

Nobody had ever driven an off-site reconstitution to completion for an app whose snapshot contains only the recovery unit. The R-356 refusal always fired first. So the downstream legs — placement mapping, the stat pre-pass, CheckPlacement, the safety dump, the DB-service-only window, volReplay — had never run in that shape. This was a first-run measurement, not a confirmation.

Result: every downstream leg held. No finding was raised against them.

Phase 1 — the driveless class (privatebin, needs_hdd: false)

step what happened
plant 2 pastes created through PrivateBin's own JSON API (X-Requested-With: JSONHttpRequest) + 4 files planted directly into the app's named volume, one with a Hungarian accented name
findability control planted a control string, found it, removed it, failed to find it — 02 in the evidence dir
off-site POST /backup/offbox/run → snapshot at 11:16:34Z, 2m20s, status: ok, store 44.5 → 47.0 MB
destroy 11 files deleted outright (rm -rf, no trash) — 03-destruction.txt names every one
prepare POST /backup/offbox/restore mode=full → snapshot 306accff into /mnt/felhom-drives/hdd_1/backups/offsite-restore/privatebin
the scratch shape unit only — .../mnt/sys_drive/felhom-data/backups/primary/privatebin/ with volume-dumps/privatebin_privatebin_data.tar. The whole dataset is that one tar. This is the shape that had never been driven through.
restore POST /backup/offbox/reconstitute — no refusal. Volume replayed, app restarted, healthy.
verify 15/15 files byte-for-byte identical, diff of the two sha256 manifests is empty

The accented filename, as explicit hex bytes: c3a17276c3ad7a74c5b172c5912d74c3bc6bc3b67266c3ba72c3b367c3a9702d723335362e747874 (árvíztűrő-tükörfúrógép-r356.txt). Non-ASCII never crossed a shell chain: the planting script was base64-encoded on DooPlex and decoded inside the guest.

The customer-facing message, verbatim (160 bytes):

A(z) privatebin: 0 fájl és 1 adatkötet visszaállítva (mentés: 2026-08-22 13:14) — az alkalmazás újraindult. Ennek az alkalmazásnak nincs adatbázisa.

Judged, not merely recorded. It names the volume beside the file count, so it is not the R-354 shape wearing a new hat: a customer reading it is told what actually came back. There is no warning sitting beside a success. The one honest criticism — the first number a customer reads is 0 fájl, and for all 40 driveless apps it will always be 0 — is a wording matter, filed as an observation and not acted on here.

Phase 2 — the drive class (calibre-web, needs_hdd: true, HDD_PATH=/mnt/felhom-drives/hdd_1)

The same walk, to prove the 13-class did not move. The scratch resolved under /mnt/felhom-drives/hdd_1/... — the app's own drive, not the system data path — and the restore placed there. See 11–14 in the evidence dir.

Evidence

evidence/ holds every artefact, copied off demo-hp at the end of each phase, before any revert. Nothing was reverted or torn down during this drill, so no intermediate teardown could have taken it.

Deliberately NOT addressed here

The message that calls an empty restore a success; the delete guard on verification copies; the absence of any readability check on the off-site store (R-359). Separate rows, untouched.

Phase 2 result

3/3 files back byte for byte, accented name included (Örkény-egyperces-r356.txt, hex c396726bc3a96e792d6567797065726365732d723335362e747874). The restore placed them under /mnt/felhom-drives/hdd_1/userdata/media/books/ — the app's own drive. /mnt/sys_drive/felhom-data/userdata/media does not exist, so there was no silent misplacement onto the system disk.

Message, verbatim (161 bytes):

A(z) calibre-web: 3 fájl és 1 adatkötet visszaállítva (mentés: 2026-08-22 13:20) — az alkalmazás újraindult. Ennek az alkalmazásnak nincs adatbázisa.

No behaviour change for the 13-class was observed. That is an absence claim, so it does not stand on the live walk alone: the unit-test red-proof for it plants the system-data fallback into the drive path and three tests convict it (TestR356_ScenarioB_*, TestR356_ScenarioE_PlaceDriveApp*).