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.
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*).