final walk Phase A + the five checks; R-239 (delivery gap) and R-240 filed
gates / gates (push) Failing after 13m22s

Phase A complete on a NEW venue (demo-hp VM 324, customer finalwalk). Installed
from the published ISO — verified byte-identical to iso.felhom.eu — claimed, app
deployed, three sentinels placed, escrow ceremony 6/6 with restic_pw_sealed=true,
R held in one 0600 file on DooPlex, off-site backup taken and the three sentinels
PROVEN IN THE SNAPSHOT BY NAME (snapshot 1da4f80d, 12.0 MB).

THE HEADLINE: a fresh install lands on agent 0.127.0 (vouched, no hand upgrade —
that half works) and controller 0.203.0, while the newest is 0.205.0. The vouched
golden still bakes 0.203.0, so tonight's box has neither R-237 nor R-234. Filed as
R-239: a delivery gap, not a regression. Every closure claimed for those two is
true of the code and false of the fleet until a golden is baked and vouched.

The five checks, on that box:
  T1 ok + the old bare-count warning (no next step)
  T2 FAILS — both runs say "elindult", the second as a success flash
  T3 FAILS — toggle off hides an existing snapshot; wizard 302s away
  T4 ok, and the wording is still "Sikeres" beside "nothing is selected" -> R-240
  T5 PASSES — driven as a browser does, prepare -> full_prep -> confirm -> commit
     completed; R-238 confirmed a harness artifact, not a product defect

HARNESS FAULT, caught by the §4 gate: the first off-site run reported ok with a
26.6 KB repo — impossible for a 12 MB sentinel. I had placed the files under
.../adatok/felhom-data/userdata/... while this box's namespace root is
/mnt/felhom-drives/adatok directly. The product was correct throughout; proving by
listing rather than by a green status is what caught it before any destruction.

