diff --git a/documentation/backlog/OPEN-ITEMS.md b/documentation/backlog/OPEN-ITEMS.md index fbe0515..315c5bc 100644 --- a/documentation/backlog/OPEN-ITEMS.md +++ b/documentation/backlog/OPEN-ITEMS.md @@ -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=&full_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. diff --git a/documentation/tests/finalwalk-r201-2026-08-07/journal.md b/documentation/tests/finalwalk-r201-2026-08-07/journal.md new file mode 100644 index 0000000..8ed34bb --- /dev/null +++ b/documentation/tests/finalwalk-r201-2026-08-07/journal.md @@ -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.