v0.214.0 — the recovery screen stops hedging about a code it can now check (R-311)
gates / gates (push) Successful in 13s

MinAgent: 0.129.0

What was already right: the screen did not bluntly accuse. R-222/R-226 hedged,
naming both causes and the kept package, and saying it could not tell them apart.
That was honest - and it could not tell them apart because nothing ever looked.
Agent v0.129.0 looks, so the hedge becomes an answer.

New class RecoveryCodeOpensRetained on HTTP 422, gated by
FeatureRetainedRecoveryClass (MinAgent 0.129.0). The gate is SEPARATE from the
R-224 one because the two name different agent versions and a box can sit between
them, where a 422 is a shape we did not design. ClassifyRecoveryFailure therefore
takes both flags; the compiler found every call site.

The message says the code is correct, names the supersession date, says the
earlier package is kept, and says the CURRENT backups are unaffected - the half a
customer will otherwise assume wrong. It promises NO restore: there is no
in-product route to a set-aside store (R-312) and the retained package may itself
predate the repository-password field. It routes to support, which can do it.

The claim guard grew a surface and immediately convicted something. It scanned
templates only, while every recovery message is a Go string in a handler - the
highest-stakes copy in the product, never scanned. It now scans recovery_handlers.go
too, and found a PRE-EXISTING unregistered claim on its first run.

Six handler tests asserting which SENTENCE the customer sees; red-proofs asserted
applied, including: 422 unconditional makes an agent that never looked read as
having looked, and routing 400 to the new class congratulates a mistype.
This commit is contained in:
2026-08-12 18:42:02 +02:00
parent 3168a78935
commit 3ed5e3e770
10 changed files with 365 additions and 11 deletions
+40
View File
@@ -1,3 +1,43 @@
## v0.214.0 — the recovery screen stops hedging about a code it can now check (2026-08-12, R-311)
**MinAgent: 0.129.0**
**What was already right, and is worth saying first.** The screen did NOT bluntly accuse a customer
holding an older code: R-222/R-226 already hedged, naming both possible causes and the kept package.
That sentence was honest — *"innen nem tudjuk megkülönböztetni őket"*, we cannot tell them apart from
here. **It could not tell them apart because nothing ever looked.** Agent v0.129.0 looks, so the hedge
can become an answer.
**New failure class `RecoveryCodeOpensRetained`** on HTTP 422, gated by `FeatureRetainedRecoveryClass`
(MinAgent 0.129.0). The gate is the R-224 twin and is SEPARATE from `trustRefusal` on purpose: the two
name different agent versions (0.126.0 and 0.129.0) and a box can sit between them, where a 422 is a
shape we did not design and must not be read as a verdict. `ClassifyRecoveryFailure` therefore takes
both flags; the compiler found every call site.
**The message, and what it deliberately does not say.** It states the code is correct, names the
supersession date, says the earlier package is kept, and — the half a customer will otherwise assume
wrong — says the CURRENT backups are unaffected. It does **not** promise the older history can be
reopened from this screen: there is no in-product route to a set-aside store (the restore machinery
resolves its repository from settings and its password from one file), and the retained package may
itself predate the repository-password field. A conditional promise that turns out false on this
screen is worse than saying less — the R-202 lesson, on the highest-stakes copy in the product. It
routes to support, which CAN do it: the 2026-08-12 drill did exactly that by hand.
**An older agent keeps the hedged sentence.** Unknown → claims less → heals itself on update.
**The claim guard grew a surface (and immediately convicted something).** `retrieval_promise_gate.py`
scanned `internal/web/templates` only — while every recovery message is a Go string in a handler, i.e.
the highest-stakes copy in the product had never been scanned. It now scans `recovery_handlers.go`
too, with Go comments stripped for the same reason template comments are. On its first run it found a
PRE-EXISTING unregistered claim (`RecoverRefused`'s "reopening would overwrite it") — now registered
as an explanation rather than a promise. `visszanyit` joins the stems: the new message uses a fourth
verb for the same claim, and the gate's own history is what happens when it chases words not claims.
Six handler tests asserting which SENTENCE the customer sees, with red-proofs asserted applied —
including: make 422 unconditional and an agent that never looked is read as having looked; route 400
to the new class and a mistype is congratulated.
---
## v0.213.0 — the banner promises only what the box can still see is true (2026-08-12, R-302) — MinAgent 0.127.0
**The abandon countdown told every customer who had given up their off-site history: *„Addig még