R-201 CLOSED — the unaided recovery journey passes, both halves, on the fifth walk
gates / gates (push) Successful in 17s

Capability map: the unaided-recovery row turns FAILED -> PROVEN-LIVE, scoped, with
what it still does not claim stated in the row itself: shape (c) did not fire
positively (with the mint guard holding there is no local key, so the offer comes
from shape (a)); and 'unaided' here means possible-without-a-shell, not obvious,
because two obstacles are unsignposted.

OPEN-ITEMS: R-201 closed with its evidence. Five new rows R-249..R-253 (the
retrieval passphrase in page HTML; the host-key scan ladder vs AAAA settle; the
listing's per-tag rows; the two unsignposted restore steps). R-243 annotated
rather than re-filed: on a REBUILD offsite_delivery_stuck does not skip, so the
row's gap is narrower than it reads.

STATUS.md: headline changed, and trimmed 97 -> 92 lines rather than extended, per
its own header.

Teardown recorded as OWED with its before-measurements, the stop-and-age gate, and
the positive controls that must survive.
This commit is contained in:
2026-08-07 17:24:27 +02:00
parent 0691bc59a5
commit 3f4fb3825f
5 changed files with 338 additions and 34 deletions
@@ -0,0 +1,73 @@
# Teardown — OWED, not done (walk5, the fifth walk, 2026-08-07)
**Deliberately not performed in this session, per §10: the machine is the evidence until the verdict
is written.** The verdict is written (`journal.md`); the venue still stands so it can be re-read if
anything in this report is questioned. **Predecessor ledgers:** `teardown-finalwalk-2026-08-07.md`,
`teardown-2026-08-06.md`.
## The enumeration, matched on IDENTITY — never on size
Size is not a key here: on 2026-08-06 an item that measured exactly the expected size turned out to be
a working store.
| Layer | Item | Identified by |
|---|---|---|
| **machine** | `demo-hp` VM **325** `walk5-appliance` — 4 disks (efidisk + 200 G + 50 G + 50 G), **17 G actual** on `/mnt/nvme-1tb/images/325` | `qm config 325``name: walk5-appliance` |
| **hub** | customer **`walk5`**, host **`walk5-4bada5`** | `GET /configs/walk5/delete` preview + a FULL-SCHEMA census |
| **off-site** | Storage Box sub-account **285351**, user `u629488-sub4`, home naming the customer | Hetzner API, matched on the home directory |
| **off-site** | `ep0` PBS namespace **`walk5`** in datastore `felhom-offsite` | `ls /mnt/pbs-datastore/ns`**the live store is `/mnt/pbs-datastore`; `/srv/pbs-felhom` is STALE and reading it gives a wrong answer in both directions** |
| **network** | WireGuard peer **10.77.0.5** | `wg_peers.host_id = walk5-4bada5`; verify removal on ep0's **live `wg show`**, not only in the hub DB |
| **DooPlex** | `~/.config/walk5/``dashboard_pw.txt`, `root_pw.txt`, `root_pw_rotated.txt`, `breakglass.json`, `retrieval_passphrase.txt`, `claim_code.txt` (all `0600`) | **`R_walk5.txt` is already `shred -u`'d, with a planted-copy control proving the sweep works** |
| **DooPlex** | the `walk5` block in `~/.ssh/config`, and the appliance's host key in `~/.ssh/known_hosts` | |
## `pvesm status` BEFORE (2026-08-07, venue standing)
```
c11-scratch dir active 983379700 KiB total 23680040 KiB used 909673048 KiB avail 2.41%
```
Take it again after; the delta should be ≈ 17 G. (`c11-scratch` and `felhom-backup` are two `dir`
entries over the **same** path `/mnt/nvme-1tb`, so they move together — do not read that as double
counting.)
## The gate that shapes the operation
**The cascade REFUSES to delete a live host** — there is no hub decommission endpoint; the word appears
only in the refusal. So VM 325 must be **stopped first** (guarded on `qm config 325` reading
`name: walk5-appliance``demo-hp` also carries a guest 9201, and the appliance carries its own) and
the hub allowed to age it past its `stale_threshold` (**30 m**, read from the deployed `hub-config`,
not assumed). Poll `GET /hosts/walk5-4bada5/delete-impact` for `deletable` — and **treat an empty
response as retry, not as success**.
Then `POST /configs/walk5/delete` with all six gates: `ack_hosts=1 ack_reset=1 ack_purge=1
confirm_id=walk5 expect_hosts=1`.
## What will NOT be gone, and must be checked rather than assumed — R-244
A full-schema census after the cascade will return rows, not zero. Four sources are **deliberate**
(`events`, `notification_log`, `host_deletions`, `customer_resets` — *"provenance/events are NEVER
wiped"*). The fifth is the open gap: **`app_log_issues`**, which the residue purge does not touch.
**Measured 2026-08-08 across the whole table:** 1309 rows, of which **71 reference a torn-down venue**
(`finalwalk`, `c11`, `rewalk`, `part4`) — **44 orphans** (safely deletable) and **27 shared with a live
customer** (`demo-felhom`, `peti-felhom`, …) which must be **de-referenced, never deleted**. **This
walk will add to that count.** Do not attempt a `DELETE … WHERE customer LIKE` — it would destroy a
live customer's issue history. R-244 carries the proposed shape.
**A per-table absence query is not a census.** The verification is a full-schema sweep, and that is
what found this.
## Positive controls the teardown must keep (each must SURVIVE)
- `qm list` still shows VM **300 `drill-r50`** — the protected drift fixture.
- Guest **9201 on `demo-hp` itself** still running (the host was never the target).
- Storage Box sub-accounts **`u629488-sub1/2/3`** (demo-felhom, peti-felhom, demo-hp) still present.
- `ep0` namespaces **`demo-felhom`** and **`demo-hp`** still present.
- WireGuard peers **10.77.0.2/.3/.4/.250** still on `wg0`.
- Hub rows for `demo-felhom`, `demo-hp`, `peti-felhom`, `david` untouched.
## One extra item this walk adds
**The `walk5` retrieval passphrase is compromised** — it reached a session transcript from the customer
page's `data-secret` attribute (**R-249**). It dies with this customer's deletion, which is the reason
the teardown should not be left indefinitely. No other walk5 secret left its `0600` file.