v0.201.0 — a correct recovery code is never called wrong again (CAMPAIGN-11) — MinAgent 0.125.0
gates / gates (push) Successful in 9s
gates / gates (push) Successful in 9s
R-216: the offsite key recovery is a coupled feature and now says so. featureProbes +
featureMinAgent 0.125.0 + a Supports gate at the unlock entry point, FAILING CLOSED — an
agent that cannot answer is named as such instead of the customer's code being blamed.
Measured live: a 404 from agent 0.120.0 came back as "we did not accept your recovery
code, check that all ten words", in 0.134 s, against a perfect code.
R-218: delete the repo-password short-circuit in needsOffsiteCredential. The declaration
stops when the TIER WORKS, not when a key exists — installing a key is the recovery
screen's whole job, so succeeding at recovery was switching off the mechanism that would
have delivered the coordinates to use it.
R-219: the unlock finishes the job — place the key, bring the tier up, then list. Without
it the promised listing could never render on the shape the screen exists for.
R-217: an unreadable store no longer claims to have opened with unattributable content
(the OffsiteInventory{} zero value). Opened / empty / unreadable are three states.
R-222: a code that is right about a RETAINED earlier package is named, not blamed. States
what the hub knows and promises nothing — no read path exists.
R-215: GET /recovery is gated on the same predicate as the interception.
Five red-proofs, each demonstrated failing and restored.
This commit is contained in:
@@ -1,3 +1,63 @@
|
||||
## v0.201.0 — a correct recovery code is never called wrong again (2026-08-05, CAMPAIGN-11) — MinAgent 0.125.0
|
||||
|
||||
CAMPAIGN-11 walked the whole recovery journey end to end for the first time. **The data came back
|
||||
byte-identical; the journey did not exist** — four operator interventions stood between a customer and
|
||||
their files, and the first one was the machine telling them their perfectly correct recovery code was
|
||||
wrong. This closes six of the nine findings.
|
||||
|
||||
**R-216 — the headline. A 404 was reported to the customer as a bad code.** The unseal lives in the
|
||||
agent behind `POST /escrow/recover-offsite-password`, which ships in agent **v0.125.0**. On an older
|
||||
agent the route 404s, and the unlock was attempted anyway: *„A megadott helyreállítási kódot nem
|
||||
fogadtuk el. Ellenőrizd, hogy mind a tíz szót pontosan…"* — measured live in 0.134 s, far too fast for
|
||||
`age`'s scrypt, against a code that was perfect. **It was the default state, not a misconfiguration**:
|
||||
the day-0 manifest vouches agent 0.120.0, and a reinstall actively *downgrades* a hand-fixed box back
|
||||
to it. Three parts:
|
||||
|
||||
- `FeatureOffsiteKeyRecovery` now exists in `featureProbes` + `featureMinAgent` (0.125.0) with a
|
||||
`Supports` gate at the unlock entry point — **the convention `features.go:72-76` and
|
||||
`publish-train-rules.md` rule 4 already required, which v0.195.0/v0.196.0 declared in their headers
|
||||
and v0.200.0 dropped when it put the same coupled feature behind a customer-facing button.**
|
||||
- **This gate FAILS CLOSED**, alone in that table: anything but `SupportYes` says *the machine* cannot
|
||||
ask yet, and no unlock is attempted. An attempt that cannot succeed must never be made, because its
|
||||
failure is what got attributed to the code. The asymmetry is documented beside the row.
|
||||
- The hub's own guard could not catch it (see the hub changelog, v0.97.0).
|
||||
|
||||
**R-218 — succeeding at recovery stopped the box asking for what it still needed.**
|
||||
`needsOffsiteCredential` short-circuited on a repository password existing — and installing one is the
|
||||
recovery screen's whole job. 32 seconds after the hub re-staged the credential, the customer's success
|
||||
switched off the mechanism that would have delivered the coordinates for the key they had just
|
||||
recovered. **The short-circuit is deleted**; the declaration now stops when the tier works, not when a
|
||||
key exists. Scenario E (a deliberately disabled target stays silent) is pinned by its own test.
|
||||
|
||||
**R-219 — the promised listing could never render on the shape the screen exists for.** Listing needs
|
||||
a target; a target cannot exist without a repository password; shape (a) is defined by having none. The
|
||||
unlock now **finishes the job** — place the key, bring the tier up, then list — and a tier that is not
|
||||
up yet says *waiting for the connection details* rather than reporting a failure.
|
||||
|
||||
**R-217 — an unreadable store claimed to have opened.** The failure path passed
|
||||
`backup.OffsiteInventory{}`, whose `Empty=false` the template read as *„A tároló megnyílt, és van benne
|
||||
tartalom, de nem tudtuk alkalmazásokhoz rendelni."* — three assertions, none of them known. The field
|
||||
built to prevent exactly this says so in its own doc comment. Opened / empty / unreadable are now three
|
||||
distinguishable states.
|
||||
|
||||
**R-222 — reaching for a retained earlier package read as a wrong code.** The hub's ACK carries
|
||||
`superseded_present` / `superseded_at` (hub v0.97.0); the screen now names that situation. It states
|
||||
the two facts the hub knows and **does not promise the earlier package can be opened** — that read path
|
||||
does not exist.
|
||||
|
||||
**R-215 — `GET /recovery` rendered the recovery story on a box that never had backups.** The predicate
|
||||
was right and the page never asked it. Gated on the same predicate as the interception.
|
||||
|
||||
**Four messages where there was one**, each saying what to do next and only one mentioning typing.
|
||||
|
||||
Left open deliberately: **R-214** (the console never stops showing a stale pairing code), **R-220**
|
||||
(drives cannot be re-enrolled after a rebuild), **R-221** (a rebuilt box cannot run the escrow ceremony
|
||||
— a real blocker for that flow).
|
||||
|
||||
Tests: `recovery_gate_test.go` (Scenarios A/F/G/H/I, handler-level), `offbox_declare_test.go`
|
||||
(Scenarios D/E). **Five red-proofs, each demonstrated failing and restored** — removing the capability
|
||||
gate brings the accusation back verbatim.
|
||||
|
||||
## v0.200.0 — the recovery screen: unlocking, and only unlocking (2026-08-05, R-193)
|
||||
|
||||
R-193's remaining half. The drill proved a customer's file comes back after a machine is destroyed;
|
||||
|
||||
Reference in New Issue
Block a user