diff --git a/REPORT-storage-identity-buildB-2026-10-16.md b/REPORT-storage-identity-buildB-2026-10-16.md
new file mode 100644
index 00000000..e00bbede
--- /dev/null
+++ b/REPORT-storage-identity-buildB-2026-10-16.md
@@ -0,0 +1,78 @@
+# REPORT — storage identity, build B: the one-disk data area and partitions (2026-10-15 → 16)
+
+Brief: „Storage identity, build B — the data area on one-disk boxes (D3, with the space check) and partitions as places
+(D5)". Design: `documentation/architecture/16-storage-physical-identity.md` §5–§7, §9 (§13 = what was built).
+Evidence: `documentation/audits/storage-identity-buildB-2026-10-15/` (README, SPACE-CHECK, live/). Method: endpoint level
+(no browser on DooPlex) and the VM console for the Proxmox install.
+
+## 1. The space check, as approved (operator, 2026-10-16)
+
+| Disk | Thin pool | Data volume | Reserve | Data area |
+|---|---|---|---|---|
+| 256 GB | ≈ 140 GiB | 50 GiB | 16 GiB | ≈ 42 GiB |
+| 512 GB | 349–383 GiB | 100 GiB | 35–38 GiB | ≈ 182–213 GiB |
+| 1 TB | ≈ 800 GiB | 130 GiB | 48 GiB | ≈ 590 GiB |
+| 2 TB | ≈ 1,720 GiB | 130 GiB | 48 GiB | ≈ 1,510 GiB |
+
+Measured: the heaviest box uses 18 GB of its data volume; the whole catalog needs ≈ 74 GB; a whole-box copy's snapshot used
+12 MB. A disk below ≈ 230 GB gets no data area (less than 20 GiB left).
+
+## 2. A fresh one-disk install
+
+Scratch VM on demo-hp, 512 GB disk, the public ISO, the published installer 1.33.0, customer Tester4: data volume **100 GiB**,
+data area **213 GiB**, registered as the default drive by itself. **Jellyfin installed with no extra step** (domain and
+subdomain only; on 0.314.0 the same request was refused for the missing media path). A whole-box copy holds nothing of the
+data area.
+
+## 3. Partitions — what the household can do now
+
+- See each part of a free disk; format an empty part; use a part that has a filesystem; use the free part of a disk whose
+ other part is already a drive.
+- Cannot: format a part while another part of the same disk is in use (the safety net refuses it — on purpose); create,
+ delete or resize a part (installer only, D5). An empty part still asks for the typed confirmation (R-1093).
+
+## 4. Versions and what waits on the operator
+
+| Component | Version | State |
+|---|---|---|
+| agent | 0.158.1 (0.158.0 superseded — security review) | vouched by the operator; on the three test boxes with bundle 0.158.1 (through the step bundle `0.158.1-step1`) |
+| controller | 0.318.0 | released; the global floor 0.318.0 / MinAgent 0.158.1 (set by the operator) |
+| installer | 1.33.0 | published (tag `installer-v1.33.0`, `manifests/webpage.yaml`) |
+| golden | 0.318.0 | baked by CC (`documentation/tests/golden-0.318.0-2026-10-16/`), vouched by the operator |
+
+Waits on the operator: discard the two unclaimed scratch registrations (ids 40, 41) and delete Tester4; Tester 1's dashboard
+password in the credentials file does not open Tester 1 (the checks ran on the scratch box instead); the poster drawing.
+
+## 5. Rows
+
+Rows before: 178 · after: 176 · opened 2 (R-1093, R-1094) · closed 4 (R-1068, R-1079, R-1082, R-1084).
+(Earlier in this session's build B part 1: R-1087, R-1088 opened; R-1088 was closed by another session.)
+
+## 6. Claims in the brief that were wrong
+
+1. „A one-disk scratch VM (200 GB)": under the approved sizes a 200 GB disk gets no data area (15 GiB < 20). Rebuilt at 512 GB.
+2. „Format the empty part, use the other" works only in that order: since the security review, a part next to an in-use part
+ cannot be formatted.
+3. „Run after build A is released": build A's agent was never vouched; the vouch needed a fresh golden (the hub refused
+ agent 0.158.1 next to golden 0.313.0) — CC baked golden 0.318.0 on the operator's word.
+4. The installer's design text (installer creates, agent mounts) holds, but the size rule and the only mkfs live in ONE root
+ helper from the agent's bundle, run by both the installer and the signed job — so the installer makes the area only when
+ the vouched agent carries that helper.
+
+## 7. Fixed without a row (security review of agent 0.158.0)
+
+The root mkfs wrapper briefly trusted a sibling mount the agent itself could make; the data-area helper read a failed `lvs`
+or `blkid` as „empty". Both fixed in 0.158.1, each test seen failing against 0.158.0; 0.158.0 marked „do not vouch".
+
+## 8. Documents
+
+`16` §7 (ruled sizes), §13 (build B status); capability map **D15** (PROVEN-LIVE) + detail; `OPEN-ITEMS` / `CLOSED-ITEMS`;
+`STATUS`; the OMV guide's second-disk line; the backup page (HU + EN); **system poster: facts file updated, drawing needs a
+refresh** (line added to STATUS).
+
+## 9. Teardown
+
+Machine: scratch VM 342 switched off the household way and destroyed; Tester 1's scratch disk removed. Host: helper scripts
+removed. Hub: build A's three per-customer floors cleared; two unclaimed registrations and Tester4 left for the operator.
+Secrets: the phrase, the dashboard password and the setup code lived only in private scratch files (shredded at the end);
+none in any commit (scanned).
diff --git a/STATUS.md b/STATUS.md
index 3d029e28..20e09e91 100644
--- a/STATUS.md
+++ b/STATUS.md
@@ -2,7 +2,7 @@
**Ready for the first real tester (Tester-2): yes. Tester 2 (a laptop) is off; nothing was sent to it.**
-**Updated 2026-10-15 (night).** Storage identity build A: agent 0.157.0 (not vouched yet), controller 0.317.0 and hub 0.154.0 — on the three test boxes only (per-box floors); the global floor stays 0.314.0 until you vouch the agent. Controller 0.317.0 also carries the app page in one column (a version number can now only be pushed once, and only from a clean tree); 0.314.0 is still the floor since 13:11 UTC — raised by CC with its own token after all three test boxes ran it (the first release with no golden; vouched golden 0.313.0); hub 0.153.0 (access tokens — CC uses its own token now, not your password). Open items: see `documentation/backlog/OPEN-ITEMS.md`. Older notes, day by day:
+**Updated 2026-10-16 (morning).** Storage identity build B shipped: agent 0.158.1 and golden 0.318.0 vouched by you, controller 0.318.0 is the floor (MinAgent 0.158.1), installer 1.33.0 published — new one-disk boxes get their own data area. Open items: see `documentation/backlog/OPEN-ITEMS.md`. Older notes, day by day:
`documentation/backlog/STATUS-HISTORY.md`. Reports: `REPORT-night-2026-10-14.md`, `REPORT-immich-rollout-2026-10-14.md`, `REPORT-seo-felho-tarhely-2026-10-14.md`, `REPORT-immich-repair-2026-10-14.md`, `REPORT-power-cut-fixes-2026-10-14.md`, `REPORT-night-power-2026-10-13.md`, `REPORT-poweroff.md`.
## What works
@@ -23,6 +23,7 @@
- Felhom runs in a virtual machine on OpenMediaVault 8, tried on an exact copy of the first outside tester's box: install, bind, claim, apps, backup, and back by itself after an OMV restart. The Hungarian guide for him is `documentation/pilot/GUIDE-omv-kvm-hu.md`; open: one-disk Jellyfin (R-1068), NAS films for Jellyfin (R-1071, yours), no disk health in a VM (R-1073, yours). Waits on you: send the guide; delete test customer Tester4 in the hub.
- A second local copy counts only when it is on a different physical disk, and the box can prove it. Inside a virtual machine the box makes the copy but says „A Felhom nem tudja ellenőrizni…" (Tester 1). On real disks nothing changes (demo-hp, N100). A NAS never hides the „only one copy" notice. A box with no drive refuses a media app in words, with a link to the Meghajtók page. Live on the three test boxes; the NAS and no-drive parts are unit-tested only. Next: build B (the internal place on one-disk boxes, R-1079). Your rulings D1–D6 are in the design (`architecture/16-storage-physical-identity.md`).
+- **One-disk boxes get their own data area** (2026-10-16): a new install makes a „Belső tárhely" on the disk, outside every whole-box copy, and media apps install there with no extra step (proven on a fresh 512 GB box: 213 GiB area, Jellyfin with no extra step). A disk split into parts can be used part by part. The backup offer no longer promises disk-failure safety when it cannot check the disk, and `/mnt/sys_drive` is no longer offered.
## What is broken
- Several root-level weaknesses wait on your four decisions below (R-954, R-971, R-982, R-985).
@@ -49,8 +50,9 @@
| D9 | R-1062 | The N100's USB drive is also its whole-box backup drive. Split it in two anyway? | **No — keep one drive**; the lived-in box keeps its nightly whole-box backup | Split: the box loses its local whole-box backup (or add a second drive first) | it stays one drive; multi-drive tests stay on Tester 1 | — |
## Waiting on you — do
+- **Discard two unclaimed boxes and delete Tester4** (hub, browser only): the build B scratch VMs registered as unclaimed boxes — registration ids 40 (`b43afa10…`) and 41 (`9c78ea30…`); both VMs are destroyed. Tester4 (the throwaway customer) is switched off the household way. If not: two dead entries stay in the Hosts list and Tester4 stays in Customers.
+- System poster needs a refresh: one-disk boxes now have a data area („Belső tárhely") on the system disk, outside the whole-guest backups (facts file updated 2026-10-16).
- **Olvasd el a Plex és a Sonarr útmutatót a demo-hp-n** (az alkalmazás oldalán az „Útmutató” fül). Ha más formát szeretnél, egy menetben átírom mind a 62-t. A robot 2026-10-16-án bejelentkezve megnézte: mindkét oldal megjelenik magyarul és angolul, 4 rész és a GYIK, minden sor egyezik a katalógussal. Ha nem nézed meg: csak a forma marad emberi szemmel nem látott.
-- **Vouch agent 0.157.0 and its config bundle** (hub → Configuration → Artifacts). Then CC raises the global floor to controller 0.317.0 with MinAgent 0.157.0 and clears the three per-box floors. If not: households stay on 0.314.0 and keep counting a same-disk copy as a second copy; the three test boxes keep their own floor.
- **Nézd meg az AdventureLog és a Plex oldalát a demo-hp-n, a rendes címén** (`felhom.enkisfelhom.hu`). A túl nagy keret javítva: a tartalom most 32 képpontra van a bal oszloptól és 36-ra a tetejétől (előtte 80 és 64 volt). Az alkalmazás oldala mostantól egy hasábban van: egy szélesség, vékony vonalak a szakaszok között, aláhúzott fül, és doboz csak ott, ahol az alkalmazás vár rád (kék) vagy ahol valami kockázatos (sárga). A „sikeres frissítés" sáv kis szürke sorrá vált a név alatt. Ha nem nézed meg: a felület él, csak senki nem látta még böngészőben.
- **Nézd meg az új alkalmazás oldalt a demo-hp-n (egy telepített és egy nem telepített app).** Egy alkalmazás mostantól egy oldal négy füllel (Beállítások · Adatok és mentés · Útmutató · Napló), az Indítás/Újraindítás/Leállítás a „Működés" kártyán van, és a „Vissza" az alkalmazáshoz visz, nem a listához. Mondd meg, jó-e így az elrendezés. Ha nem nézed meg: a felület él, csak senki nem látta még böngészőben — a robot a DooPlexen nem tud kattintani.
- **The N100 sheet (about 30 minutes):** `documentation/audits/n100-lived-in-2026-10-15/SHEET.md` — install Plex and claim it, make the admins in Prowlarr/Sonarr/Radarr, add your download sources in Prowlarr, add one show and one film. Then say „done". If not: the media apps wait, safe behind their gate.
diff --git a/documentation/architecture/00-capability-map.md b/documentation/architecture/00-capability-map.md
index 4dd91559..2a05cffd 100644
--- a/documentation/architecture/00-capability-map.md
+++ b/documentation/architecture/00-capability-map.md
@@ -180,6 +180,7 @@
| [D12](capability-map-detail/D.md#d12) | Boot ordering: automount + networking survive reboot; appliance self-heal watchdog | agent v0.85 | **PROVEN-LIVE** | — | `audits/CAMPAIGN-4-2026-07-13.md` (2026-07-13); `audits/CAMPAIGN-6A-2026-07-14.md` (2026-07-14) |
| [D13](capability-map-detail/D.md#d13) | Media apps see EVERY drive; a drive added, pulled, back or safely removed is handled per app (notice, real restart, wiring, torrents paused/resumed) | controller v0.313.0, catalog `0188430`, hub v0.151.0 | **PROVEN-LIVE** | Tier-0 boxes (Tester 1, demo-hp 9201); the fleet with golden 0.313.0 + the floor | `audits/media-build-2026-10-15/G/` (2026-10-15); `audits/media-drive-events-2026-10-14/` (2026-10-14) |
| [D14](capability-map-detail/D.md#d14) | A second local copy COUNTS only on a proven different physical disk: the agent knows each place's disks; a VM box makes the copy but says it cannot check; a same-disk copy is not made; a NAS never hides the one-copy notice; a box with no drive refuses a data-folder app in words | agent v0.157.0, controller v0.317.0, hub v0.154.0 | **PARTIAL** | live: VM `unknown` (Tester 1) and two real-disk boxes `proven` (demo-hp, N100); unit only: the same-disk skip, the NAS notice, the no-drive sentence; `usb_bridge` never seen on a device | `audits/storage-identity-buildA-2026-10-15/README.md` (2026-10-15); `architecture/16-storage-physical-identity.md` §13 |
+| [D15](capability-map-detail/D.md#d15) | A one-disk box gets its own data area („Belső tárhely") outside every whole-box copy, registered as the default drive with no press, so media and data-folder apps install with no extra step; a free disk's partitions can be formatted or used one by one | installer 1.33.0, agent v0.158.1, controller v0.318.0, golden 0.318.0 | **PROVEN-LIVE** | fresh 512 GB one-disk VM on demo-hp; partitions on a scratch disk; the old-box signed job and the D4 sentence unit-proven only; an empty part asks for confirmation (R-1093) | `audits/storage-identity-buildB-2026-10-15/README.md` (2026-10-16) |
## E. Access, networking & household use
diff --git a/documentation/architecture/16-storage-physical-identity.md b/documentation/architecture/16-storage-physical-identity.md
index 2c93f979..cc141cb5 100644
--- a/documentation/architecture/16-storage-physical-identity.md
+++ b/documentation/architecture/16-storage-physical-identity.md
@@ -6,8 +6,8 @@
> whether two storage places sit on the same physical disk." Triggered by the OMV test (`audits/omv-vm-2026-10-15/`,
> R-1068). Spike: `audits/storage-identity-2026-10-15/` (Part B there). Marks as in `01`: **[FACT]** read in a named
> file or measured; **[DESIGN]** a proposal. **Status: ACCEPTED 2026-10-15** — the operator ruled D1–D6 as recommended (§12). **Build A shipped 2026-10-15**
-> (§3, §4, §5's D4 sentence, §8, §10); **§5's internal place, §6 and §7 wait for build B** — what is built, and where the
-> build differs from this text, is §13.
+> (§3, §4, §5's D4 sentence, §8, §10); **build B shipped 2026-10-16** (§5's internal place, §6, §7, §9) — what is built,
+> and where the build differs from this text, is §13.
> Paths: A = `felhom-agent/`, C = `felhom-controller/controller/`, E = `felhom.eu/`.
## 1. Today, in one table (Part A)
@@ -216,5 +216,25 @@ fields) · website and guides (the OMV guide's second-disk line; the backup expl
- An older agent (no same-disk call): the controller keeps the pre-build `st_dev` rule and logs it once.
- §11 rejects `sys_drive` for household data, but the drives page still offers `/mnt/sys_drive` to attach (R-280) — R-1082.
-**Build B — waits:** §5's internal place, §6 partitions, §7 the installer (and the D3 space check the operator asked for).
+**Build B — the internal place, partitions, the installer (2026-10-16)** (agent v0.158.1 — v0.158.0 superseded; controller
+v0.318.0; installer 1.33.0; evidence `audits/storage-identity-buildB-2026-10-15/`; the D3 space check: its `SPACE-CHECK.md`,
+sizes ruled above in §7):
+
+| Section | Built | Where it differs from the text above |
+|---|---|---|
+| §5 internal place | the root helper `felhom-internal-place` (bundle) makes `pve/felhom-belso` by the ruled rule; the installer's step 5b (appliance only) and the signed `add_internal_place` (an old box) run it; the agent mounts it at `/mnt/belso` like a drive (kind `internal`); the controller binds and registers it as the default drive | the place is made only in **appliance** mode (a byo host's pool is the owner's); every failing read in the helper refuses (security review of 0.158.0) |
+| §6 partitions | each part of a free disk is listed (empty / filesystem / in_use); „format this part", „use this part"; a data-bearing part's wipe id binds disk id + part number + fs-UUID | the „filesystem with no files" state is folded into `filesystem` (no root read-only mount; the typed confirmation covers both). **A part can be formatted only while nothing on its disk is mounted**: the root mkfs wrapper refuses any mounted node and deliberately trusts no „it is Felhom's own drive" claim (the agent could fake it — security review of 0.158.0). So a household formats its free parts before using any part; a free part next to an in-use drive can still be USED, not formatted |
+| §7 installer | `step_grows` by the ruled table; step 5b | the host root is left as Proxmox makes it (SPACE-CHECK §3) |
+| §9 old boxes | the signed `add_internal_place` (no parameters; the size is the rule's) | — |
+
+**Proven live 2026-10-16** (`audits/storage-identity-buildB-2026-10-15/README.md`): a fresh one-disk install (512 GB VM,
+the public installer 1.33.0, agent 0.158.1 and golden 0.318.0 vouched) → data volume 100 GiB, internal place 213 GiB,
+registered as the default drive with no press; Jellyfin installed with no extra step onto it; a whole-box copy holds nothing
+of it; partitions formatted and used through the wizard; the honest backup offer on a VM. **Not as written:** an empty part
+asks for the typed confirmation (the probe reads the parent's partition table — R-1093); a 200 GB disk gets no internal
+place under the ruled sizes (15 GiB < 20).
+
+Also in build B: R-1084 (the whole-box backup offer asks the same-disk question) and R-1082 (`/mnt/sys_drive` is never
+offered to attach, by device). A bundle that adds a path needs a step bundle on boxes with an older wrapper (R16, R-880):
+0.158.1 was delivered through `0.158.1-step1`.
diff --git a/documentation/architecture/capability-map-detail/D.md b/documentation/architecture/capability-map-detail/D.md
index fbee7e74..6ede0e7b 100644
--- a/documentation/architecture/capability-map-detail/D.md
+++ b/documentation/architecture/capability-map-detail/D.md
@@ -268,3 +268,29 @@ the installer (R-1079).
---
+
+## D15 — The one-disk box's own data area; partitions as places
+
+*Map row: [D15](../00-capability-map.md#d15) · added 2026-10-16.*
+
+**Scenario:** a household with one disk installs a media app and expects it to work with no extra step — and expects its
+films not to fill every whole-box copy. A household with a split disk wants to use the free part without wiping the rest.
+
+**Components:** installer 1.33.0 (step 3 sizes the data volume by the ruled table; step 5b runs the bundle's root helper
+`felhom-internal-place`), agent v0.158.1 (mounts the place like a drive, kind `internal`; lists partitions; the signed
+`add_internal_place` for an old box), controller v0.318.0 (binds and registers it as the default drive; the partition
+wizard). Design: `architecture/16-storage-physical-identity.md` §5–§7, §9, §13; sizes: `audits/storage-identity-buildB-2026-10-15/SPACE-CHECK.md`.
+
+**Status:** **PROVEN-LIVE** (2026-10-16) on a fresh 512 GB one-disk VM from the public ISO and installer: data volume 100 GiB,
+data area 213 GiB, registered as the default drive with no press, Jellyfin installed with no extra step onto it, a whole-box
+copy holds nothing of it; partitions formatted and used through the wizard; formatting the whole disk under a used part
+refused in words.
+
+**Unit only:** the old-box signed job (no box with ≥ 20 GiB free thin space was at hand), the D4 sentence (R-1068's other
+half). **Known gaps:** an empty part asks for the typed confirmation (R-1093); the whole-disk refusal sentence (R-1094); a
+part next to a mounted part can only be used, not formatted (the root wrapper trusts no „Felhom's own" claim, `16` §13).
+
+**Evidence:** `audits/storage-identity-buildB-2026-10-15/README.md`.
+
+---
+
diff --git a/documentation/architecture/felhom-system-poster.facts.md b/documentation/architecture/felhom-system-poster.facts.md
index ab9bb382..82c015eb 100644
--- a/documentation/architecture/felhom-system-poster.facts.md
+++ b/documentation/architecture/felhom-system-poster.facts.md
@@ -66,6 +66,9 @@ Inside, from bottom to top:
- the **system disk** (Proxmox + the guest),
- **data drive 1** (household data and the **Tier-1** backup folder),
- an optional **data drive 2** (the **Tier-2** copy).
+ - on a **one-disk box**, the **data area** („Belső tárhely", installer 1.33.0) — a part of the system disk the box uses as
+ data drive 1; it is **not** in the whole-guest backups, and a copy between it and the system data is never counted as a
+ second copy (it is the same disk).
Note on the drawing: the data drives are attached to the guest from the host; the **whole-guest backups do not include the data drives** (that is what the per-app tiers are for).
Arrows out of the box:
diff --git a/documentation/audits/storage-identity-buildB-2026-10-15/README.md b/documentation/audits/storage-identity-buildB-2026-10-15/README.md
new file mode 100644
index 00000000..d0ac5cae
--- /dev/null
+++ b/documentation/audits/storage-identity-buildB-2026-10-15/README.md
@@ -0,0 +1,47 @@
+# Storage identity, build B — live evidence (2026-10-16)
+
+Design: `architecture/16-storage-physical-identity.md` §5–§7, §9 (§13 = what was built). Releases: agent v0.158.1
+(v0.158.0 superseded by a security review), controller v0.318.0, installer 1.33.0 (published), golden 0.318.0
+(`documentation/tests/golden-0.318.0-2026-10-16/`). The operator vouched agent 0.158.1 + golden 0.318.0 and raised the
+global floor to 0.318.0 / MinAgent 0.158.1.
+
+**Method:** endpoint level (no browser on DooPlex) — the dashboard requests the pages make (`/api/stacks//deploy`,
+`/api/storage/init`, `/api/storage/attach`, `/api/disks/candidates`, `/backups`, `/claim`, `/api/server/poweroff`), the agent's
+local API with the guest's own token (`/disks`, `/disks/candidates`, `/disks/same-disk`, `/backup`), the VM console
+(screendumps) for the Proxmox install. Times are UTC.
+
+## Part 1 — the D3 space check
+
+`SPACE-CHECK.md` + `space/` — ruled by the operator 2026-10-16: data volume 50/100/130 GiB, reserve max(16 GiB, 10 %) ≤ 48 GiB.
+
+## Part 2 — live
+
+| What | Result | File |
+|---|---|---|
+| A fresh one-disk install (scratch VM 342 on demo-hp, **512 GB** disk, ISO 1.29.0, the public installer 1.33.0, customer Tester4) | pool 383 GiB → data volume **100 GiB**, internal place **created, 213 GiB**; day-0 SUCCESS in 3 min | `05-vm342-create.txt`, `07-fresh-install.log` |
+| The agent mounts it, the controller registers it | `/mnt/belso` (by fs-UUID) → bound at `/mnt/felhom-drives/belso`; the guest config has no mount point for it; controller 0.318.0: „registered /mnt/felhom-drives/belso (default=true)" | `15-box-logs.txt` |
+| Jellyfin with no extra step | deploy with DOMAIN + SUBDOMAIN only → **202**, healthy in 30 s, `/media` = `/mnt/felhom-drives/belso/userdata/media` (the OMV run on 0.314.0: 400 „HDD_PATH … kötelező") | `08-jellyfin-deploy.txt` |
+| Not in the whole-box copy | a 64 MB marker in the place → 0 entries in the archive (control: 29,512 `var/lib/felhom/docker` entries); vzdump „excluding bind mount point mp8" | `09-…` |
+| The place is the system disk | same-disk internal vs sys_drive: **same disk, proven** (kind internal, `unknown/vm` — a VM; build A never counts such a copy) | `10-…` |
+| R-1082 | the attach list is empty while the controller's own mount table holds `/mnt/sys_drive` (0.314.0 offered it) | `10-…` |
+| Partitions (a 16 GB scratch disk, two parts, part 2 ext4) | both listed, formattable; part 1 formatted + registered (`/mnt/felhom-drives/resz1`); then nothing of the disk is offered for formatting, part 2 offered for USE only and attached (`resz2`); same-disk part 1 vs part 2: **same disk, proven**; formatting the whole disk: **409** in words | `11-`…`14-` |
+| R-1084 | the offer on a VM: „Ezt a meghajtót kijelölheted a rendszermentés helyéül. A Felhom nem tudja ellenőrizni … ezért nem ígérhetjük, hogy egy lemezhiba után is vissza tudod állítani a rendszert." | `14-…` |
+| Delivery to the three test boxes | Tester 1, demo-hp, N100: agent 0.158.1 + bundle 0.158.1 (through the step bundle `0.158.1-step1`), controller 0.318.0 by the floor | — |
+
+## Not as the design said (filed or recorded)
+
+- **An empty part asks for the typed confirmation** („device has a partition table"): `lsblk` reports the parent disk's table
+ for a partition, so the agent's probe reads an empty part as data-bearing. Safe direction, wrong friction → R-1093.
+- **The whole-disk refusal sentence** ends „Csak a szabad részét formázhatod" — not true while another part is mounted (the
+ free part can then only be used) → R-1094.
+- **A 200 GB disk gets no internal place** under the ruled sizes (pool 113 → 113 − 16 − 82 = 15 GiB < 20); the brief's
+ 200 GB VM could not show it, so the VM was rebuilt with 512 GB (`05-…`).
+- **Tester 1's dashboard password in the restored credentials file does not open Tester 1** — the dashboard checks ran on the
+ Tester4 scratch box instead (also a VM, same shape).
+
+## Teardown
+
+Machine: VM 342 switched off the household way (`/api/server/poweroff`, alarms held) and destroyed; Tester 1's 16 GB scratch
+disk unlinked and deleted. Host: the helper `agentq.sh` removed from Tester 1's host (VM 342 is gone with its copy). Hub: the
+three per-customer floors of build A cleared (303 `floor_set`); Tester4's host is off — the operator deletes the throwaway
+customer. Secrets: scan of this folder for the phrase, the dashboard password, the setup code and the token prefix = none.
diff --git a/documentation/audits/storage-identity-buildB-2026-10-15/live/01-scratch-disk.txt b/documentation/audits/storage-identity-buildB-2026-10-15/live/01-scratch-disk.txt
new file mode 100644
index 00000000..7309b199
--- /dev/null
+++ b/documentation/audits/storage-identity-buildB-2026-10-15/live/01-scratch-disk.txt
@@ -0,0 +1,8 @@
+## 2026-10-16T02:11:42Z add a 16G scratch disk to Tester 1 (VM 341 on demo-hp)
+Formatting '/mnt/hdd_1/images/341/vm-341-disk-7.raw', fmt=raw size=17179869184 preallocation=off
+scsi6: successfully created disk 'nvme-scratch:341/vm-341-disk-7.raw,backup=0,size=16G'
+scsi6: nvme-scratch:341/vm-341-disk-7.raw,backup=0,size=16G
+## inside Tester 1 host
+sde 50G drive-scsi4
+sdf 20G drive-scsi5
+sdg 16G drive-scsi6
diff --git a/documentation/audits/storage-identity-buildB-2026-10-15/live/02-two-parts.txt b/documentation/audits/storage-identity-buildB-2026-10-15/live/02-two-parts.txt
new file mode 100644
index 00000000..4beb1bdc
--- /dev/null
+++ b/documentation/audits/storage-identity-buildB-2026-10-15/live/02-two-parts.txt
@@ -0,0 +1,10 @@
+blkid rc=2 (2 = nothing on it)
+bash: line 1: parted: command not found
+blkid rc=2 (2 = nothing on it)
+NAME SIZE FSTYPE LABEL MOUNTPOINT
+sdg 16G
+|-sdg1 8G
+`-sdg2 8G ext4 scratchp2
+scsi-0QEMU_QEMU_HARDDISK_drive-scsi6 ../../sdg
+scsi-0QEMU_QEMU_HARDDISK_drive-scsi6-part1 ../../sdg1
+scsi-0QEMU_QEMU_HARDDISK_drive-scsi6-part2 ../../sdg2
diff --git a/documentation/audits/storage-identity-buildB-2026-10-15/live/03-tester1-rc2.txt b/documentation/audits/storage-identity-buildB-2026-10-15/live/03-tester1-rc2.txt
new file mode 100644
index 00000000..75738ba8
--- /dev/null
+++ b/documentation/audits/storage-identity-buildB-2026-10-15/live/03-tester1-rc2.txt
@@ -0,0 +1,2 @@
+gitea.dooplex.hu/admin/felhom-controller:0.317.0
+gitea.dooplex.hu/admin/felhom-controller:0.318.0-rc.2 Up 25 seconds (healthy)
diff --git a/documentation/audits/storage-identity-buildB-2026-10-15/live/04-agent-partitions.txt b/documentation/audits/storage-identity-buildB-2026-10-15/live/04-agent-partitions.txt
new file mode 100644
index 00000000..5acb8c91
--- /dev/null
+++ b/documentation/audits/storage-identity-buildB-2026-10-15/live/04-agent-partitions.txt
@@ -0,0 +1,6 @@
+initialize /dev/sdg data_bearing=True
+ /dev/sdg1 empty fs= mountable=False formattable=True
+ /dev/sdg2 filesystem fs=ext4 mountable=True formattable=True uuid:ae2bd22b-3dc9-4be0-a713-c192b8d307a0
+attach /dev/sdg data_bearing=True
+ /dev/sdg1 empty fs= mountable=False formattable=True
+ /dev/sdg2 filesystem fs=ext4 mountable=True formattable=True uuid:ae2bd22b-3dc9-4be0-a713-c192b8d307a0
diff --git a/documentation/audits/storage-identity-buildB-2026-10-15/live/05-vm342-create.txt b/documentation/audits/storage-identity-buildB-2026-10-15/live/05-vm342-create.txt
new file mode 100644
index 00000000..6a5265f9
--- /dev/null
+++ b/documentation/audits/storage-identity-buildB-2026-10-15/live/05-vm342-create.txt
@@ -0,0 +1,22 @@
+Formatting '/mnt/hdd_1/images/342/vm-342-disk-0.raw', fmt=raw size=214748364800 preallocation=off
+scsi0: successfully created disk 'nvme-scratch:342/vm-342-disk-0.raw,size=200G'
+update VM 342: -boot order=scsi0;ide2
+boot: order=scsi0;ide2
+cores: 4
+ide2: local:iso/felhom-installer-1.29.0-pve9.2-1.iso,media=cdrom,size=1665356K
+memory: 8192
+net0: virtio=BC:24:11:DE:A6:46,bridge=vmbr0
+scsi0: nvme-scratch:342/vm-342-disk-0.raw,size=200G
+status: running
+2026-10-16T06:47:25Z PVE install pressed on VM 342 (ISO 1.29.0, /dev/sda 200G, ext4, PVE default layout)
+## 2026-10-16T07:14:34Z VM 342 (200 GB) removed: with the ruled sizes a 200 GB disk gives only ~15 GiB for the data area (< 20 GiB) — rebuilt with 512 GB
+name: buildb-onedisk
+scsi0: nvme-scratch:342/vm-342-disk-0.raw,size=200G
+purging VM 342 from related configurations..
+scsi0: successfully created disk 'nvme-scratch:342/vm-342-disk-0.raw,size=512G'
+update VM 342: -boot order=scsi0;ide2
+boot: order=scsi0;ide2
+net0: virtio=BC:24:11:B7:71:A8,bridge=vmbr0
+scsi0: nvme-scratch:342/vm-342-disk-0.raw,size=512G
+status: running
+2026-10-16T07:17:30Z PVE install pressed on VM 342 (ISO 1.29.0, /dev/sda 512G, ext4, PVE default layout)
diff --git a/documentation/audits/storage-identity-buildB-2026-10-15/live/06-per-customer-floors-cleared.txt b/documentation/audits/storage-identity-buildB-2026-10-15/live/06-per-customer-floors-cleared.txt
new file mode 100644
index 00000000..3da2082a
--- /dev/null
+++ b/documentation/audits/storage-identity-buildB-2026-10-15/live/06-per-customer-floors-cleared.txt
@@ -0,0 +1,3 @@
+07:38:44 tester-1 cleared: HTTP/1.1 303 See Other Location: /customers/tester-1?flash=floor_set
+07:38:44 demo-hp cleared: HTTP/1.1 303 See Other Location: /customers/demo-hp?flash=floor_set
+07:38:44 demo-felhom cleared: HTTP/1.1 303 See Other Location: /customers/demo-felhom?flash=floor_set
diff --git a/documentation/audits/storage-identity-buildB-2026-10-15/live/07-fresh-install.log b/documentation/audits/storage-identity-buildB-2026-10-15/live/07-fresh-install.log
new file mode 100644
index 00000000..23454b0a
--- /dev/null
+++ b/documentation/audits/storage-identity-buildB-2026-10-15/live/07-fresh-install.log
@@ -0,0 +1,147 @@
+[INFO] auto-sized guest RAM: 4096 MiB (host 7939 MiB; clamp(host-4096, min 4096, max host-2048), ceiling host-1024)
+[INFO] auto-sized guest cores: 3 (host 4 cores; host-1, min 2)
+
+[INFO] felhom-host-install v1.33.0 — mode=appliance customer=Tester4 vmid=9201
+
+[STEP] 1/8 pre-flight
+[INFO] pve-manager/9.2.2/b9984c6d90a4bd80 (running kernel: 7.0.2-6-pve)
+[INFO] node: buildb (auto)
+[INFO] agent config: /etc/felhom-agent/agent.json
+[INFO] agent: not installed yet — will be fetched + installed in step 5/8
+[INFO] local-lvm free: ~383 GiB
+[INFO] free RAM: ~6365 MiB
+[INFO] existing guests on this host: 0 (pct+qm)
+[INFO] archive storage 'local' present
+[INFO] acl storage 'felhom-pbs' not present yet — expected: the PBS-DR tier creates it; the grant is pre-positioned deliberately
+[INFO] dnsmasq: not present before Felhom — recorded; uninstall will remove it again if we install it
+[INFO] hub reachable (https://hub.felhom.eu)
+[OK] customer 'Tester4' exists + passphrase valid
+[INFO] golden: none local — will fetch + verify from Gitea in step 7/8
+[OK] pre-flight passed
+[STEP] 2/8 Proxmox API token
+[OK] token minted (secret captured, not logged)
+[OK] scoped ACL applied (Base@/, Guest@/pool/felhom + /vms/990000..990009, Store@[local local-lvm felhom-pbs])
+[SKIP] old broad role FelhomAgent already absent
+[STEP] 3/8 compute volume grows
+[INFO] auto-computed from a 383 GiB thin pool (16 §7: 50/100/130 GiB)
+[INFO] grows: rootfs +0G (->32G), data +76G (->100G, ONE volume)
+[STEP] 4/8 host enrollment (POST /host-enroll)
+[OK] host REUSED (idempotent — existing credential)
+[INFO] host_id: Tester4-68d1d8 (api_key captured, not logged)
+[STEP] 4b/8 break-glass credential (root@pam console password → hub vault)
+[OK] root@pam password set + vaulted to the hub (retrieve via the operator /admin path; never logged here)
+[WARN] NOTE: the root@pam password just CHANGED — the old one now fails at the PVE web GUI (:8006).
+[WARN] Retrieve the new one at hub → host page (vaulted recovery credential).
+[STEP] 5/8 agent install (fetch + verify + install)
+[INFO] disabled pve-enterprise.sources (Enabled: no)
+[INFO] disabled ceph.sources (Enabled: no)
+[INFO] added pve-no-subscription.sources (suite=trixie)
+[OK] apt repos aligned to no-subscription (changed; apt-get update OK)
+[WARN] no git credential in controller.yaml — fetching artifacts ANONYMOUSLY (they are world-readable; sha256 verification unchanged)
+[INFO] manifest: agent v0.158.1 (sha 20264df64ef646a8…), golden v0.318.0
+[INFO] fetching agent binary v0.158.1 from Gitea …
+[OK] verified sha256 20264df64ef646a8… matches the hub manifest
+[OK] installed /usr/local/bin/felhom-agent (felhom-agent 0.158.1)
+[INFO] installing the 'sudo' package (required for the non-root agent model) …
+[OK] sudo installed (Sudo version 1.9.16p2)
+[INFO] installing the 'age' package (escrow ceremony identity-wrap dependency) …
+[OK] age installed (1.2.1)
+[OK] created service user felhom-agent
+[OK] added felhom-agent to systemd-journal (unprivileged journal read for NAS verify)
+[OK] verified sha256 c23c3d355fe70a6f… matches the hub manifest
+ os-apply: BUNDLE START agent=0.158.1 sha=c23c3d355fe70a6f authority=installer files=30 write=29 same=1 kept=0 skipped=0
+ os-apply: BUNDLE WROTE /usr/local/sbin/felhom-mkfs-guarded (new)
+ os-apply: BUNDLE WROTE /usr/local/sbin/felhom-selfupdate-guarded (new)
+ os-apply: BUNDLE WROTE /usr/local/sbin/felhom-pbs-apply (new)
+ os-apply: BUNDLE WROTE /usr/local/sbin/felhom-backup-target-apply (new)
+ os-apply: BUNDLE WROTE /usr/local/sbin/felhom-vzdump-partial-clean (new)
+ os-apply: BUNDLE WROTE /usr/local/sbin/felhom-internal-place (new)
+ os-apply: BUNDLE WROTE /usr/local/sbin/felhom-crash-guard (new)
+ os-apply: BUNDLE WROTE /usr/local/sbin/felhom-priv-apply (new)
+ os-apply: BUNDLE WROTE /var/lib/vz/snippets/felhom-guest-hook.sh (new)
+ os-apply: BUNDLE WROTE /usr/local/sbin/felhom-shared-parent.sh (new)
+ os-apply: BUNDLE WROTE /etc/systemd/system/felhom-shared-parent.service (new)
+ os-apply: BUNDLE WROTE /etc/systemd/system/felhom-crash-guard.service (new)
+ os-apply: BUNDLE WROTE /etc/systemd/system/felhom-crash-guard-check.service (new)
+ os-apply: BUNDLE WROTE /etc/systemd/system/felhom-crash-guard-check.timer (new)
+ os-apply: BUNDLE WROTE /etc/felhom/crash-guard.conf (new)
+ os-apply: BUNDLE WROTE /etc/grub.d/01_felhom_oneshot (new)
+ os-apply: BUNDLE WROTE /etc/grub.d/42_felhom_oneshot (new)
+ os-apply: BUNDLE WROTE /etc/systemd/system/felhom-agent.service (new)
+ os-apply: BUNDLE WROTE /etc/systemd/system/felhom-agent-rollback.service (new)
+ os-apply: BUNDLE WROTE /etc/systemd/system/felhom-agent.service.d/felhom-agent-limits.conf (new)
+ os-apply: BUNDLE WROTE /usr/local/sbin/felhom-mgmt-watchdog (new)
+ os-apply: BUNDLE WROTE /etc/tmpfiles.d/felhom-privsep.conf (new)
+ os-apply: BUNDLE WROTE /etc/systemd/system/felhom-mgmt-watchdog.service (new)
+ os-apply: BUNDLE WROTE /etc/systemd/system/felhom-mgmt-watchdog.timer (new)
+ os-apply: BUNDLE WROTE /etc/systemd/system/felhom-sshd.service (new)
+ os-apply: BUNDLE WROTE /etc/felhom-oob.nft (new)
+ os-apply: BUNDLE WROTE /etc/systemd/system/felhom-oob-nft.service (new)
+ os-apply: BUNDLE WROTE /etc/sudoers.d/felhom-op (new)
+ os-apply: BUNDLE WROTE /etc/sudoers.d/felhom-agent (new)
+ os-apply: BUNDLE DONE agent=0.158.1 written=29 same=1 self-check=ok signers-created=False
+[OK] installed every root-owned file from config bundle v0.158.1 (sha c23c3d355fe70a6f…; checked, previous copies kept)
+[OK] OOB felhom-sshd instance + static belt from the bundle (agent renders config + fills sets once oob.enabled)
+[STEP] 5b/8 internal data place (Belső tárhely)
+[OK] internal place: created, 213 GiB (the agent mounts it at /mnt/belso)
+[STEP] 6/8 agent config + service
+[WARN] backup target: DEGRADED — no eligible second drive, so the whole-system backup stays on the SYSTEM drive.
+[WARN] It protects against file corruption but NOT against a disk failure. Attach a second drive and assign it in the dashboard.
+[INFO] creating island bridge vmbr9 (portless, 169.254.253.1/30)
+[OK] vmbr9 up: 169.254.253.1/30
+[INFO] R-50 island ON: local_api=169.254.253.1:8443 (vmbr9); guest net1=169.254.253.2/30; lan_resolver.host_ip=192.168.0.118
+[INFO] node=buildb local_api=169.254.253.1:8443 tls_fp=77:14:E0:5D:21:B0…
+[OK] wrote /etc/felhom-agent/agent.json (0600 felhom-agent)
+[OK] agent --selftest (read-only) passed
+[OK] felhom-agent service active (non-root felhom-agent reads the config OK)
+[OK] wrote /etc/felhom/os-trust.json + operator-signers (felhom-op-1) — the root-owned slow-lane anchors
+[STEP] 7/8 golden archive
+[WARN] no git credential in controller.yaml — fetching artifacts ANONYMOUSLY (they are world-readable; sha256 verification unchanged)
+[INFO] fetching golden v0.318.0 from Gitea → /var/lib/vz/dump/vzdump-lxc-9100-2026_10_16-09_45_36.tar.zst
+[OK] verified sha256 18077b6a689a06f3… matches the hub manifest
+[OK] golden imported + verified: local:backup/vzdump-lxc-9100-2026_10_16-09_45_36.tar.zst
+[STEP] 8/8 provision guest 9201
+[SKIP] pool felhom already exists
+=== felhom-agent 0.158.1 selftest=provision (vmid=9201 customer=Tester4 hostname=tester4) ===
+ --- front half: bring-up (provision) local:backup/vzdump-lxc-9100-2026_10_16-09_45_36.tar.zst → vmid 9201 ---
+time=2026-10-16T09:46:34.045+02:00 level=INFO msg="bring-up: pool membership re-asserted" vmid=9201 pool=felhom
+ [OK] front half: vmid 9201 up (boot+running) in 49s; MAC=BC:24:11:F9:27:7E
+ --- back half: mint per-guest token + populate bootstrap config mount ---
+time=2026-10-16T09:46:39.169+02:00 level=INFO msg="provision: back-half complete" vmid=9201 mount=mp9 guest_path=/etc/felhom-bootstrap endpoint=169.254.253.1:8443
+ [OK] back half: bootstrap mount mp9 → /etc/felhom-bootstrap on vmid 9201 (host dir /var/lib/felhom-agent/guests/9201/bootstrap)
+ local-api endpoint 169.254.253.1:8443 · leaf fp ae0761dd4b8aa39a50ce43d350dfe1162a75b66f13494241cb681ee92ebf99e7 · token: minted (not printed)
+=== selftest=provision OK — guest 9201 provisioned + bootstrap-mounted (KEPT) ===
+ next: reboot the guest → the golden's baked controller-bootstrap unit deploys the controller,
+ which PULLS its controller.yaml from the hub (retrieval passphrase) and merges in this local_api.
+[OK] provision completed
+[INFO] rebooting guest 9201 so the baked controller-bootstrap unit picks up the mount
+[STEP] verify
+[OK] pct status: running
+[OK] onboot: 1
+ mp0: local-lvm:vm-9201-disk-1,mp=/var/lib/felhom,backup=1,size=100G
+ mp8: /mnt/felhom-drives,mp=/mnt/felhom-drives
+ rootfs: local-lvm:vm-9201-disk-0,size=32G
+[OK] pool: guest 9201 is a member of felhom
+[OK] acl: FelhomAgentBase@/ present (user+token)
+[OK] acl: FelhomAgentGuest@/pool/felhom present (user+token)
+[OK] acl: FelhomAgentStore@/storage/local present (user+token)
+[OK] acl: FelhomAgentStore@/storage/local-lvm present (user+token)
+[OK] acl: FelhomAgentStore@/storage/felhom-pbs present (user+token)
+[OK] acl: FelhomAgentGuest@/vms/990000 present (user+token)
+[OK] acl: FelhomAgentGuest@/vms/990001 present (user+token)
+[OK] acl: FelhomAgentGuest@/vms/990002 present (user+token)
+[OK] acl: FelhomAgentGuest@/vms/990003 present (user+token)
+[OK] acl: FelhomAgentGuest@/vms/990004 present (user+token)
+[OK] acl: FelhomAgentGuest@/vms/990005 present (user+token)
+[OK] acl: FelhomAgentGuest@/vms/990006 present (user+token)
+[OK] acl: FelhomAgentGuest@/vms/990007 present (user+token)
+[OK] acl: FelhomAgentGuest@/vms/990008 present (user+token)
+[OK] acl: FelhomAgentGuest@/vms/990009 present (user+token)
+[OK] authz signers: 2 (operator-signed self-update armed)
+[OK] controller: Up 20 seconds (healthy) (after ~0s)
+[INFO] controller image: gitea.dooplex.hu/admin/felhom-controller:0.318.0
+[WARN] cloudflared not visible yet
+[INFO] (confirm in the hub UI that host Tester4-68d1d8 reports guest 9201)
+
+[OK] Day-0 provision SUCCESS — vmid=9201 host_id=Tester4-68d1d8 customer=Tester4 golden=local:backup/vzdump-lxc-9100-2026_10_16-09_45_36.tar.zst
+[INFO] root@pam was rotated + vaulted at step 4b — retrieve at hub → host page (the old GUI password no longer works).
diff --git a/documentation/audits/storage-identity-buildB-2026-10-15/live/08-jellyfin-deploy.txt b/documentation/audits/storage-identity-buildB-2026-10-15/live/08-jellyfin-deploy.txt
new file mode 100644
index 00000000..7d617def
--- /dev/null
+++ b/documentation/audits/storage-identity-buildB-2026-10-15/live/08-jellyfin-deploy.txt
@@ -0,0 +1,10 @@
+jellyfin deploy 07:49:38 — values: DOMAIN, SUBDOMAIN only (no HDD_PATH)
+{"ok":true,"message":"Telepítés elindítva – az állapot a kártyán követhető"}
+
+HTTP 202
+## 07:50:17 jellyfin: Up 17 seconds (healthy)
+/var/lib/docker/volumes/jellyfin_jellyfin_cache/_data -> /cache
+/var/lib/docker/volumes/jellyfin_jellyfin_config/_data -> /config
+/mnt/felhom-drives/belso/userdata/media -> /media
+/mnt/felhom-drives/belso/userdata/media -> /mnt/felhom-drives/belso/userdata/media
+userdata
diff --git a/documentation/audits/storage-identity-buildB-2026-10-15/live/09-wholebox-copy-excludes-place.txt b/documentation/audits/storage-identity-buildB-2026-10-15/live/09-wholebox-copy-excludes-place.txt
new file mode 100644
index 00000000..972f9a6d
--- /dev/null
+++ b/documentation/audits/storage-identity-buildB-2026-10-15/live/09-wholebox-copy-excludes-place.txt
@@ -0,0 +1,13 @@
+## whole-box copy, phase=done at 07:51:21
+archive: vzdump-lxc-9201-2026_10_16-09_50_29.tar.zst 1225 MB
+2026-10-16 09:50:29 INFO: including mount point rootfs ('/') in backup
+2026-10-16 09:50:29 INFO: including mount point mp0 ('/var/lib/felhom') in backup
+2026-10-16 09:50:29 INFO: excluding bind mount point mp8 ('/mnt/felhom-drives') from backup (not a volume)
+2026-10-16 09:50:29 INFO: excluding bind mount point mp9 ('/etc/felhom-bootstrap') from backup (not a volume)
+2026-10-16 09:51:18 INFO: archive file size: 1.20GB
+marker entries in the archive: 0
+belso entries in the archive: 2
+control — mp0 entries (must be > 0): 29512
+drwxr-xr-x 0/0 0 2026-10-16 09:49 ./var/lib/felhom/docker/overlay2/05cdeccc9f31a5095cd7da730f524ea4697bf80120ea3a15a12e09f406d77bf6/diff/mnt/felhom-drives/belso/
+drwxr-xr-x 0/0 0 2026-10-16 09:49 ./var/lib/felhom/docker/overlay2/05cdeccc9f31a5095cd7da730f524ea4697bf80120ea3a15a12e09f406d77bf6/diff/mnt/felhom-drives/belso/userdata/
+drwxr-xr-x 0/0 0 2026-10-16 09:49 ./var/lib/felhom/docker/overlay2/05cdeccc9f31a5095cd7da730f524ea4697bf80120ea3a15a12e09f406d77bf6/diff/mnt/felhom-drives/belso/userdata/media/
diff --git a/documentation/audits/storage-identity-buildB-2026-10-15/live/10-same-disk-and-r1082.txt b/documentation/audits/storage-identity-buildB-2026-10-15/live/10-same-disk-and-r1082.txt
new file mode 100644
index 00000000..2eb07b72
--- /dev/null
+++ b/documentation/audits/storage-identity-buildB-2026-10-15/live/10-same-disk-and-r1082.txt
@@ -0,0 +1,9 @@
+## 07:52:06 same-disk: the internal place vs sys_drive (agent call)
+different=False proven=True reason=same_disk | a.kind=internal a.identity=unknown ['serial:scsi:QEMU_HARDDISK:drive-scsi0'] | b.kind=system
+## GET /disks row of the internal place
+{'name': 'belso', 'mount_path': '/mnt/belso', 'guest_path': '/mnt/felhom-drives/belso', 'kind': 'internal', 'role': 'user-data', 'identity': 'unknown', 'identity_reason': 'vm', 'bound_under_parent': True}
+## R-1082: the attach list (dashboard /api/disks/candidates)
+## R-1082: the attach list (dashboard /api/disks/candidates, controller 0.318.0)
+{"data":{"vmid":9201,"initialize":[],"attach":[]},"ok":true}
+## precondition: the controller's own mount table holds /mnt/sys_drive (what 0.314.0 offered in the OMV run, audits/omv-vm-2026-10-15)
+/dev/mapper/pve-vm--9201--disk--1 /mnt/sys_drive ext4 rw,relatime,stripe=16 0 0
diff --git a/documentation/audits/storage-identity-buildB-2026-10-15/live/11-scratch-disk-vm342.txt b/documentation/audits/storage-identity-buildB-2026-10-15/live/11-scratch-disk-vm342.txt
new file mode 100644
index 00000000..a2481997
--- /dev/null
+++ b/documentation/audits/storage-identity-buildB-2026-10-15/live/11-scratch-disk-vm342.txt
@@ -0,0 +1,7 @@
+## 2026-10-16T07:52:36Z add a 16G scratch disk to VM 342
+scsi1: successfully created disk 'nvme-scratch:342/vm-342-disk-1.raw,backup=0,size=16G'
+blkid rc=2 (2 = nothing on it)
+NAME SIZE FSTYPE LABEL MOUNTPOINT
+sdb 16G
+|-sdb1 8G
+`-sdb2 8G ext4 scratchp2
diff --git a/documentation/audits/storage-identity-buildB-2026-10-15/live/12-partitions-format.txt b/documentation/audits/storage-identity-buildB-2026-10-15/live/12-partitions-format.txt
new file mode 100644
index 00000000..11319e07
--- /dev/null
+++ b/documentation/audits/storage-identity-buildB-2026-10-15/live/12-partitions-format.txt
@@ -0,0 +1,25 @@
+## 07:52:51 candidates before (dashboard /api/disks/candidates)
+initialize /dev/sdb whole_disk_in_use=False
+ /dev/sdb1 empty fs= formattable=True mountable=False
+ /dev/sdb2 filesystem fs=ext4 formattable=True mountable=True
+attach /dev/sdb whole_disk_in_use=False
+ /dev/sdb1 empty fs= formattable=True mountable=False
+ /dev/sdb2 filesystem fs=ext4 formattable=True mountable=True
+## 07:52:51 format part 1 (the wizard POST /api/storage/init)
+{"data":{"phase":"formatting","started":true},"ok":true}
+
+HTTP 200
+## 07:52:58 init status
+{"data":{"device":"/dev/sdb1","durable_id":"byid:scsi-0QEMU_QEMU_HARDDISK_drive-scsi1-part1","error":"","opsign":"","phase":"needs_confirmation","reason":"device has a partition table","started_at":"2026-10-16T07:52:51.782009734Z","updated_at":"2026-10-16T07:52:52.051700007Z","where":"/mnt/resz1"},"ok":true}
+## candidates after part 1 is a drive
+initialize /dev/sdb whole_disk_in_use=False
+ /dev/sdb1 empty fs= formattable=True mountable=False
+ /dev/sdb2 filesystem fs=ext4 formattable=True mountable=True
+attach /dev/sdb whole_disk_in_use=False
+ /dev/sdb1 empty fs= formattable=True mountable=False
+ /dev/sdb2 filesystem fs=ext4 formattable=True mountable=True
+## 07:53:13 confirmed format of part 1 (the wizard re-posts with confirmed + the durable id it was shown)
+{"data":{"phase":"formatting","started":true},"ok":true}
+
+HTTP 200
+{"data":{"device":"/dev/sdb1","durable_id":"","error":"","opsign":"","phase":"done","reason":"","started_at":"2026-10-16T07:53:13.503303783Z","updated_at":"2026-10-16T07:53:15.360607509Z","where":"/mnt/felhom-drives/resz1"},"ok":true}
diff --git a/documentation/audits/storage-identity-buildB-2026-10-15/live/13-partitions-use.txt b/documentation/audits/storage-identity-buildB-2026-10-15/live/13-partitions-use.txt
new file mode 100644
index 00000000..45f50ba6
--- /dev/null
+++ b/documentation/audits/storage-identity-buildB-2026-10-15/live/13-partitions-use.txt
@@ -0,0 +1,7 @@
+## 07:53:25 candidates with part 1 in use
+initialize: []
+attach /dev/sdb whole_disk_in_use=True [('/dev/sdb2', 'filesystem', 'formattable=False')]
+## 07:53:25 use part 2 (the wizard POST /api/storage/attach)
+{"data":{"registered":true,"where":"/mnt/felhom-drives/resz2"},"ok":true}
+
+HTTP 200
diff --git a/documentation/audits/storage-identity-buildB-2026-10-15/live/14-samedisk-refusal-offer.txt b/documentation/audits/storage-identity-buildB-2026-10-15/live/14-samedisk-refusal-offer.txt
new file mode 100644
index 00000000..936f286a
--- /dev/null
+++ b/documentation/audits/storage-identity-buildB-2026-10-15/live/14-samedisk-refusal-offer.txt
@@ -0,0 +1,9 @@
+## 07:53:38 same-disk: part 1 vs part 2 (agent call)
+different=False proven=True reason=same_disk | a.kind=partition b.kind=partition | ['serial:scsi:QEMU_HARDDISK:drive-scsi1']
+## 07:53:39 the server refuses formatting the whole disk under a registered part (POST /api/storage/init device=/dev/sdb)
+{"error":"Ezen a lemezen egy használatban lévő meghajtó van, ezért a teljes lemez nem formázható. Csak a szabad részét formázhatod.","ok":false}
+
+HTTP 409
+## 07:53:39 /backups — the whole-box backup offer
+A Felhom nem tudja ellenőrizni, hogy a második meghajtó valóban másik lemez-e (virtuális gépben és egyes USB-házakban ez nem látszik), ezért nem számolja második másolatnak.
+Ezt a meghajtót kijelölheted a rendszermentés helyéül. A Felhom nem tudja ellenőrizni, hogy ez a meghajtó valóban másik lemez-e (virtuális gépben és egyes USB-házakban ez nem látszik), ezért nem ígérhetjük, hogy egy lemezhiba után is vissza tudod állítani a rendszert.
diff --git a/documentation/audits/storage-identity-buildB-2026-10-15/live/15-box-logs.txt b/documentation/audits/storage-identity-buildB-2026-10-15/live/15-box-logs.txt
new file mode 100644
index 00000000..b3635b01
--- /dev/null
+++ b/documentation/audits/storage-identity-buildB-2026-10-15/live/15-box-logs.txt
@@ -0,0 +1,28 @@
+## agent (journal)
+Oct 16 09:45:34 buildb felhom-agent[6589]: time=2026-10-16T09:45:34.644+02:00 level=INFO msg="internal place: mounted on the host" where=/mnt/belso fs_uuid=0347cd44-d4d9-4c02-94fe-3af6789e3368 gib=213 duration_ms=954
+Oct 16 09:45:35 buildb felhom-agent[6589]: time=2026-10-16T09:45:35.837+02:00 level=INFO msg="wgtunnel: registered with hub" pubkey="NkTpVgvdFWq0cXODnqTBBDGvz2gZSd9wURYN4GnTuWk=" assigned_ip=10.77.0.6/32 existed=false generation=4 sync=ok
+Oct 16 09:45:35 buildb felhom-agent[6589]: time=2026-10-16T09:45:35.840+02:00 level=INFO msg="wgtunnel: registered with hub" pubkey="NkTpVgvdFWq0cXODnqTBBDGvz2gZSd9wURYN4GnTuWk=" assigned_ip=10.77.0.6/32 existed=true generation=4 sync=unchanged
+Oct 16 09:46:05 buildb felhom-agent[6589]: time=2026-10-16T09:46:05.422+02:00 level=INFO msg="wgtunnel: tunnel conf applied" endpoint=167.233.158.164:443 dns_name=ep0.felhom.eu assigned_ip=10.77.0.6/32 action=enable
+Oct 16 09:46:38 buildb felhom-agent[6589]: time=2026-10-16T09:46:38.331+02:00 level=INFO msg="guest-attach: drive bound under shared parent (normalized to one bind, live)" vmid=9201 where=/mnt/belso stable=/mnt/felhom-drives/belso prior_binds=0
+Oct 16 09:46:38 buildb felhom-agent[6589]: time=2026-10-16T09:46:38.786+02:00 level=INFO msg="local-api: guest-attach bound under shared parent" vmid=9201 where=/mnt/belso guest_path=/mnt/felhom-drives/belso
+Oct 16 09:46:55 buildb felhom-agent[6589]: time=2026-10-16T09:46:55.526+02:00 level=INFO msg="guest-attach: drive bound under shared parent (normalized to one bind, live)" vmid=9201 where=/mnt/belso stable=/mnt/felhom-drives/belso prior_binds=1
+Oct 16 09:47:01 buildb felhom-agent[6589]: time=2026-10-16T09:47:01.029+02:00 level=INFO msg="local-api: same-disk" vmid=9201 a=/mnt/sys_drive b=/mnt/felhom-drives/belso different=false proven=true reason=same_disk
+Oct 16 09:49:23 buildb felhom-agent[6589]: time=2026-10-16T09:49:23.794+02:00 level=INFO msg="local-api: same-disk" vmid=9201 a=/mnt/sys_drive b=/mnt/felhom-drives/belso different=false proven=true reason=same_disk
+Oct 16 09:49:41 buildb felhom-agent[6589]: time=2026-10-16T09:49:41.555+02:00 level=INFO msg="local-api: same-disk" vmid=9201 a=/mnt/sys_drive b=/mnt/felhom-drives/belso different=false proven=true reason=same_disk
+Oct 16 09:52:07 buildb felhom-agent[6589]: time=2026-10-16T09:52:07.593+02:00 level=INFO msg="local-api: same-disk" vmid=9201 a=/mnt/felhom-drives/belso/userdata b=/mnt/sys_drive different=false proven=true reason=same_disk
+Oct 16 09:53:14 buildb felhom-agent[6589]: time=2026-10-16T09:53:14.891+02:00 level=INFO msg="local-api: disk assigned (host mount ensured)" vmid=9201 where=/mnt/resz1
+Oct 16 09:53:14 buildb felhom-agent[6589]: time=2026-10-16T09:53:14.962+02:00 level=INFO msg="guest-attach: drive bound under shared parent (normalized to one bind, live)" vmid=9201 where=/mnt/resz1 stable=/mnt/felhom-drives/resz1 prior_binds=0
+Oct 16 09:53:15 buildb felhom-agent[6589]: time=2026-10-16T09:53:15.333+02:00 level=INFO msg="local-api: guest-attach bound under shared parent" vmid=9201 where=/mnt/resz1 guest_path=/mnt/felhom-drives/resz1
+Oct 16 09:53:27 buildb felhom-agent[6589]: time=2026-10-16T09:53:27.615+02:00 level=INFO msg="local-api: disk assigned (host mount ensured)" vmid=9201 where=/mnt/resz2
+Oct 16 09:53:27 buildb felhom-agent[6589]: time=2026-10-16T09:53:27.706+02:00 level=INFO msg="guest-attach: drive bound under shared parent (normalized to one bind, live)" vmid=9201 where=/mnt/resz2 stable=/mnt/felhom-drives/resz2 prior_binds=0
+Oct 16 09:53:28 buildb felhom-agent[6589]: time=2026-10-16T09:53:28.088+02:00 level=INFO msg="local-api: guest-attach bound under shared parent" vmid=9201 where=/mnt/resz2 guest_path=/mnt/felhom-drives/resz2
+Oct 16 09:53:39 buildb felhom-agent[6589]: time=2026-10-16T09:53:39.199+02:00 level=INFO msg="local-api: same-disk" vmid=9201 a=/mnt/felhom-drives/resz1 b=/mnt/felhom-drives/resz2 different=false proven=true reason=same_disk
+Oct 16 09:53:39 buildb felhom-agent[6589]: time=2026-10-16T09:53:39.796+02:00 level=INFO msg="local-api: same-disk" vmid=9201 a=/mnt/sys_drive b=/mnt/felhom-drives/belso different=false proven=true reason=same_disk
+Oct 16 09:53:40 buildb felhom-agent[6589]: time=2026-10-16T09:53:40.005+02:00 level=INFO msg="local-api: same-disk" vmid=9201 a=/mnt/sys_drive b=/mnt/felhom-drives/resz1 different=true proven=false reason=vm
+Oct 16 09:53:40 buildb felhom-agent[6589]: time=2026-10-16T09:53:40.199+02:00 level=INFO msg="local-api: same-disk" vmid=9201 a=/mnt/sys_drive b=/mnt/felhom-drives/resz2 different=true proven=false reason=vm
+Oct 16 09:53:42 buildb felhom-agent[6589]: time=2026-10-16T09:53:42.263+02:00 level=INFO msg="local-api: same-disk" vmid=9201 a=/mnt/felhom-drives/resz1 b=/mnt/sys_drive different=true proven=false reason=vm
+Oct 16 09:53:42 buildb felhom-agent[6589]: time=2026-10-16T09:53:42.465+02:00 level=INFO msg="local-api: same-disk" vmid=9201 a=/mnt/felhom-drives/resz2 b=/mnt/sys_drive different=true proven=false reason=vm
+## controller
+2026/10/16 07:46:56 [INFO] [internal-place] registered /mnt/felhom-drives/belso (default=true) — media and data-folder apps can use it
+2026/10/16 07:49:39 [INFO] [stacks] Deploy jellyfin: a media app — HDD_PATH (its own config) on the default drive "/mnt/felhom-drives/belso"; the media binds cover every present drive
+2026/10/16 07:49:39 [INFO] [stacks] Deploying stack jellyfin with 3 env vars: [SUBDOMAIN, HDD_PATH, DOMAIN]
diff --git a/documentation/audits/storage-identity-buildB-2026-10-15/live/16-teardown-vm342.txt b/documentation/audits/storage-identity-buildB-2026-10-15/live/16-teardown-vm342.txt
new file mode 100644
index 00000000..16ba91be
--- /dev/null
+++ b/documentation/audits/storage-identity-buildB-2026-10-15/live/16-teardown-vm342.txt
@@ -0,0 +1,14 @@
+## 07:54:28 household power-off (POST /api/server/poweroff)
+{"data":{"code":"confirm_required"},"error":"Írd be a megerősítő szót: KIKAPCSOLÁS.","ok":false}
+
+HTTP 400
+VM 342: running at 07:58:35
+VM 342 is running - destroy failed
+status: running
+## 07:58:46 household power-off with the confirmation word
+{"data":{"powering_off":true},"ok":true}
+
+HTTP 202
+VM 342: stopped at 07:59:18
+purging VM 342 from related configurations..
+Configuration file 'nodes/demo-hp/qemu-server/342.conf' does not exist
diff --git a/documentation/audits/storage-identity-buildB-2026-10-15/live/17-teardown-tester1.txt b/documentation/audits/storage-identity-buildB-2026-10-15/live/17-teardown-tester1.txt
new file mode 100644
index 00000000..dfc4bba3
--- /dev/null
+++ b/documentation/audits/storage-identity-buildB-2026-10-15/live/17-teardown-tester1.txt
@@ -0,0 +1,7 @@
+## 07:59:28 Tester 1 scratch disk removal
+sdg not mounted
+ls: cannot access '/tmp/agentq.sh': No such file or directory
+scsi6: nvme-scratch:341/vm-341-disk-7.raw,backup=0,size=16G
+update VM 341: -delete scsi6 -force 1
+0
+0
diff --git a/documentation/audits/storage-identity-buildB-2026-10-15/live/18-r1082-hub-boxes.txt b/documentation/audits/storage-identity-buildB-2026-10-15/live/18-r1082-hub-boxes.txt
new file mode 100644
index 00000000..819e2fff
--- /dev/null
+++ b/documentation/audits/storage-identity-buildB-2026-10-15/live/18-r1082-hub-boxes.txt
@@ -0,0 +1,8 @@
+## 2026-10-16 R-1082: which boxes had attached /mnt/sys_drive — the hub's latest report per customer (reports.report_json
+## "storage", a list of {mount, label, …}; hub database copied with its WAL)
+demo-hp sys_drive mentions 0 | felhom-drives mentions 1 (control: its registered drive is listed)
+Tester-2 sys_drive mentions 0 | felhom-drives mentions 0
+tester-1 sys_drive mentions 0 | felhom-drives mentions 5
+demo-felhom sys_drive mentions 0 | felhom-drives mentions 1
+Tester4 sys_drive mentions 0 | felhom-drives mentions 1 (the data area, /mnt/felhom-drives/belso)
+Result: no box has /mnt/sys_drive registered; nothing to keep working, nothing to detach.
diff --git a/documentation/backlog/CLOSED-ITEMS.md b/documentation/backlog/CLOSED-ITEMS.md
index 637d88bb..12031e64 100644
--- a/documentation/backlog/CLOSED-ITEMS.md
+++ b/documentation/backlog/CLOSED-ITEMS.md
@@ -35,6 +35,15 @@
---
+## 2026-10-16 — storage identity build B (agent v0.158.1, controller v0.318.0, installer 1.33.0, golden 0.318.0)
+
+| Row | What | Closed | Evidence |
+|---|---|---|---|
+| **R-1068** | **On a one-disk box a media app's Install was refused with a raw field error.** (P3) | CLOSED 2026-10-16 — both halves built: a one-disk box now gets its own data area (installer 1.33.0 step 5b; an old box by the signed `add_internal_place`), registered as the default drive with no press — **live:** Jellyfin installed with DOMAIN + SUBDOMAIN only, 202, healthy, `/media` on the data area (the OMV run: 400 „HDD_PATH … kötelező"); a box with no drive at all gets the D4 sentence (controller 0.317.0, unit-proven). | `audits/storage-identity-buildB-2026-10-15/README.md` `08-jellyfin-deploy.txt` |
+| **R-1079** | **Build „storage that knows its physical disks"** (`architecture/16-storage-physical-identity.md`). (P2) | CLOSED 2026-10-16 — build A (2026-10-15) + build B (2026-10-16) shipped; `16` §13 lists what was built and where it differs. Live: a fresh 512 GB one-disk install → data volume 100 GiB, data area 213 GiB; partitions formatted and used; the honest backup offer. Follow-ups filed: R-1083, R-1093, R-1094. | `audits/storage-identity-buildB-2026-10-15/README.md`; `audits/storage-identity-buildA-2026-10-15/README.md` |
+| **R-1082** | **The drives page offered `/mnt/sys_drive` for attaching.** (P3) | CLOSED 2026-10-16 — operator ruling „hide it now"; **controller v0.318.0** excludes the system data volume by DEVICE (any second bind of it too); a box that registered it keeps it. Red-proved; **live:** the attach list empty while the controller's own mount table holds `/mnt/sys_drive`. Boxes that had attached it (the hub's latest report of all five boxes, 2026-10-16): **none** — nothing to keep working, nothing to detach (`live/18-r1082-hub-boxes.txt`). | `audits/storage-identity-buildB-2026-10-15/README.md` `10-same-disk-and-r1082.txt` |
+| **R-1084** | **The whole-box backup offer promised disk-failure protection without checking the disk.** (P3) | CLOSED 2026-10-16 — **controller v0.318.0**: the offer asks the agent; proven different → the promise; unproven (a VM) → offered without it („…ezért nem ígérhetjük…"); same disk → not offered; older agent → today's offer. Red-proved; **live** on a VM box. | `audits/storage-identity-buildB-2026-10-15/README.md` `14-samedisk-refusal-offer.txt` |
+
## 2026-10-15 (night) — storage identity build A (agent v0.157.0, controller v0.317.0, hub v0.154.0)
| Row | What | Closed | Evidence |
diff --git a/documentation/backlog/OPEN-ITEMS.md b/documentation/backlog/OPEN-ITEMS.md
index 1ec33b1a..e3f233e3 100644
--- a/documentation/backlog/OPEN-ITEMS.md
+++ b/documentation/backlog/OPEN-ITEMS.md
@@ -159,7 +159,7 @@ stopping line that lies.
| **R-683** | App updates | P3 | **[P3-LOW] Watch: after a power cut during an update's health check, the hold named an HOUR-OLD second-drive copy, not the one the update's own backup should have just made.** 2026-09-24 chaos round 3 (nextcloud, `backup_max_age: 1m`): no `backing-up` phase was seen and the hold named Tier 2 at 13:04 for an update pressed at 14:04; the pre-cut controller log was lost with the container (the runner now saves it at arm time — R-320). Round 11, the same action without a power cut, named a fresh 14:34 copy and logged the Tier-2 copy. The sentence was TRUE (it named the copy it offered); the question is why the update did not back up first. Not reproduced; watch the next power-cut drill. `audits/night-2026-09-24/E/round-03*.json`, `E/round-11-controller-pre.log` | **OPEN — P3; owner: CC (watch)** | — | — | CC |
| **R-785** | App updates | P3 | **[P3-LOW] SparkyFitness is pinned 11 releases and a major behind upstream (v0.17.3; upstream v1.7.3, v1.6.0 dated 2026-07-24).** READ 2026-10-01 (`audits/visitors-2026-10-01/C/bench/C1-previous-tag.txt`). **Needs:** an update walk 0.17 → 1.x through the ladder (bench + box), after R-784 is decided. | **OPEN — rank P3-LOW; owner: CC (after R-784)** | — | — | CC |
-## Backup & restore — 32 rows (P2 3, P3 18, P4 11)
+## Backup & restore — 31 rows (P2 3, P3 17, P4 11)
| ID | Category | Sev | What | State | Blocked on | Next action | Owner |
|---|---|---|---|---|---|---|---|
@@ -183,7 +183,6 @@ stopping line that lies.
| **R-921** | Backup & restore | P3 | **When the off-site tier answers BUSY, the household still gets a short stop of every app — with no copy.** MEASURED 2026-10-08 night on demo-hp (read-back 2026-10-09, `audits/dooplex-survival-2026-10-09/partE/R-518.txt`): local tier 20:20–20:25Z (own stop, < 2 min), then at 20:26:14Z the agent refused the off-site request (`backup refused — a heavy operation is already in flight`, `busy=backup:local` — the night OS step ran 20:27–20:29Z), yet the controller's metrics show all 15 app containers down at 20:26:19Z and back at 20:27:19Z; the retry ran the off-site tier at 20:34Z with its own short stop. So a two-tier night costs THREE stops, one of them for nothing. This was R-518's noted "unmeasured" risk. Fix shape: ask the agent whether it is free (or reserve the slot) BEFORE quiescing, and resume at once on BUSY. | **NARROWED 2026-10-09 — built; RELEASED 2026-10-10 (controller 0.305.0 on demo-hp, demo-felhom, Tester 1):** before stopping apps the controller asks the agent which tiers have a job in flight (`GET /backup/status`); another tier's job in flight → no stop, the tier stays due (red-proved: 3 apps stopped for a refused tier before); a refusal after the stop still resumes the apps at once (pinned). Also fixes a stop after a long upload or a restart mid-upload. **LEFT: the measured case itself** — the agent's host-wide busy lock (the night OS step, restore test, fstrim) is served on NO endpoint, so the controller cannot see it before stopping; needs one agent field (e.g. `busy` on `GET /backup/status`) + a controller pre-check behind a feature probe. `07` §6.4. | an agent change | Build the agent `busy` field + its controller check; read back a two-tier night | CC |
| **R-933** | Backup & restore | P3 | **Mirror the images of every catalog app we support into our own registry, before scale.** Operator, 2026-10-12 (S8, `09` §3 decision 203): *„Will need to mirror the apps we support later, just to be sure."* Today a restore re-pulls each image from its maker; a version the maker deleted cannot start (the accepted limit, `07` §6.6, R-698 closed). Size it first: the supported catalog's images (every ladder version a box can hold) × their size; then where the copy lives (the DooPlex registry is Tier 2, precious — the copy must not make DooPlex a single point of failure for every household's restore) and how a restore falls back to it. | **OPEN** — NEW 2026-10-12 | the size measurement | Measure the total size of the supported catalog's images; then a one-page design (where, how a restore falls back, cost) | CC (measure + design), operator (the go) |
| **R-1019** | Backup & restore | P3 | **The live download-client templates put downloads into two backup tiers nobody chose.** MEASURED 2026-10-14 with the controller's own classifier over the live templates (`audits/media-all-drives-2026-10-14/``A-drives/A6-3-capture-sets.txt`): Transmission's `${USERDATA_PATH}/media/transmission/watch` bind is not listed in its `backup:` block, so it is classed MANDATORY and goes into the OFF-SITE copy (a writable unlisted bind defaults to mandatory); and qBittorrent's `media/torrents` and Transmission's `media/transmission` are `optional`, so on a box with a second drive every download is mirrored there nightly (Tier 2 = mandatory + optional) — it can fill the backup drive with films. | **NARROWED** — filed 2026-10-14; the `watch` half FIXED 2026-10-14 (declared optional, app-catalog `bc54c01`); open: the `optional` download folders still get a nightly Tier-2 mirror on a box with a second drive | — | Declare the media binds `excluded` (the watch folder too) in the live-fix task; `15` §7 states the rule for the per-drive bind | CC |
-| **R-1084** | Backup & restore | P3 | **The whole-box backup offer promises protection against a disk failure without asking whether the drive is a different disk.** SEEN 2026-10-15 on Tester 1 (a box inside a VM, every place `unknown/vm`), controller 0.317.0, `/backups`: „Ezt a meghajtót kijelölheted a rendszermentés helyéül — így egy lemezhiba után is vissza tudod állítani a rendszert.” next to the new „A Felhom nem tudja ellenőrizni, hogy a második meghajtó valóban másik lemez-e…” — the page says both. Build A (`architecture/16-storage-physical-identity.md` §4) covered Tier-2 and the one-copy notice only; the whole-guest target offer (C/internal/web/backup_target_offer.go) still trusts any second drive. Evidence: `audits/storage-identity-buildA-2026-10-15/tester1-backup-pages-after.txt`. | OPEN | — | Make the offer ask the agent (`POST /disks/same-disk`, drive vs `/var/lib/felhom`): proven different → today's sentence; unknown → an honest one; same → no offer. A controller change with a test. | CC |
| **R-91** | Backup & restore | P4 | Old 13 GB datastore copy at `/srv/pbs-felhom` on ep0's root disk **Checked from source 2026-10-05 (burn-down round 2):** Gate is long past (row waits on demo-felhom's first post-migration PBS backup, migration 2026-07-27). Last positive record of the copy: audits/CAMPAIGN-9-restore-proof-2026-07-28.md:759 'ep0 : /srv/pbs-felhom rollback copy intact (13G)'; CONTEXT.md:3666 still says it is 13 G of dead weight awaiting R-91. No later record of deletion found (grep srv/pbs-felhom across felhom.eu). Deleting is on ep0 (protected) and needs an operator word. | WATCHING | demo-felhom's first **post-migration** PBS backup | Delete once it lands; fix `CONTEXT.md:1018` same commit | CC |
| **R-164** | Backup & restore | P4 | **C2's chain: the DB volume tar cannot be dropped until a SOUND dump predicate exists.** The unit carries both a volume tar and a SQL dump; the restore uses **both** — the dump is authoritative and replayed *after* the tar so it WINS (F17), with only the DB service up (R-47) — `internal/backup/restore_unit.go:262-266`. Dropping the DB container's tar would halve DB-app units **and** close the R-127(b) initdb-skip password trap (restored PGDATA ⇒ `POSTGRES_PASSWORD` ignored). | **BLOCKED** — on the predicate | a dump-validity predicate that is not `accounts has rows` | **The obvious gate is DEAD, measured:** `ValidateDump` warns when the `accounts` table is empty, and that warning was **correct** — the live DB genuinely had 0 accounts, and seeding one stopped the warning and put the row in the dump. But **a fresh appliance legitimately has zero accounts**, so promoting that predicate to a gate would **block every new customer's first backup**. Order: (1) a sound predicate — dump vs **live** per-table counts, not an absolute expectation; (2) warn→gate; (3) tar-drop. **Until (1), the tar is load-bearing** — not because dumps are bad, but because nothing can yet prove one is good. Pairs with **R-127** | CC |
| **R-213** | Backup & restore | P4 | **Putting files back in place — the half the recovery screen deliberately does not do.** The screen (R-193, controller v0.200.0) unlocks the repository and LISTS what is in it; restoring is per-app and lives in the backups area, and the operator ruled the two separate on 2026-08-05: *a screen that unlocks and then offers to overwrite is two decisions wearing one button*. What is missing is the step after the listing — a customer who can now SEE their files still has to work out, per app, which restore to choose. **The operator named its requirement: a live-versus-backup comparison** — the customer must be able to see what would change before anything is overwritten | **DEFERRED** — operator ruling 2026-10-12 (S18, `09` §3 decision 213): designed after the first customers. Stays P4; re-dated: look again when the first paying household has run 30 days. **OPEN — not started, deliberately** | the comparison design (nothing exists for it yet) | After the first customers | Operator + CC |
@@ -196,15 +195,13 @@ stopping line that lies.
| **R-32** | Backup & restore | P4 | **[P2-HIGH] RESET must purge the customer base dir; the orphan card must stay honest; unattributed bytes must be visible.** The rehearsal's S7 said in advance that an orphan card would BE a finding — and one appeared (16:58:14). Cause: RESET's `"hetzner":"ok"` leg destroys the sub-account, but **a Hetzner sub-account is an access-control object, not a data object** — its directory survives, so re-enabling offsite recreated an account over the previous lifecycle's ciphertext, encrypted under a key that same RESET had destroyed. **MIGRATED FROM `ROADMAP.md` 2026-08-22 (R-369) — originally filed 2026-07-21, size M, roadmap state `idea`.** Moved verbatim; nothing added or reinterpreted. The roadmap keeps its copy as history, marked moved. | **OPEN — migrated from ROADMAP 2026-08-22, rank unchanged** **2026-10-06 night: design written** (`audits/night-burndown-2026-10-06/design-R-32.md`) — pick A: purge the repo + set-aside copies through the sub-account's own password login BEFORE deleting it (no main-account credential); the „repo data destroyed" comment at `hub/internal/offsite/offsite.go:276-280` is false for the shared tier; part (3) waits on a read-only measurement (`du` on port 23). Operator: agree to route A. **2026-10-07 07:58: `09` §3 decision 167 — option A yes, and delete the old RESET leftovers once.** **2026-10-07 (Part D step 2, read only):** the hub shows bx11 holding 3.3 GB of data while the four live customers account for ~0.6 GB → **~2.7 GB belongs to no live customer**; no live customer shows a set-aside folder, so the leftovers are in homes whose sub-account is gone, reachable only by the pool box's MAIN account. **The one-time clean-up is STOPPED:** no main-account login for bx11 is held on DooPlex (the API token in the credentials file sees no box). Needs: the main-account login, or the operator lists and deletes in the Hetzner console (`audits/day-2026-10-07/D/D2-listing-readonly.txt`). **2026-10-07: option A DELIVERED (hub 0.142.0):** RESET purges the repo and every `.orphaned-*` through the sub-account's own login before deleting it, and keeps the sub-account if the purge fails (red-proved, `audits/day-2026-10-07/D/`). Not yet seen live (no scratch RESET today). **The one-time clean-up of the ~2.7 GB of leftovers is STOPPED:** it needs the pool box's main-account login (see above). **2026-10-07 14:43 — `09` §3 decision 173: leave the ~2.7 GB of old leftovers for now; re-ranked P2 → P4.** Option A itself is delivered (hub 0.142.0). What stays open is ONLY the leftovers: they were computed (box total minus live customers), never listed, and deleting them needs the pool box's MAIN login, which reaches every customer's data. **Blocker: a safe main-account path.** | — | **Ruling from the run (three parts, deliberately separate):** (1) because RESET destroys custody, the ciphertext it leaves behind is unrecoverable **BY DESIGN** → RESET gains a **main-account purge of the customer base dir** (the existing operator ack already covers it); (2) the **move-aside guard STAYS** for reinstall-*without*-RESET — there custody survives and the card's "history recoverable" promise is true (R-26 depends on exactly that); (3) the operator **Restic tab shows per-customer directory bytes vs attributed snapshot bytes**, so dead data cannot hide. Measured on the pool box that night: **49 M attributed** (2 snapshots, 48.717 MiB) against **1.4 G + 3.0 M unattributed** across TWO `.orphaned-*` dirs. Evidence `restic-and-pool.txt` | CC |
| **R-1087** | Backup & restore | P4 | **Whole-box copies left on the OLD local target are never pruned after the target moves.** MEASURED 2026-10-15 (storage-identity build B space check): the N100's host root (`local`) holds three copies from 2026-07-28 (5.5–5.7 GB each, ≈ 16.8 GB); its agent's `local_backup_target` is now `felhom-backup` (the USB disk, retention 3), and retention prunes only the current target. On a small-root box such leftovers would starve the local copies (R-548). Evidence: `audits/storage-identity-buildB-2026-10-15/space/felhom-pve-9201.txt`. | OPEN | — | Decide whether the agent prunes its own `vzdump-lxc--*` files on a former target (after a newer copy exists on the new one), or the target move asks; until then, the N100's three July files can be removed by hand with the operator's word. | CC |
-## Storage & devices — 13 rows (P2 1, P3 7, P4 5)
+## Storage & devices — 12 rows (P3 6, P4 6)
| ID | Category | Sev | What | State | Blocked on | Next action | Owner |
|---|---|---|---|---|---|---|---|
-| **R-1079** | Storage & devices | P2 | **Build „storage that knows its physical disks” (`architecture/16-storage-physical-identity.md`, DRAFT): every place carries `physical_disks` + `identity`, computed by the agent; Tier-2 counts only on proven different disks; a „Belső tárhely” internal place on one-disk boxes; partitions as places.** Operator ruling 2026-10-15 asked for it. Spike proved the agent-side walk on real devices (one disk, two disks, two partitions, USB pass-through) and showed a VM can only be `unknown` (`audits/storage-identity-2026-10-15/README.md`). Closes, when built: R-1068, R-1074, R-1075; touches R-1069, R-1071, R-1073, R-548. **-- 2026-10-15:** the operator ruled D1–D6 as recommended, and asked to check the D3 space. **Build A SHIPPED** (agent v0.157.0, controller v0.317.0 with MinAgent 0.157.0, hub v0.154.0): identity per place, the same-disk call, Tier-2 + the one-copy notice ask the agent, the D4 sentence, the hub shows the fields — `16` §13, `audits/storage-identity-buildA-2026-10-15/`. Closed R-1072, R-1074, R-1075; narrowed R-1068. | NARROWED 2026-10-15 — build A shipped; build B (internal place, partitions, installer) not started. | A build B task file (installer + agent partitions); the operator's vouch of agent 0.157.0 for the global floor. | Build B per `16` §5–§7 (check the D3 space on real pool sizes first). | Operator |
-| **R-1068** | Storage & devices | P3 | **On a box with one disk, a media app's (or any data-folder app's) Install is refused with a raw field error, and the way through is nowhere near the button.** MEASURED 2026-10-15 on the OMV-VM copy of the pilot's box (one passed NVMe, controller 0.314.0): `POST /api/stacks/jellyfin/deploy` with DOMAIN+SUBDOMAIN → **400 „a(z) "Médiatár útvonal" (HDD_PATH) mező kitöltése kötelező”** — the env var name reaches the household. R-1031's default-drive rule finds no drive because none is registered. The box DOES offer one: `/api/disks/candidates` listed `/mnt/sys_drive` (the installer's data volume, `already_mounted`), and `handleStorageRegisterMounted` (R-280) registers it — **seen in the candidate list and the code, NOT pressed** (the box was removed). With a second disk attached through „Csatlakoztatás”, the same Install succeeded in 30 s. Evidence: `audits/omv-vm-2026-10-15/README.md` „What happened”, `B4-deploy.txt`. **-- 2026-10-15 (storage-identity spike):** the `sys_drive` route is REJECTED by design — `sys_drive` is a folder of `mp0` (`backup=1`), so films there would ride in every whole-guest copy; the proposal is an internal data place outside vzdump, `architecture/16-storage-physical-identity.md` §5; folded into R-1079. **-- 2026-10-15 (build A, controller v0.317.0):** the raw-error half is DONE — on a box with no drive the install answers „Ehhez az alkalmazáshoz egy adattároló kell. A Meghajtók oldalon adhatsz hozzá egyet.” with a link to the Meghajtók page (HTTP 400, code `needs_drive`), never the field name; unit-proven and red-proofed, **not seen live** (no one-disk box at hand). The internal-place half waits for build B (`16` §5, §13). | NARROWED 2026-10-15 — the sentence is built (v0.317.0); the internal place is not. | Build B of R-1079 (the installer's internal place). | Build B; then see the sentence live once on a one-disk box (a scratch VM with one disk). | CC |
| **R-1069** | Storage & devices | P3 | **A disk passed into a Felhom VM on a virtio bus cannot be formatted, and the household reads the agent's raw English refusal.** MEASURED 2026-10-15 (OMV KVM plugin, „Add host disk”, default Bus `virtio`): `POST /api/disks/format` → 500 „agentapi: format: HTTP 409: format refused: device has no durable id to bind the format to (path-only formats are not permitted)”. A virtio-blk disk without a serial has no `/dev/disk/by-id` link inside the guest, so the anti-retarget guard refuses — correct and safe. The same disk on Bus `sata` got `byid:ata-QEMU_HARDDISK_QM00003` and formatted. Affects every hypervisor that passes disks as virtio without a serial (OMV KVM, Proxmox without `serial=`). The pilot guide says `sata`. Evidence: `audits/omv-vm-2026-10-15/B4c-second-disk-format.txt`. | OPEN | — | Translate the refusal for the household („Ezt a lemezt a Felhom nem tudja biztonságosan azonosítani — a virtuális gépben állítsd a lemez buszát SATA-ra”); optionally fall back to a filesystem-UUID binding after a blank-format. | CC |
| **R-1073** | Storage & devices | P3 | **Felhom in a virtual machine sees no disk health: SMART is UNKNOWN for its own system disk and any passed disk.** MEASURED 2026-10-15 on the OMV-VM copy: every storage target reported `smart.health = UNKNOWN`, all counters null (the guest sees QEMU disks). On the pilot's box the NVMe and the „old, not stable” Toshiba would be watched by OMV only, and Felhom's drive-health alarms (R-330/R-332's whole point) cannot fire. Evidence: the host report in `audits/omv-vm-2026-10-15/README.md` (memory/disk section) and `C-hub-events-Tester4.txt`. | WAITING-ON-OPERATOR | Operator: is a VM install a supported shape, and if so, is „OMV watches SMART” acceptable or must Felhom say on the dashboard that it cannot watch the disks? | Operator rules; then CC adds a household line on the Meghajtók page when SMART is unavailable. | Operator |
-| **R-1082** | Storage & devices | P3 | **The drives page offers `/mnt/sys_drive` for attaching, while the storage-identity design rejects `sys_drive` as a drive for household data — and the new no-drive install sentence links to that page.** FOUND 2026-10-15 building `16` build A: `attachableStores` (felhom-controller `internal/web/attach_sources.go:79-136`) offers the guest data volume's `/mnt/sys_drive` on purpose — R-280, the way back after a reinstall so a restore has a destination, pinned by `TestMountedUnregisteredStores_OffersTheGuestDataVolume`. `architecture/16-storage-physical-identity.md` §11 rejects registering it for media (it rides in every whole-guest copy, local and off-site). Build A's D4 refusal (controller v0.317.0) never names it, but its link leads to the page that offers it. Not changed: the brief says to stop and report where source and design disagree, and removing it would reverse R-280. **-- 2026-10-16: operator ruling „hide it now”** (asked at the build B stop): the drives page stops offering `/mnt/sys_drive`; a box that already attached it keeps working; such boxes are listed from the hub, nothing is detached. | READY — ruled 2026-10-16: hide it now (build B). | — | Build B item 7: the drives page never offers `/mnt/sys_drive`; red-proved test; list boxes that attached it. | CC |
+| **R-1093** | Storage & devices | P3 | **An EMPTY partition asks for the typed „data will be erased" confirmation.** MEASURED 2026-10-16 (build B, scratch VM, agent 0.158.1): `POST /api/storage/init` for a blank part → `needs_confirmation`, reason „device has a partition table" — `lsblk` reports the PARENT disk's table (PTTYPE) for a partition, so the agent's probe reads an empty part as data-bearing. Safe direction (more friction, never less), but `16` §6 says an empty part is self-serve and the wizard shows „adatot tartalmaz". Evidence: `audits/storage-identity-buildB-2026-10-15/live/12-partitions-format.txt`. | OPEN | — | In the agent's device probe, ignore a PTTYPE that a partition inherits from its parent (judge only the part's own signature and children); a red-proved test with a blank part fixture. Next agent release. | CC |
| **R-1062** | Storage & devices | P4 | **The N100's USB drive cannot be split in two without losing the box's whole-guest backup target.** The operator asked (2026-10-15 16:31) for two halves for multi-drive tests. Read first (`audits/n100-lived-in-2026-10-15/B/`): no family files — 2.7 GB nightly vzdumps of guest 9201 (`dump/`, PVE storage `felhom-backup` = the whole-guest backup target), 3.1 GB app backups + an off-site restore copy, 422 MB leftover app data of removed apps, empty media folders. The agent refuses a decommission of a backup target (`refuseIfBackupTarget`) and the N100 has no other drive to move that role to. Nothing changed. | **WAITING-ON-OPERATOR** — filed 2026-10-15 | operator decision | Keep one drive (CC's pick: the lived-in box keeps its local whole-guest backup), or give a word to drop that backup leg / add a second drive first | operator |
| **R-1063** | Storage & devices | P3 | **„Végleges leszerelés" leaves a half-state when the agent refuses: the dashboard marks the drive decommissioned first and never undoes it.** `handleStorageDecommission` → `finalizeDecommissionWith` calls `settings.SetDecommissioned` (and may move the default) BEFORE `agent.Decommission`; on the agent's 403 (protected role) or 409 (whole-guest backup target) it returns the error and keeps the mark — the dashboard would show a retired drive the agent kept serving. Read from code 2026-10-15 (`felhom-controller` `internal/web/storage_handlers.go`); NOT pressed on the lived-in N100 on purpose. | **OPEN** — filed 2026-10-15 | — | Measure on demo-hp (a backup-target drive), then: ask the agent first (or undo the mark and the default on a refusal); a test with a refusing agent seam, red first | CC |
| **R-1064** | Storage & devices | P4 | **Removing a storage path does not mention the cross-drive backup copies it holds.** demo-hp 2026-10-15: `/mnt/sizing-bench` removed through `/settings/storage/remove` (302, „Adattároló eltávolítva") while calibre-web's and paperless-ngx's `cross_drive.destination_path` pointed at it; the copies stay on disk, the records still name the removed path. The in-use check counts HDD_PATH only (`appsUsingPath`). | **OPEN** — filed 2026-10-15 | — | Read what tonight's tier-2 run (01:30) does with the two records; then: name the copies in the removal's confirmation (or count them as in use) | CC |
@@ -213,6 +210,7 @@ stopping line that lies.
| **R-331** | Storage & devices | P4 | **Disk health Phase 3 — growth-rate detection, and retiring the static 64.** The v0.215.0 count backstop (64 unreadable sectors → Hiba) is **a judgement from ONE drive**: the observed benign excursion peaked at 16 and cleared inside an hour, and the terminal run passed 64 at 13 Aug 11:28 and never came back. It is deliberately a backstop BEHIND the sustain rule, not the primary signal, but it is still a magic number tuned on a single sample and it will be wrong for some drive. With Phase 2's history the box can ask the question that actually matters — *is this count climbing, and how fast* — which distinguishes a drive with eight stable aging sectors from one adding forty a day, something no static threshold can do. Revisit 64 when that exists | **READY (M) — NEW 2026-08-14** | R-330 | Growth-rate rule over persisted samples; re-derive or delete the static 64 | CC |
| **R-1076** | Storage & devices | P4 | **A cheap SSD reports a vendor-less WWN, so a WWN-first disk key may not be unique.** MEASURED 2026-10-15 on the N100's system SSD (AirDisk 512 GB): `ID_WWN=0x5000000123456f1f` — NAA-5 with OUI `000000`, a pattern that looks like a placeholder; its serial `QDF922W009654S30EX` looks real. The agent's wipe binding prefers `wwn-` links (A/internal/storage/durable_device.go:32). Not known whether two units share the WWN. Evidence: `audits/storage-identity-2026-10-15/B-n100.txt`. | OPEN | — | Check a second unit of the same model (or vendor data); if shared, make the agent skip OUI-000000 WWNs (the design already keys on model+serial, `architecture/16-storage-physical-identity.md` §3). | CC |
| **R-1077** | Storage & devices | P4 | **No USB enclosure that hides or fakes a disk's serial has been measured.** The storage-identity spike (2026-10-15) had none at hand and found none in earlier evidence; the design's `usb_bridge` unknown rule (`architecture/16-storage-physical-identity.md` §3) is therefore an assumption. Cheap single- and dual-bay bridges are known to report one bridge serial for any disk. Evidence: `audits/storage-identity-2026-10-15/README.md` case 4b. | OPEN | — | Buy or borrow one cheap USB enclosure (single and dual bay), run `tools/physdisk_probe.py` against it, and set the rule from what it reports. | Operator (a device) then CC |
+| **R-1094** | Storage & devices | P4 | **The whole-disk format refusal tells the household to format the free part — which is refused while the other part is in use.** SEEN 2026-10-16 (controller 0.318.0): 409 „Ezen a lemezen egy használatban lévő meghajtó van, ezért a teljes lemez nem formázható. Csak a szabad részét formázhatod." — since agent 0.158.1 a part next to a mounted part can only be USED (the root wrapper trusts no „Felhom's own" claim). Evidence: `audits/storage-identity-buildB-2026-10-15/live/14-samedisk-refusal-offer.txt`. | READY | — | Reword `err.web.meghajto_hasznalatban_formazas` (hu + en): „… nem formázható. A szabad részét használatba veheted." Next controller release; the copy gates run. | CC |
## Security & access — 21 rows (P1 2, P2 3, P3 10, P4 6)
diff --git a/documentation/tests/golden-0.318.0-2026-10-16/00-boot.txt b/documentation/tests/golden-0.318.0-2026-10-16/00-boot.txt
new file mode 100644
index 00000000..d811267e
--- /dev/null
+++ b/documentation/tests/golden-0.318.0-2026-10-16/00-boot.txt
@@ -0,0 +1 @@
+booted 07:13:07
diff --git a/documentation/tests/golden-0.318.0-2026-10-16/02-round-trip.txt b/documentation/tests/golden-0.318.0-2026-10-16/02-round-trip.txt
new file mode 100644
index 00000000..9399b6b9
--- /dev/null
+++ b/documentation/tests/golden-0.318.0-2026-10-16/02-round-trip.txt
@@ -0,0 +1,3 @@
+## round trip 2026-10-16T07:20:15Z
+sha256 18077b6a689a06f3e2c08deefe939c631124f07ffc64533ec3896e75d61a4654 bytes 649065920
+bake said 18077b6a689a06f3e2c08deefe939c631124f07ffc64533ec3896e75d61a4654
diff --git a/documentation/tests/golden-0.318.0-2026-10-16/03-teardown.txt b/documentation/tests/golden-0.318.0-2026-10-16/03-teardown.txt
new file mode 100644
index 00000000..c76cc40c
--- /dev/null
+++ b/documentation/tests/golden-0.318.0-2026-10-16/03-teardown.txt
@@ -0,0 +1,6 @@
+## teardown 2026-10-16T07:20:28Z
+purging CT 9100 from related configurations..
+0
+3
+qemu running: 0
+disk back to virgin
diff --git a/documentation/tests/golden-0.318.0-2026-10-16/README.md b/documentation/tests/golden-0.318.0-2026-10-16/README.md
new file mode 100644
index 00000000..cac41ad2
--- /dev/null
+++ b/documentation/tests/golden-0.318.0-2026-10-16/README.md
@@ -0,0 +1,37 @@
+# Golden 0.318.0 — bake + publish, 2026-10-16 (storage identity build B)
+
+Why: the hub refuses to vouch agent 0.158.1 next to golden 0.313.0 (R-120: the golden is older than the controller the
+fleet runs). The operator chose „bake a golden now" (2026-10-16), so build B's fresh-install proof can run on a vouched
+agent. Procedure: `documentation/runbooks/RUNBOOK-manual-build.md` §4.0 and §4.1 steps 1–4, in the drill VM on DooPlex.
+The script came from CC's clean `felhom-agent` clone at `origin/main` (`1a8bed1`).
+
+| | Previous (`../golden-0.313.0-2026-10-15/`) | This bake |
+|---|---|---|
+| `build-golden.sh` | v3.2.0 | same file, unchanged |
+| Controller | `felhom-controller:0.313.0` (MinAgent 0.155.0) | **`felhom-controller:0.318.0`** (**MinAgent 0.157.0**) |
+| Docker engine | approved set (six pairs) | same six pairs, `GOLDEN_DOCKER_PKGS` set from the start |
+| Template | `debian-13-standard_13.6-1_amd64.tar.zst` | same (after `pveam update`; `_amd64` filtered) |
+
+## Pass markers (from `bake.log`, this folder)
+
+```
+[golden] build-golden.sh v3.2.0 — baking controller gitea.dooplex.hu/admin/felhom-controller:0.318.0
+[golden] Docker engine set PINNED to the approved release: containerd.io=2.3.6-1~debian.13~trixie … docker-ce=5:29.8.2-1~debian.13~trixie …
+ docker OK (overlay2; data-root /var/lib/docker)
+INFO: including mount point rootfs ('/') in backup
+INFO: including mount point mp0 ('/var/lib/felhom') in backup
+[golden] upload OK (HTTP 201)
+GOLDEN_VERSION=0.318.0
+GOLDEN_SHA256=18077b6a689a06f3e2c08deefe939c631124f07ffc64533ec3896e75d61a4654
+```
+
+No `excluding`, no `FATAL`, no `GOLDEN_DOCKER_PKGS not set`; the unit `Result=success`. Round trip: the registry's file
+downloaded and hashed = the bake's sha, 649,065,920 bytes (`02-round-trip.txt`). Token: the unit's properties grep = 0;
+the committed log grep = 0, with a working control (= 1 on a copy with the token appended, the copy shredded).
+Teardown: `03-teardown.txt` (CT 9100 purged, token/script/log shredded in the VM, VM off, disk back to `virgin`).
+
+## Vouch — the operator's act
+
+Three fields together (runbook §4.1 step 5): golden **0.318.0**, agent **0.158.1** (NOT 0.158.0 — superseded by the
+security review; NOT the `0.158.1-step1` entry), min_agent **0.157.0** (0.318.0's MinAgent). The agent's bundle is
+`c23c3d355fe70a6fc6427c7996f76d72dab79a60f2c5497ea975de850cb1c41b`.
diff --git a/documentation/tests/golden-0.318.0-2026-10-16/bake.log b/documentation/tests/golden-0.318.0-2026-10-16/bake.log
new file mode 100644
index 00000000..5f8afe81
--- /dev/null
+++ b/documentation/tests/golden-0.318.0-2026-10-16/bake.log
@@ -0,0 +1,340 @@
+[golden] build-golden.sh v3.2.0 — baking controller gitea.dooplex.hu/admin/felhom-controller:0.318.0
+[golden] creating build LXC 9100 (nesting=1,keyctl=1, unprivileged; rootfs 32G + ONE data volume 24G @ /var/lib/felhom, backup=1) …
+ Logical volume "vm-9100-disk-0" created.
+ Logical volume pve/vm-9100-disk-0 changed.
+Creating filesystem with 8388608 4k blocks and 2097152 inodes
+Filesystem UUID: 7e37a060-d7d2-475d-83e5-67eab3275078
+Superblock backups stored on blocks:
+ 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
+ 4096000, 7962624
+ Logical volume "vm-9100-disk-1" created.
+ Logical volume pve/vm-9100-disk-1 changed.
+Creating filesystem with 6291456 4k blocks and 1572864 inodes
+Filesystem UUID: a3b42718-952b-4e23-8eee-52448fb9897b
+Superblock backups stored on blocks:
+ 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
+extracting archive '/var/lib/vz/template/cache/debian-13-standard_13.6-1_amd64.tar.zst'
+Total bytes read: 553512960 (528MiB, 99MiB/s)
+Detected container architecture: amd64
+Creating SSH host key 'ssh_host_ecdsa_key' - this may take some time ...
+done: SHA256:0PNkfBVrUtRjVaiSrIlIUWHMMFUqzPIE2CSgi1rINvw root@felhom-golden
+Creating SSH host key 'ssh_host_rsa_key' - this may take some time ...
+done: SHA256:augNDRnuAosVOyx4y2gHFL8UZLLelWBMNn5COUeRgbQ root@felhom-golden
+Creating SSH host key 'ssh_host_ed25519_key' - this may take some time ...
+done: SHA256:C1akccRXwjrpEnO9h/kmkVlcoLxqbh6Ho7zYFeAngNw root@felhom-golden
+[golden] starting + installing Docker (official repo, trixie channel) …
+[golden] Docker engine set PINNED to the approved release: containerd.io=2.3.6-1~debian.13~trixie docker-buildx-plugin=0.37.1-1~debian.13~trixie docker-ce=5:29.8.2-1~debian.13~trixie docker-ce-cli=5:29.8.2-1~debian.13~trixie docker-ce-rootless-extras=5:29.8.2-1~debian.13~trixie docker-compose-plugin=5.6.0-1~debian.13~trixie
+apt-listchanges: Can't set locale; make sure $LC_* and $LANG are correct!
+perl: warning: Setting locale failed.
+perl: warning: Please check that your locale settings:
+ LANGUAGE = (unset),
+ LC_ALL = (unset),
+ LC_CTYPE = (unset),
+ LC_NUMERIC = (unset),
+ LC_COLLATE = (unset),
+ LC_TIME = (unset),
+ LC_MESSAGES = (unset),
+ LC_MONETARY = (unset),
+ LC_ADDRESS = (unset),
+ LC_IDENTIFICATION = (unset),
+ LC_MEASUREMENT = (unset),
+ LC_PAPER = (unset),
+ LC_TELEPHONE = (unset),
+ LC_NAME = (unset),
+ LANG = "en_US.UTF-8"
+ are supported and installed on your system.
+perl: warning: Falling back to the standard locale ("C").
+locale: Cannot set LC_CTYPE to default locale: No such file or directory
+locale: Cannot set LC_MESSAGES to default locale: No such file or directory
+locale: Cannot set LC_ALL to default locale: No such file or directory
+apt-listchanges: Can't set locale; make sure $LC_* and $LANG are correct!
+perl: warning: Setting locale failed.
+perl: warning: Please check that your locale settings:
+ LANGUAGE = (unset),
+ LC_ALL = (unset),
+ LC_CTYPE = (unset),
+ LC_NUMERIC = (unset),
+ LC_COLLATE = (unset),
+ LC_TIME = (unset),
+ LC_MESSAGES = (unset),
+ LC_MONETARY = (unset),
+ LC_ADDRESS = (unset),
+ LC_IDENTIFICATION = (unset),
+ LC_MEASUREMENT = (unset),
+ LC_PAPER = (unset),
+ LC_TELEPHONE = (unset),
+ LC_NAME = (unset),
+ LANG = "en_US.UTF-8"
+ are supported and installed on your system.
+perl: warning: Falling back to the standard locale ("C").
+locale: Cannot set LC_CTYPE to default locale: No such file or directory
+locale: Cannot set LC_MESSAGES to default locale: No such file or directory
+locale: Cannot set LC_ALL to default locale: No such file or directory
+ installed: containerd.io 2.3.6-1~debian.13~trixie
+ installed: docker-buildx-plugin 0.37.1-1~debian.13~trixie
+ installed: docker-ce 5:29.8.2-1~debian.13~trixie
+ installed: docker-ce-cli 5:29.8.2-1~debian.13~trixie
+ installed: docker-ce-rootless-extras 5:29.8.2-1~debian.13~trixie
+ installed: docker-compose-plugin 5.6.0-1~debian.13~trixie
+[golden] no approved guest release given - the template versions stay; first-night count vs an approved release: n/a
+[golden] pending Debian upgrades in the baked guest (what a FUTURE approval may bring): 56
+[golden] baking daemon.json: classic overlay2 driver (containerd-snapshotter OFF) + log rotation …
+[golden] wiring the single data volume (R-165 variant V-c): /var/lib/felhom/{docker,sys_drive} -> binds …
+[golden] verifying Docker works in the build guest (storage driver should be overlay2 on the ext4 data volume) …
+Unable to find image 'hello-world:latest' locally
+latest: Pulling from library/hello-world
+4f55086f7dd0: Pulling fs layer
+4f55086f7dd0: Verifying Checksum
+4f55086f7dd0: Download complete
+4f55086f7dd0: Pull complete
+Digest: sha256:11a3eb1597e864c51b3f56733cb2e8a90bf0c284bfc05f9444d81c558bc848aa
+Status: Downloaded newer image for hello-world:latest
+ docker OK (overlay2; data-root /var/lib/docker)
+ live-restore: on
+ /var/lib/docker is a real mount: /dev/mapper/pve-vm--9100--disk--1[/docker] ext4
+ /mnt/sys_drive is a real mount: /dev/mapper/pve-vm--9100--disk--1[/sys_drive] ext4
+ both paths are ONE filesystem: /dev/mapper/pve-vm--9100--disk--1 23317576
+[golden] baking the in-guest controller image gitea.dooplex.hu/admin/felhom-controller:0.318.0 (no registry cred at deploy) …
+
+WARNING! Your credentials are stored unencrypted in '/root/.docker/config.json'.
+Configure a credential helper to remove this warning. See
+https://docs.docker.com/go/credential-store/
+
+0.318.0: Pulling from admin/felhom-controller
+774043ccc8cc: Pulling fs layer
+ab6b448d4be9: Pulling fs layer
+23a5bfa58353: Pulling fs layer
+862a57157567: Pulling fs layer
+a7bd8aa6efbb: Pulling fs layer
+0cbfef0f6e91: Pulling fs layer
+862a57157567: Waiting
+a7bd8aa6efbb: Waiting
+0cbfef0f6e91: Waiting
+774043ccc8cc: Verifying Checksum
+774043ccc8cc: Download complete
+862a57157567: Verifying Checksum
+862a57157567: Download complete
+23a5bfa58353: Verifying Checksum
+23a5bfa58353: Download complete
+a7bd8aa6efbb: Verifying Checksum
+a7bd8aa6efbb: Download complete
+0cbfef0f6e91: Verifying Checksum
+0cbfef0f6e91: Download complete
+ab6b448d4be9: Verifying Checksum
+ab6b448d4be9: Download complete
+774043ccc8cc: Pull complete
+ab6b448d4be9: Pull complete
+23a5bfa58353: Pull complete
+862a57157567: Pull complete
+a7bd8aa6efbb: Pull complete
+0cbfef0f6e91: Pull complete
+Digest: sha256:e0e788ae67adf3b60efdd042470cd4ea1d5e5b3a7fa77685f67dcb9892f8ea20
+Status: Downloaded newer image for gitea.dooplex.hu/admin/felhom-controller:0.318.0
+gitea.dooplex.hu/admin/felhom-controller:0.318.0
+[golden] asking the controller which infra images it manages …
+[golden] baking infra images (4): traefik:v3.7.13 cloudflare/cloudflared:2026.9.3 gtstef/filebrowser:1.5.6-stable gitea.dooplex.hu/admin/felhom-samba:1.1.0 …
+v3.7.13: Pulling from library/traefik
+e2de96513ba9: Pulling fs layer
+b686a4f73445: Pulling fs layer
+78cb21c375ca: Pulling fs layer
+acb2f33459b1: Pulling fs layer
+acb2f33459b1: Waiting
+e2de96513ba9: Verifying Checksum
+e2de96513ba9: Download complete
+b686a4f73445: Verifying Checksum
+b686a4f73445: Download complete
+acb2f33459b1: Verifying Checksum
+acb2f33459b1: Download complete
+78cb21c375ca: Verifying Checksum
+78cb21c375ca: Download complete
+e2de96513ba9: Pull complete
+b686a4f73445: Pull complete
+78cb21c375ca: Pull complete
+acb2f33459b1: Pull complete
+Digest: sha256:24841fe2de7304c149343d877d2923b4c8800a38ba015dea9174c23b20e344a0
+Status: Downloaded newer image for traefik:v3.7.13
+docker.io/library/traefik:v3.7.13
+2026.9.3: Pulling from cloudflare/cloudflared
+2cc7ee286bf3: Pulling fs layer
+c172f21841df: Pulling fs layer
+218cf840d0d9: Pulling fs layer
+f6069939f718: Pulling fs layer
+d6b1b89eccac: Pulling fs layer
+2780920e5dbf: Pulling fs layer
+7c12895b777b: Pulling fs layer
+3214acf345c0: Pulling fs layer
+52630fc75a18: Pulling fs layer
+dd64bf2dd177: Pulling fs layer
+b839dfae01f6: Pulling fs layer
+ebddc55facdc: Pulling fs layer
+c4bc6f35ff5e: Pulling fs layer
+b96fe2995f90: Pulling fs layer
+58c0c263dc73: Pulling fs layer
+bd8962e29291: Pulling fs layer
+cac2ae0193cb: Pulling fs layer
+f0383d5ebc47: Pulling fs layer
+52630fc75a18: Waiting
+dd64bf2dd177: Waiting
+b839dfae01f6: Waiting
+ebddc55facdc: Waiting
+c4bc6f35ff5e: Waiting
+b96fe2995f90: Waiting
+58c0c263dc73: Waiting
+bd8962e29291: Waiting
+cac2ae0193cb: Waiting
+f0383d5ebc47: Waiting
+d6b1b89eccac: Waiting
+2780920e5dbf: Waiting
+7c12895b777b: Waiting
+3214acf345c0: Waiting
+f6069939f718: Waiting
+2cc7ee286bf3: Verifying Checksum
+2cc7ee286bf3: Download complete
+c172f21841df: Download complete
+218cf840d0d9: Download complete
+f6069939f718: Verifying Checksum
+f6069939f718: Download complete
+d6b1b89eccac: Verifying Checksum
+d6b1b89eccac: Download complete
+2780920e5dbf: Verifying Checksum
+2780920e5dbf: Download complete
+2cc7ee286bf3: Pull complete
+7c12895b777b: Verifying Checksum
+7c12895b777b: Download complete
+3214acf345c0: Verifying Checksum
+3214acf345c0: Download complete
+52630fc75a18: Verifying Checksum
+52630fc75a18: Download complete
+dd64bf2dd177: Verifying Checksum
+dd64bf2dd177: Download complete
+b839dfae01f6: Verifying Checksum
+b839dfae01f6: Download complete
+ebddc55facdc: Verifying Checksum
+ebddc55facdc: Download complete
+c4bc6f35ff5e: Download complete
+c172f21841df: Pull complete
+b96fe2995f90: Verifying Checksum
+b96fe2995f90: Download complete
+bd8962e29291: Verifying Checksum
+bd8962e29291: Download complete
+58c0c263dc73: Verifying Checksum
+58c0c263dc73: Download complete
+cac2ae0193cb: Verifying Checksum
+cac2ae0193cb: Download complete
+f0383d5ebc47: Verifying Checksum
+f0383d5ebc47: Download complete
+218cf840d0d9: Pull complete
+f6069939f718: Pull complete
+d6b1b89eccac: Pull complete
+2780920e5dbf: Pull complete
+7c12895b777b: Pull complete
+3214acf345c0: Pull complete
+52630fc75a18: Pull complete
+dd64bf2dd177: Pull complete
+b839dfae01f6: Pull complete
+ebddc55facdc: Pull complete
+c4bc6f35ff5e: Pull complete
+b96fe2995f90: Pull complete
+58c0c263dc73: Pull complete
+bd8962e29291: Pull complete
+cac2ae0193cb: Pull complete
+f0383d5ebc47: Pull complete
+Digest: sha256:072c067d25ccbe61d46e18f0d0723255f2bb5304f7317caa95b27031520ff92c
+Status: Downloaded newer image for cloudflare/cloudflared:2026.9.3
+docker.io/cloudflare/cloudflared:2026.9.3
+1.5.6-stable: Pulling from gtstef/filebrowser
+55afa1ecc21d: Pulling fs layer
+8ed8f35f8d4f: Pulling fs layer
+989b226a579c: Pulling fs layer
+660aeead31d5: Pulling fs layer
+4f4fb700ef54: Pulling fs layer
+adce24567e4c: Pulling fs layer
+f17ea56b313b: Pulling fs layer
+6b6f3b3efe88: Pulling fs layer
+4ed1ca4f3fce: Pulling fs layer
+e6fc9c6a5757: Pulling fs layer
+d47782d1182a: Pulling fs layer
+6b6f3b3efe88: Waiting
+4ed1ca4f3fce: Waiting
+e6fc9c6a5757: Waiting
+d47782d1182a: Waiting
+4f4fb700ef54: Waiting
+adce24567e4c: Waiting
+f17ea56b313b: Waiting
+660aeead31d5: Waiting
+55afa1ecc21d: Verifying Checksum
+55afa1ecc21d: Download complete
+660aeead31d5: Verifying Checksum
+660aeead31d5: Download complete
+8ed8f35f8d4f: Verifying Checksum
+8ed8f35f8d4f: Download complete
+989b226a579c: Verifying Checksum
+989b226a579c: Download complete
+4f4fb700ef54: Verifying Checksum
+4f4fb700ef54: Download complete
+f17ea56b313b: Verifying Checksum
+f17ea56b313b: Download complete
+6b6f3b3efe88: Verifying Checksum
+6b6f3b3efe88: Download complete
+4ed1ca4f3fce: Verifying Checksum
+4ed1ca4f3fce: Download complete
+e6fc9c6a5757: Verifying Checksum
+e6fc9c6a5757: Download complete
+adce24567e4c: Verifying Checksum
+adce24567e4c: Download complete
+d47782d1182a: Verifying Checksum
+55afa1ecc21d: Pull complete
+8ed8f35f8d4f: Pull complete
+989b226a579c: Pull complete
+660aeead31d5: Pull complete
+4f4fb700ef54: Pull complete
+adce24567e4c: Pull complete
+f17ea56b313b: Pull complete
+6b6f3b3efe88: Pull complete
+4ed1ca4f3fce: Pull complete
+e6fc9c6a5757: Pull complete
+d47782d1182a: Pull complete
+Digest: sha256:7c5d7ac8ffda31294d278063cf9d2e04303b39e6dce1f4c691342240ca7703b8
+Status: Downloaded newer image for gtstef/filebrowser:1.5.6-stable
+docker.io/gtstef/filebrowser:1.5.6-stable
+1.1.0: Pulling from admin/felhom-samba
+897d797d2723: Pulling fs layer
+3051591aa250: Pulling fs layer
+ce57a3f93416: Pulling fs layer
+fb94eeec2fe1: Pulling fs layer
+fb94eeec2fe1: Waiting
+ce57a3f93416: Verifying Checksum
+ce57a3f93416: Download complete
+fb94eeec2fe1: Verifying Checksum
+fb94eeec2fe1: Download complete
+897d797d2723: Verifying Checksum
+897d797d2723: Download complete
+3051591aa250: Verifying Checksum
+3051591aa250: Download complete
+897d797d2723: Pull complete
+3051591aa250: Pull complete
+ce57a3f93416: Pull complete
+fb94eeec2fe1: Pull complete
+Digest: sha256:1c17c09422bec0366d7cf0e0fcfc1486ba6c90334a0a5d5c851073a9342f8f10
+Status: Downloaded newer image for gitea.dooplex.hu/admin/felhom-samba:1.1.0
+gitea.dooplex.hu/admin/felhom-samba:1.1.0
+[golden] baking the controller-bootstrap unit (deploys the BAKED controller from the config mount) …
+Created symlink '/etc/systemd/system/multi-user.target.wants/felhom-controller-bootstrap.service' → '/etc/systemd/system/felhom-controller-bootstrap.service'.
+[golden] baking the controller-bootstrap PATH unit (starts the service on bootstrap-mount hot-plug — B1) …
+Created symlink '/etc/systemd/system/multi-user.target.wants/felhom-controller-bootstrap.path' → '/etc/systemd/system/felhom-controller-bootstrap.path'.
+[golden] baking the first-boot SSH host-key regeneration unit (F3) …
+Created symlink '/etc/systemd/system/multi-user.target.wants/felhom-regen-hostkeys.service' → '/etc/systemd/system/felhom-regen-hostkeys.service'.
+[golden] identity-clean + minimize …
+[golden] stop + archive …
+INFO: including mount point rootfs ('/') in backup
+INFO: including mount point mp0 ('/var/lib/felhom') in backup
+INFO: archive file size: 618MB
+INFO: Finished Backup of VM 9100 (00:00:40)
+[golden] DONE. golden archive volid: local:backup/vzdump-lxc-9100-2026_10_16-09_18_45.tar.zst (rootfs 32G + ONE data volume 24G @ /var/lib/felhom, all in the archive)
+[golden] publishing golden (649065920 bytes, sha256 18077b6a689a06f3…) → https://gitea.dooplex.hu/api/packages/admin/generic/felhom-golden/0.318.0/golden.tar.zst
+[golden] pre-delete existing: HTTP 404 (404/204 expected)
+[golden] upload OK (HTTP 201)
+GOLDEN_VERSION=0.318.0
+GOLDEN_SHA256=18077b6a689a06f3e2c08deefe939c631124f07ffc64533ec3896e75d61a4654
+[golden] Record in the hub operator UI (Configs → Day-0 artifacts): golden 0.318.0 / 18077b6a689a06f3e2c08deefe939c631124f07ffc64533ec3896e75d61a4654
+[golden] (the build guest 9100 is stopped; destroy it with: pct destroy 9100 --purge)
diff --git a/website/CHANGELOG.md b/website/CHANGELOG.md
index 496d2576..62da1dec 100644
--- a/website/CHANGELOG.md
+++ b/website/CHANGELOG.md
@@ -1,4 +1,11 @@
-## 2026-10-15 (evening) — Prowlarr's card: no button any more (R-1058)
+## 2026-10-16 — the backup page: one-disk boxes (storage identity build B)
+
+- `biztonsagimentes.html` / `en/backups.html`: a new paragraph pair „Ha a gépben csak egy lemez van" / „If the machine has
+ only one disk" — the new install's own data area (outside the full system backup), and what protects against a disk failure
+ (another disk or the remote backup; Felhom counts a second copy only on a disk it can prove is different). Published only
+ after it became true: agent 0.158.1 + golden 0.318.0 vouched and installer 1.33.0 published the same morning.
+
+## 2026-10-15 (evening) — Prowlarr's card: no button any more (R-1058)
- The card says the box links Prowlarr to Sonarr and Radarr whichever is installed first (controller 0.314.0, the floor).
diff --git a/website/biztonsagimentes.html b/website/biztonsagimentes.html
index 03103090..256bd383 100644
--- a/website/biztonsagimentes.html
+++ b/website/biztonsagimentes.html
@@ -264,6 +264,10 @@
A távoli mentés helye: a Felhom dobozon a távoli másolat egy általunk biztosított tárhelyre kerül, titkosítva. A „haver rendszer” és az iroda általános lehetőségek a 3-2-1 szabályhoz – ezeket ma nem állítjuk be.
+
Ha a gépben csak egy lemez van
+
Az új telepítés a lemezen létrehoz egy saját adatterületet („Belső tárhely”) a fényképeknek, filmeknek és dokumentumoknak. Az alkalmazások plusz lépés nélkül ide települnek, és a nagy fájlok nem kerülnek bele a teljes rendszermentésbe, így az kicsi és gyors marad.
+
Egy lemezen minden helyi másolat ugyanazon a lemezen van. Ez véd a véletlen törlés és a hibás fájlok ellen, de egy lemezhiba ellen nem. Lemezhiba ellen egy másik lemez vagy a távoli mentés véd. A Felhom ezt meg is mutatja: csak akkor számol második másolatot, ha biztosan tudja, hogy az egy másik lemezen van, és ha ezt nem tudja ellenőrizni (például egy virtuális gépben), azt ki is írja.
+
A helyreállítási kód – amit csak te ismersz
A távoli mentésed titkosított, és a titkosítás kulcsa egy helyreállítási kód. Ez a kód pontosan egyszer jelenik meg: a te képernyődön, a beállításkor. Nálunk nem marad belőle másolat.
Ez tudatos döntés, és két oldala van. Az egyik, hogy a távoli mentésedet rajtad kívül senki nem tudja elolvasni – mi sem. A másik, hogy ha a doboz megsemmisül és a kód is elveszett, akkor a távoli mentés nekünk sem visszaállítható. Ezért a kód papírra kerül, és jó helyre.
Where the remote backup goes: on a Felhom box the remote copy goes, encrypted, to storage we provide. The "buddy system" and the office are general options for the 3-2-1 rule – we do not set them up today.
+
If the machine has only one disk
+
A new install makes its own data area („Internal storage”) on the disk for photos, films and documents. Apps install there with no extra step, and the big files stay out of the full system backup, so that backup stays small and fast.
+
On one disk, every local copy is on the same disk. That protects against deleting something by mistake and against broken files, but not against a disk failure. A different disk or the remote backup protects against a disk failure. Felhom shows this too: it counts a second copy only when it knows for sure that the copy is on another disk, and when it cannot check that (for example inside a virtual machine), it says so.
+
The recovery code – only you know it
Your remote backup is encrypted, and the key to the encryption is a recovery code. The code appears exactly once: on your screen, when it is set up. We keep no copy of it.
This is a deliberate choice, and it has two sides. One: nobody but you can read your remote backup – not even us. The other: if the box is destroyed and the code is lost too, then we cannot restore the remote backup either. So the code goes on paper, and somewhere safe.