Nothing destroyed. The venue stands.
This commit is contained in:
2026-08-07 00:42:59 +02:00
parent feed748325
commit 2d2d8d3ddc
2 changed files with 115 additions and 0 deletions
+3
View File
@@ -164,6 +164,9 @@ the fault was real. Full observables: `tests/campaign11-evidence-2026-08-05/jour
| **R-237** | **After a successful recovery the customer is shown no backups at all, because the restore surface is keyed on apps that are currently installed and currently marked for future remote backup.** Measured 2026-08-06. Post-rebuild, with the key recovered, the tier configured and the escrow re-sealed, `/backups/restore` said „**Nincs telepített alkalmazás**" and „Nincs távoli mentésre jelölt alkalmazás — a kijelölés a Távoli mentés oldalon történik" — pointing at a page which itself said there were no installed applications. A **circular dead end**: to restore an app you must select it; to select it, it must be installed; to know what to install, you must see the backup you cannot see. Reaching the restore actually required three undocumented steps in order — re-attach the drives, redeploy the app, and toggle it on for **future** remote backups (`/backups/restore/app` refuses with „Ez az alkalmazás nincs távoli mentésre kijelölve", i.e. a *forward-looking* setting gates a *backward-looking* action). None of this is hinted at by the recovery screen, which says „Nincs teendőd". A household that has just lost its box does not know which apps it used to run. | **CLOSED 2026-08-06** — controller v0.204.0: the list is now built from `OffsiteInventoryList` (the repository's own snapshot tags). Installed-ness became a property OF a row, never a filter; an unreadable store renders as UNKNOWN **and keeps the action offered**; `felhom-offbox` and `_shares` are excluded. 7 new tests incl. a rendered-page test for the rebuilt shape, and a red-proof that keys the list back on installed-and-toggled apps. |
| **R-238** | ~~**„Teljes visszaállítás előkészítése" accepts the click and does nothing.**~~ **RECLASSIFIED 2026-08-06 — a HARNESS ARTIFACT, with a real residue that IS fixed.** Measured 2026-08-06, repeatedly. `POST /backup/offbox/restore` with `mode=full` (the exact form the page renders) returns **302**, and then: no job is ever recorded (`/api/backup/restore-status` `last` stays `null` across ~9 minutes of polling), the wizard stays on step 1 „Előkészítés" with the same two forms, no error is shown to the customer, and **the controller's own debug ring contains no line for it at all** — zero `offbox`, `prepare` or `snapshot` entries. `mode=unit` on the identical form works and reports properly, so the plumbing and the session are fine. This is the terminal dead end of the recovery journey: everything upstream succeeded — code accepted, key recovered, tier configured, escrow re-sealed, drives re-attached, app redeployed — and the customer still cannot get their files back. **PASS for the R-201 re-walk was defined as a sentinel's sha256 byte-identical after recovery; this is why that criterion was NOT met.** **The diagnosis** (`restore_wizard.go`, `offbox_handlers.go:314`): `mode=full` without `confirm=1` is **step 1 of a deliberate two-step** — it computes size + headroom, **starts no job by design**, and redirects carrying `&full_prep=<app>&full_size=<size>`. `deriveWizardStep` reveals the commit **only** when `FullPrepApp == App`. The endpoint driver posted step 1 and re-fetched the wizard **without** that parameter, so the pure function correctly returned the intent step, and `restore-status.last == null` was correct too. **The operator drove the same restore to completion in a browser.** The wizard was NOT re-keyed. **The residue was real and is fixed in controller v0.204.0:** neither branch of step 1 wrote anything to the log — `offboxRedirectTo` only flashes to the page — so a refusal, **including by the headroom gate**, left no trace on the box. Both branches now log, as does the concurrent-op refusal; pinned by a handler-level test with a red-proof. | **CLOSED 2026-08-06** — controller v0.204.0 |
| **R-239** | **The fixes are written, tested, pushed — and a machine installed tonight gets none of them.** Measured on the final walk (2026-08-07, `tests/finalwalk-r201-2026-08-07/journal.md`): a fresh install from the published ISO landed on agent **0.127.0** (vouched, **no hand upgrade** — that half works) and controller **0.203.0**, while the newest released controller is **0.205.0**. The vouched golden still bakes 0.203.0, so a new box has neither **R-237** (v0.204.0 — the restore list driven by the store) nor **R-234** (v0.205.0 — the skipped-app verdict and the single-flight message). **Proven from the customer's side on that box, not inferred:** T3 — with the future-backup toggle switched off, the restore page showed **0** entries for an app whose snapshot demonstrably exists, and the wizard redirected away; T2 — two off-site runs back to back both answered „A távoli mentés elindult", the second as a SUCCESS flash, which is exactly the sequence that made a customer read a stale green tick as covering an app they had just selected. **Not a regression and not a code defect — a delivery gap.** The remedy is already documented: bake a golden carrying the current controller and vouch it as a three-field change (`golden_version` + `agent_version` + `min_agent`), per `runbooks/RUNBOOK-manual-build.md` §4.1. **Until that happens, every closure claimed for R-234 and R-237 is true of the code and false of the fleet** — which is the distinction this register exists to keep. | **READY** — owner Viktor |
| **R-240** | **A backup that covered nothing calls itself „Sikeres".** On a configured box with no app selected for off-site backup, a run reports status `ok` with the warning „Sikeres — nincs mentésre jelölt alkalmazás" — *successful* immediately beside *nothing is selected*. Measured as T4 on the final walk, 2026-08-07; flagged once before (2026-08-06) and deliberately not touched then, because the task that noticed it forbade changing that path. **It is the same rhetorical shape the project has spent a fortnight removing** — R-203's *a warning beside a success is read as a success*, R-234's *„✓ Rendben" over an app that was skipped*, R-225's *unknown rendered as zero* — one notch weaker each time, and this is the weakest and last of them. The state itself is honest and must stay `ok`: an unconfigured box reporting `incomplete` forever is its own defect, pinned by a test. **The defect is the word „Sikeres", not the verdict.** Wording such as „Nincs mentésre jelölt alkalmazás — ez a futás semmit nem mentett" says the same thing without congratulating the customer on it. | **READY** — owner Viktor |
**Recorded against existing rows by Phase 2:**
- **R-216 — §4.1 is now MEASURED, not deduced.** The previous session could only offer two absences.
@@ -0,0 +1,112 @@
# THE FINAL WALK (R-201) — overnight, unattended — journal
**Venue:** `demo-hp` VM **324 `finalwalk-appliance`** (`finalwalk.felhom.eu` @ 192.168.0.142), guest
LXC **9201**, hub customer **`finalwalk`**, host id **`finalwalk-ed05d6`**. All three earlier venues
were torn down on 2026-08-06; nothing was reused except a **freed** Storage Box sub-account number.
**Written before the destruction, per §9.9.**
---
## THE HEADLINE FINDING — a fresh install does NOT get the fixes
| | landed on | vouched |
|---|---|---|
| agent | **0.127.0** ✅ | 0.127.0 |
| controller | **0.203.0** ❌ | golden 0.203.0 |
| newest released controller | **0.205.0** | — |
**No hand upgrade was needed and none was applied — that part works.** But the vouched golden still
bakes controller **0.203.0**, so a box installed tonight is **two releases behind**: it has neither
**R-237** (v0.204.0, the restore list keyed on the store) nor **R-234** (v0.205.0, the skipped-app
verdict and the single-flight message).
**This is not a regression — it is a delivery gap.** The fixes exist, are tested and are pushed; what
is missing is a golden carrying them and a vouch. Three of tonight's five checks measure exactly those
fixes, and they measure the OLD behaviour because that is what a customer receives.
Timeline: bind **21:56:42Z** → agent 0.127.0 ONLINE **21:59:01Z** (2 m 19 s) → controller 0.203.0
reporting **22:01:03Z** → guest 9201 running.
---
## Phase A — the fixture (six records, §4)
**1. Installed from the published ISO.** `felhom-installer-1.26.1-pve9.2-1.iso`, verified
**byte-identical to the published copy** (`sha256 f3cc86d5f0ec…59a6` local == iso.felhom.eu). Served
installer script tag confirmed `installer-v1.25.0` on both git-syncs.
All three known TUI traps handled: GRUB's graphical default (down+ret inside one command, terminal
installer first try); the Hungarian keymap switched to **U.S. English****positive control:** the
administrator email rendered `finalwalk@felhom.eu`, and `@` is `shift-2` on US vs `AltGr+V` on HU, the
only available evidence for the 24 masked password characters; and `--boot` set in its own `qm set`
with the ISO detached, both verified from `qm config` **before first boot** (`boot: order=scsi0`,
`ide2` lines = 0), with auto-reboot unchecked and confirmed `[ ]` with focus moved away.
Day-0 fired unaided: pairing code **`T63-485`**, matching MAC `bc:24:11:c6:73:d0`.
**2. Claimed** through the real `/claim` form. The reset-code hatch was used — **permitted in Phase A
by §3**, and it is a guest command line, so it is counted as such and does not touch the Phase-B rule.
**3. App + three sentinels.** `calibre-web` deployed with `HDD_PATH=/mnt/felhom-drives/adatok`,
`state: running` **and `health_probe.healthy: true`**.
| # | file | bytes | sha256 |
|---|---|---|---|
| A | `FINALWALK-SENTINEL-A.txt` | 57 | `863fa61c091c64488d8224b12f3915bfe264c46f9cad3d3d874b2ce725a1e5ee` |
| B | `FINALWALK-őrszem-ékezetes-árvíztűrő.txt` | 80 | `b56668663035a332ae9b8a77b5847c8310c7ff48c5c2068114060561389ccf23` |
| C | `FINALWALK-SENTINEL-C-12MB.bin` | 12 582 912 | `28630aa93119af0790b749671ef3896dbab88f8d239da8313ef5631fa068efda` |
Sentinel B's filename **as hex**, identical at source and on the box:
`46494e414c57414c4b2d c591 72737a656d2d c3a9 6b657a657465732d c3a1 7276 c3ad 7a74 c5b1 72 c591 2e747874`
`ő é á í ű ő`, **no `efbfbd`**. Written from explicit bytes via `pct push` + a Python placer; no
shell chain ever saw the name.
**4. Escrow ceremony.** Preflight **6 of 6 green** (`pbs_storage_id` · `dr_tier` · `age_binary` ·
`hub_upload` · `staged_secret` · `sudo_grant`), `agent_supported: true`.
Result: `phase: done` · **`restic_pw_sealed: TRUE`** · `uploaded: true` · `entropy_bits: 129.24` ·
`key_fingerprint: 81:dc:91:ce:a1:d0:50:3a:…:68:d5`.
**R** was claimed ONE-SHOT and streamed file→file to `~/.config/finalwalk/R_finalwalk.txt` (`0600`,
**DooPlex only**); the guest and jump-host copies were `shred -u`'d and the raw response deleted. It
was never rendered, never an argument, never a log line. Shape only: **10 words, 85 characters**.
**5. Off-site backup, and the sentinels proved BY NAME.**
```
1da4f80d 2026-08-06 22:24:33 finalwalk [felhom-offbox, calibre-web]
/mnt/felhom-drives/adatok/userdata/media/books/FINALWALK-SENTINEL-A.txt 57
/mnt/felhom-drives/adatok/userdata/media/books/FINALWALK-SENTINEL-C-12MB.bin 12582912
/mnt/felhom-drives/adatok/userdata/media/books/FINALWALK-őrszem-ékezetes-árvíztűrő.txt 80
```
> **HARNESS FAULT, and the §4 gate is what caught it.** The FIRST run reported **`ok` with a 26.6 KB
> repository** — impossible for a 12 MB incompressible sentinel. Listing showed why: I had placed the
> files under `…/adatok/**felhom-data**/userdata/…`, while this box's namespace root is
> `/mnt/felhom-drives/adatok` **directly**, so they were never in the app's data at all. **The product
> was correct throughout** — it captured the unit and the declared mandatory path, including
> calibre-web's real `metadata.db`. Moved to the right path, re-run: 12.0 MB and all three listed. The
> gate's rule — *prove by listing, never by a green status* — is exactly what stopped a destruction
> that would have proven nothing.
**6. Pre-destruction truth.** Controller `0.203.0` · agent `0.127.0` · PBS wrapper **matches
vouched** · guests **1/1** · DR recipe **present** · key escrow **present** · snapshot `1da4f80d` ·
1 snapshot · **12.0 MB** · repo `sftp:u629488-sub4@…:/home/felhom-repo` port 23.
---
## The five checks (§5) — on controller 0.203.0, which is what a customer gets
| | check | observable | verdict |
|---|---|---|---|
| **T1** | selected app that cannot be captured (`opengist`, not deployed) → run | verdict **`ok`**; warning „Figyelmeztetés: 1 alkalmazásnak nincs elérhető mentése, ezek kimaradtak: opengist"; counters intact (1 snapshot, 12.0 MB, `last_success` advanced) | **old behaviour.** v0.205.0 also keeps `ok` for an *undeployed* app — deliberately — but says which, why and what to do. Here the message is a bare count with **no next step** |
| **T2** | two off-site runs back to back | run #1 „A távoli mentés elindult…"; run #2 **the same message**, `flash_error` count **0** | **FAILS.** This is R-234's measured cause, live. v0.205.0 answers „Már fut egy távoli mentés — ez a kérés nem indított újat…" as an error |
| **T3** | toggle future-backup **off** for an app that HAS a snapshot, then open the restore page | restore entries for calibre-web: **0**; wizard **302** away | **FAILS.** R-237 exactly: the customer's existing backup is hidden by a setting about the future |
| **T4** | off-site run with nothing selected | verdict `ok`; warning **„Sikeres — nincs mentésre jelölt alkalmazás"** | unchanged, as required — **and the wording is still *"successful"* beside *"nothing is covered"*. Filed (§8) |
| **T5** | full-restore wizard driven **as a browser does** | prepare → `&full_prep=calibre-web&full_size=12.8 MB` → following it revealed the confirm → commit → **`ok: true`**, „A(z) calibre-web teljes mentése visszaállítva ellenőrző mappába" | **PASSES.** R-238 confirmed a **harness artifact**, not a product defect — carrying the state the wizard hands back makes it complete |
**Live sentinels re-verified after T5: all three MATCH** (the verification restore writes to a
separate folder and left live data untouched).
**T2 and T3 are the same finding as the headline**, seen from the customer's side: the fixes are
written and pushed but not delivered, so tonight's box still exhibits both defects.