R-294/R-295: orphan card stops promising restorability; one name per secret
gates / gates (push) Successful in 14s

The orphan card told a customer their set-aside off-site history may be
restorable later with their recovery code. The discriminator lives on the hub
and no wire field carries it, so the box rendering that card cannot evaluate the
promise. Copy replaced per the spec: state what happens, decline what we cannot
know and say why, name a route.

The claim page called the same three-word dashboard code two different names
depending on branch, one of which collides with the ten-word escrow code.
Retired 'Visszaallito kod'; the name is now constant and the sentence changes.
Naming only - a test pins that a reset code is still accepted.

secret_in_markup_gate no longer convicts Go template comments, which are
stripped before render; still convicts a real rendered secret.
This commit is contained in:
2026-08-10 13:53:21 +02:00
parent b762a37097
commit 86a78c6767
7 changed files with 276 additions and 7 deletions
+33 -1
View File
@@ -1,4 +1,36 @@
## v0.211.0 — the wall a rebuilt box could not get past (2026-08-10, R-280) — MinAgent 0.127.0
## v0.211.0 — the wall a rebuilt box could not get past (2026-08-10, R-280 / R-294 / R-295) — MinAgent 0.127.0
**R-294 / R-202 — the orphan card stops promising what it cannot know.** The card told a customer,
at the moment they had just lost their off-site history, that the old copies *„a hozzá tartozó
helyreállítási kóddal később visszaállítható lehet"*. The discriminator is
`host_escrow_superseded.identity_blob` and it lives on the **hub**; the box caches only
`HubEscrowIdentityPresent` (the CURRENT escrow) and no report or ACK field carries superseded-blob
retention. **The renderer could not evaluate the condition it was stating**, and for everything set
aside before hub v0.93.0 (2026-08-04 ~11:11Z) it is false and unfixable. Copy replaced verbatim from
`documentation/design/SPEC-orphan-card-copy-2026-08-10.md` §4: it states what happens, declines the
claim it cannot evaluate and says why, and names a route (write to us). Four render tests, per branch
of the gate.
**SPEC DEFECT FOUND AND NOT ACTED ON — `backups_remote.html:98` makes the same promise.** The spec
lists that line as *"Accurate; keep"*, but it ends *„a hozzájuk tartozó helyreállítási kóddal később
visszaállíthatók lehetnek"* — the identical claim in a different conjugation, which the spec's own
regression guard (`visszaállító` + `lehet`, singular) does not match. Left as-is deliberately: the
instruction is not to improvise Hungarian at the customer. **Needs a wording decision → R-296.**
**R-295 — one name per secret (controller half).** The claim page called the SAME three-word
dashboard code „Beállító kód" on the first-time branch and „Visszaállító kód" on the reset branch,
while the TEN-word escrow code is „Helyreállítási kód". Two near-homographs for two different
secrets; the collision cost a real code. „Visszaállító kód" is **retired**: the dashboard code is
„Beállító kód" on both branches (`claim.html`) and in both operator-facing strings (`claim.go`
the `print-reset-code` output and the lockout message), and where the one secret serves two
situations the **name is constant and the sentence changes**. **Naming only — no acceptance logic
moved**, pinned by `TestResetCode_StillAcceptedOnTheSetupPage`.
**Gate fix (instrument, not product).** `secret_in_markup_gate.py` treated a Go template comment
`{{/* ... */}}` as a rendered expression and convicted the prose explaining a fix for containing the
word "secret". Template comments are stripped by `html/template` and cannot reach the response body,
so they are now skipped — `<!-- -->` comments deliberately are NOT, because those do ship. Proven in
both directions: the gate passes the comment and still convicts a planted `{{.RecoveryPassword}}`.
**R-280 — after a reinstall the data drive can be re-attached, and the page stops promising a click
that does not exist.** Measured on the rebuilt demo-hp 2026-08-09: the restore page diagnosed the