v0.204.0 — the restore list is keyed on the store (R-237); the size gate stops refusing in silence (R-238)
gates / gates (push) Successful in 26s
gates / gates (push) Successful in 26s
R-237: /backups/restore listed apps that are CURRENTLY DEPLOYED and CURRENTLY TOGGLED ON for future off-site backups. A rebuilt box has neither, so a household that had just lost everything was shown nothing to restore while the repository held their snapshots — measured live on the R-201 re-walk. To restore an app you had to select it, to select it you had to have installed it, and to know what to install you had to see the backup you could not see. The store is now the source of the list (offsite_restore_list.go), built on the existing R-193 OffsiteInventoryList. Installed-ness became a property OF a row, never a filter on it. Every case is answered rather than hidden: a snapshot for an app that is not installed is offered and says it will reinstall first; an installed app with no snapshot is shown as having nothing; an unreadable store renders as UNKNOWN (R-225's rule, one screen over) AND keeps the action, because "we could not look" is not "there is nothing"; no-target is its own state. The felhom-offbox and _shares marker tags are excluded from the app list. R-238 classified as a HARNESS ARTIFACT: mode=full without confirm=1 is step 1 of a deliberate two-step — it starts no job by design and redirects carrying &full_prep=<app>, which deriveWizardStep requires to reveal the commit. A driver that did not carry it forward landed back on the intent step. The operator's browser run completed the same restore. The wizard's precedence rules were NOT re-keyed: a stale ?full_prep= must never resurrect a commit button mid-restore. The residue WAS real and is fixed: neither branch of that step wrote anything to the log, so a refusal — including by the headroom gate — left no trace on the box. Both branches now log, and so does the concurrent-op refusal. resolveWizardApp is removed: it was dead once the gate moved, and its test pinned the defect's behaviour (an untoggled app refused), which would have read as policy. 28 packages ok, 9/9 gates OK. Three red-proofs, each asserted to have applied.
This commit is contained in:
@@ -1,3 +1,54 @@
|
||||
## v0.204.0 — what you can restore is decided by the store, not by what happens to be installed (2026-08-06, R-237 / R-238) — MinAgent 0.127.0
|
||||
|
||||
**A household that had just lost its box was shown nothing to restore.** Measured live on the R-201
|
||||
re-walk (`felhom.eu/documentation/tests/part4-rewalk-2026-08-06/journal.md`): after a rebuild, with
|
||||
the key recovered, the tier configured and the escrow re-sealed, `/backups/restore` said „Nincs
|
||||
telepített alkalmazás" and the wizard refused every app with „Ez az alkalmazás nincs távoli mentésre
|
||||
kijelölve" — while the repository held their snapshots the whole time.
|
||||
|
||||
**The list was keyed on the wrong thing.** It was `buildOffboxApps()` filtered on `.Enabled`: apps
|
||||
**currently deployed** AND **currently toggled on for FUTURE off-site backups**. A rebuilt box has
|
||||
neither. That is a circular dead end at the worst possible moment — to restore an app you must select
|
||||
it, to select it you must have installed it, and to know what to install you must see the backup you
|
||||
cannot see. **The toggle is a statement about future backups; requiring it to look at a past one
|
||||
conflates two different questions, and that conflation was the defect.**
|
||||
|
||||
**The store is now the source of the list** (`internal/web/offsite_restore_list.go`), built on the
|
||||
existing R-193 inventory (`OffsiteInventoryList`) which already reads the repository and groups by
|
||||
app tag. Installed-ness became a property OF a row, never a filter on it: it changes what restoring
|
||||
implies, not whether the row exists. Every case is answered rather than hidden —
|
||||
|
||||
| case | what the customer sees |
|
||||
|---|---|
|
||||
| snapshot present, app NOT installed | listed and restorable, plus „Nincs telepítve — a visszaállítás előbb újratelepíti." |
|
||||
| app installed, no snapshot | listed, „Nincs mentése a távoli tárolóban — nincs mit visszaállítani." |
|
||||
| store unreadable | „Nem tudjuk elolvasni a távoli tárolót, ezért **nem tudjuk, mi van benne**. Ez nem azt jelenti, hogy üres…" — **and the action is still offered**, because "we could not look" is not "there is nothing" |
|
||||
| no target yet (the pristine rebuilt shape) | „A távoli tároló kapcsolódási adatai még nem érkeztek meg ehhez a géphez… Ez magától rendeződik." |
|
||||
| store genuinely empty | „A távoli tároló üres — nincs mit visszaállítani." |
|
||||
|
||||
That unknown-is-not-empty rule is **R-225's, one screen over**, and it now points both ways: a read
|
||||
failure must not be rendered as an empty list, and it must not silently withhold the action either.
|
||||
|
||||
**Two marker tags are excluded from the app list**: `felhom-offbox` rides on every snapshot, and
|
||||
`_shares` has its own restore entry with no per-app wizard — listing either would have offered a
|
||||
restore of something that does not exist. (The R-193 unlock listing still shows them; that is
|
||||
recorded, not fixed here.)
|
||||
|
||||
### R-238 — the size gate no longer refuses in silence
|
||||
|
||||
**Classified as a harness artifact, and the residue fixed anyway.** `POST /backup/offbox/restore`
|
||||
with `mode=full` and no `confirm=1` is step 1 of a deliberate two-step: it computes size + headroom,
|
||||
**starts no job**, and redirects carrying `&full_prep=<app>` so `deriveWizardStep` reveals the
|
||||
commit. A driver that does not carry that parameter forward lands back on the intent step — which is
|
||||
`deriveWizardStep` working exactly as its precedence comments describe, and is why the endpoint-level
|
||||
run read as "the button does nothing". **The operator's browser run completed the same restore.**
|
||||
|
||||
**What was genuinely wrong: neither branch of that step wrote anything to the log.** `restore-status`
|
||||
is empty by design (no job), and `offboxRedirectTo` only flashes to the page — so a customer refused
|
||||
a disaster restore, **including a refusal by the headroom gate**, left no trace on the box at all.
|
||||
Both branches now log, and so does the concurrent-op refusal. Nothing about the wizard's precedence
|
||||
rules was re-keyed: a stale parameter must still never resurrect a commit button mid-restore.
|
||||
|
||||
## v0.203.0 — the box collects what the hub staged for it (2026-08-06, R-218 consume half / R-220 message) — MinAgent 0.127.0
|
||||
|
||||
**R-218's declaration half shipped in v0.201.0 and works. Its consume half never existed.**
|
||||
|
||||
Reference in New Issue
Block a user