# REPORT — the fifth walk (R-201), 2026-08-07 **Runbook-style validation, supervised. One machine destroyed on purpose, with the operator's confirmation at the §6 STOP. No product code written.** Venue: `demo-hp` VM **325 `walk5-appliance`**, customer `walk5`, host `walk5-4bada5`. Full evidence: `documentation/tests/walk5-r201-2026-08-07/`. --- ## 1. THE VERDICT — both halves, separately ### THE DATA: **PASS** All three sentinels came back **byte-identical** out of snapshot `5b0f20f7`, under the key recovered from the sealed package with R: ``` 11eb7fb2d1891f62a685e3d9a9fda44e0a342d437d4aebaa15fcb4c0fd79d539 61 WALK5-SENTINEL-A.txt 6b504d1e83bf4c673334d0b9e701f3e5f07311d954fdc4463a6b0a55b261ae32 66 WALK5-őrszem-ékezetes-árvíztűrő.txt 0baaf402733e6a85f3d9ce8c4c3a57b05692f5f6733da6a23da76d2cd7635210 12582912 WALK5-SENTINEL-C-12MB.bin name hex 57414c4b352d c591 72737a656d2d c3a9 6b657a657465732d c3a1 7276 c3ad 7a74 c5b1 72 c591 2e747874 ``` Identical to Phase A in every byte **including the accented filename's name bytes**. Read back with `os.listdir` on a **bytes** path, so no decode/encode round trip could launder a `U+FFFD` into looking correct — the check that caught this three times before. ### THE JOURNEY: **PASS — the first time in five walks** **No step needed a command line inside the guest.** Everything that *progressed* the journey was an HTTP request a browser makes. The previous walk needed **three** guest command lines; this needed **zero**. The reset-code hatch was used **once, in Phase A**, where §3 permits it. **Named per §3 so the claim is not read wider than it is** — the guest command lines used were the `w5watch.log` sampler, `docker logs`, the settings reads, the restic listing and the final sentinel verification. **All instrumentation:** none changed state, none was needed to progress, and removing them all would have changed nothing but my ability to describe what happened. --- ## 2. §5's OBSERVATION — the first live exercise of R-241's fix, and it stands on its own **At 14:58:52Z, unaided, before anyone had logged in:** ``` [WARN] [offbox] NOT minting a repository password: the hub holds a sealed recovery package for this box, and a fresh key would orphan the history that package protects (R-241). The transport is configured; the tier stays down until the customer's recovery code places the escrowed key. [INFO] [offbox] apply-offsite: transport configured …, tier HELD awaiting the escrowed key ``` | §5 asks | answer | |---|---| | does it declare a need, and when is it staged/collected? | **yes** — declared `needs_credential` 14:38:49Z and 14:53:49Z; hub staged **14:56:34Z**; collected + applied **14:58:52Z**. **Zero human actions**, on a box not yet claimed | | **is any repository key written?** | **NO** — sampled every ~20 s from 14:24:52Z; `repo_password` absent at every sample. The directory holds `applied_marker`, `known_hosts`, `ssh_key` and nothing else | | what state does it report instead? | `enabled=true`, `escrow_state=pending`, no key → the derived **`awaiting_recovery_key`** holding state | | the two fingerprints, before login | hub's package seals `eabf427c7274…144f`; **the box holds NONE** | **Positive control, because an absent line is not evidence:** the scheduler logged `agent-channel-health` ×5, `stack-scan` ×2, `system-health`, `backup-cache` and `offsite-credential-retry` in the same window. The absence of a mint is **explained**, not merely observed. > **HONEST SCOPE.** With the mint guard holding there is **no local key**, so the offer fires on > **shape (a)**, not shape (c). Shape (c) was measured in **Phase A, in its negative half** — hub hash > == local hash, correctly silent. **This walk proves the mint guard positively and the discriminator > negatively.** A positive shape-(c) firing needs a box holding a *different* key, which v0.206.0 now > prevents from arising by itself. --- ## 3. THE RTO **71.7 s**, login (15:04:25.417Z) → open store (15:05:37.156Z). Of that, **12.44 s was the unseal itself**; ~22 s was **my own harness retry** (I scraped the CSRF token from a `` tag the recovery page does not carry, got a 403, re-read it from the form). **A customer clicking the button sees ≈50 s.** Both numbers are given because 71.7 s is what was measured. --- ## 4. DEAD ENDS, in the customer's terms **By §3's definition — something needing a shell inside the guest — there were ZERO.** Two obstacles were met, both cleared **from the dashboard**, and **neither is signposted**: | # | what the customer sees | what got past it | known? | |---|---|---|---| | 1 | „nincs elérhető adatmeghajtó a visszaállításhoz" | Tárhely → Meghajtók → „Meglévő meghajtó csatolása" re-registers both surviving disks | **NEW — R-252** | | 2 | „a(z) calibre-web nincs telepítve — előbb állítsd helyre az alkalmazást" — **on a page that says three lines above „Nincs telepítve — a visszaállítás előbb újratelepíti"** | redeploy from the catalogue (~90 s), then re-run the restore | **NEW — R-253** | **So: the machinery works end to end and the data is provably safe. The unaided journey now succeeds, and it succeeds through two obstacles a customer must guess their way past.** --- ## 5. WHAT EACH INSTALL LANDED ON — and delivery is part of the pass | | vouched | first install | after the rebuild | |---|---|---|---| | agent | 0.127.0 | **0.127.0** | **0.127.0** | | controller | golden 0.206.0 | **0.206.0** | **0.206.0** | **No hand upgrade either time, and no downgrade on the reinstall.** This is the first walk of the five where the box under test **is the box a customer receives** — R-239's delivery gap, the headline of both previous walks, is closed for this run. --- ## 6. THE RECOVERY SCREEN, QUOTED Appeared **without being sought**: `/` → 302 `/launcher` → 302 **`/recovery`**. > „Ezt a gépet újratelepítették. **A korábbi, házon kívüli mentéseid megvannak** — a Felhom központi > rendszere őriz hozzájuk egy lezárt csomagot, amelyet **2026-08-07T12:51:02Z** zártunk le. […] > **A helyreállítási kódot senki nem tudja pótolni** — sem a Felhom, sem az ügyfélszolgálat, sem az > üzemeltető. […] Ha megadod a kódot, **feloldjuk a mentéseid zárolását és megmutatjuk, mi van > bennük**. **Ebben a lépésben semmit nem állítunk vissza és semmi nem változik.**" The sealed-at timestamp **matches `host_escrow.created_at` exactly**. *(Copy wart, recorded not filed: it is a raw ISO-8601 string on a Hungarian customer screen where every other date reads `2026-08-07 14:57`.)* --- ## 7. THE LISTING, against Phase A | | Phase A | the screen | |---|---|---| | app | `calibre-web` | **`calibre-web`** ✅ | | when | `5b0f20f7` @ 12:57:41Z | **2026-08-07 14:57** ✅ (CEST) | | size | 12.784 MiB | **12.8 MB** ✅ | A second row `felhom-offbox · 12.8 MB` also appears — the tier's marker tag rendered as an app, and the total doubled. **R-251.** --- ## 8. §4.6's TWO PRE-DESTRUCTION CHECKS — both pass, neither previously exercised on a clean box - **The recovery offer is NOT shown**: `/` → `/launcher`, **zero** recovery mentions on either landing page, `/recovery` 302s. And the reason is measured, not assumed — box key, box's ACK-cached hub hash and hub `restic_pw_sha256` are all `eabf427c7274…144f`, so **shape (c) compares equal and stays silent**. - **The restore page lists the app with the future-backup toggle OFF** — identical rendering both ways. **R-237's fix, live**; the last walk measured 0 entries and a 302 here. --- ## 9. PHASE A's SEVEN RECORDS Controller `0.206.0` · agent `0.127.0` · PBS wrapper **matches vouched** · guests 1/1 · DR recipe **present** · key escrow **present** · snapshot `5b0f20f7` · 1 snapshot · **12.0 MB** (12 611 563 B) · `host_escrow` blob **383 B**, `identity_blob` **572 B**, `stale_at` **NULL**, 0 superseded rows · escrowed key fingerprint `a6:86:f7:fb:…:4c:f9` · box key == hub hash == `eabf427c7274…144f`. **Sentinels listed BY NAME** out of the snapshot with `restic ls latest --long` — see §1. > **The §4.5 gate earned its place again, and this time it caught MY fault.** The first off-site run > reported **`ok` in 28 s with 0 snapshots**: I had sent the per-app toggle as `enabled=1`, and the > handler accepts only `on`/`true`, so it recorded *off* and the run correctly backed up nothing. > Re-toggled, selection verified in the rendered page, re-run → 1 snapshot, 12.0 MB. **A green tick is > not evidence a file is in a snapshot.** --- ## 10. R — SHREDDED, with a working control One `0600` file on **DooPlex only**, never rendered, never an argument, never a log line. Shape only: **82 characters, 10 hyphen-separated tokens**. ``` plant → ~/.config/walk5/R_PLANTED_CONTROL.txt sweep → 2 hits (the real file + the planted control) ← the control PROVES the sweep works shred → both, then the pattern file itself sweep → 0 hits ``` **Every sweep path was asserted to exist first** — a sweep pointed at a missing path returns zero for the wrong reason. The appliance's copy was `shred -u`'d mid-walk and its absence verified. --- ## 11. NEW FINDINGS — the highest register ID moved **R-248 → R-253** | ID | | |---|---| | **R-249** | **The retrieval passphrase ships in the customer page's HTML** (`data-secret`), so any headless read puts it in a transcript — with no reveal action and **no audit event**, where the break-glass credential emits one. Found by doing it. **MEDIUM** | | **R-250** | **A customer create can fail fail-closed** because the host-key scan ladder (~60 s) is shorter than the fresh sub-account's DNS/**AAAA-before-A** settle (~100 s measured). Retry is safe and idempotent; nothing says so. **LOW-MEDIUM** | | **R-251** | The recovery listing renders **one row per restic tag**, showing the customer an "app" they never installed and their data counted twice. **Cosmetic** | | **R-252** | After a rebuild the restore refuses — **the drives lost their registration** — and nothing on the recovery path says to re-attach them | | **R-253** | The restore refuses because the app is not installed, **on a page that says the restore reinstalls it**. Two shipped sentences that contradict each other, in the customer's language, at the last step of a recovery | **Recorded against an existing row rather than minted:** **R-243** claims `offsite_delivery_stuck` "skips the applied shape". **On a rebuild it does not skip** — 88 s after the destruction the hub emitted the warning and wrote an **operator-channel** `notification_log` row naming a guest rebuild as the cause, correctly. The gap is real for the state R-243 describes and **not** for the state a rebuild produces; the row is annotated so it is not read wider than it measures. --- ## 12. TEARDOWN — OWED, not done The machine is the evidence until the verdict is written. Full enumeration, the "before" measurements, the stop-and-age gate, and the positive controls that must survive: `documentation/tests/walk5-r201-2026-08-07/teardown-owed.md`. **R-244's residue will grow by this venue.** --- ## 13. WHAT DID NOT RUN, AND WHY - **A positive shape-(c) firing.** Structurally unreachable on a healthy v0.206.0 rebuild — see §2. - **A soak / scheduled cycle.** The previous walk covered it; §7 does not ask for one and adding it would have delayed the destruction past the operator's window. - **Any product code.** §0 forbids it: five findings were filed and the walk continued. - **Teardown.** §10 defers it deliberately. - **`felhom-offbox`'s second listing row and the raw ISO date** were observed, not chased. ## Documents updated `00-capability-map.md` (the unaided-recovery row → **PROVEN-LIVE, scoped**), `OPEN-ITEMS.md` (**R-201 CLOSED**; R-249…R-253 filed; R-243 annotated), `STATUS.md` (headline changed; trimmed 97 → 92 lines rather than extended), and the journal + teardown ledger.