6.6 KiB
REPORT — v0.213.0: the banner promises only what the box can still see is true (2026-08-12)
Commit 8971256. Green gate: build/vet clean, 28 packages ok, 0 FAIL; all eleven controller
gates OK (one is new). Golden 0.213.0 baked, published and round-trip verified. The Day-0 vouch is
the operator's and was not made here. --no-verify used nowhere.
1. Is the pinned fingerprint provably the right key? — NO. It is a recorded assumption.
Asked first, as instructed. Nothing on the box records which key wrote the set-aside copies — that key is gone, which is why they were set aside. What is pinned is the package the hub held at the decision, which in the ordinary rebuilt-box story IS the pre-rebuild escrow covering the pre-rebuild repo password. On a twice-rebuilt box that presumption can be wrong: the hub may hold rebuild #2's package while the copies are rebuild #1's, and no key on file opens them. The pin cannot detect that.
Recorded as an assumption in the field comment on settings.AbandonPinnedEscrowKeySHA256, in the test
header, and in R-302 — so it can be narrowed later rather than hardening into a fact.
What it does detect, and what the rejected proxy could not: the package being replaced after the decision — the exact act that cost both demo boxes their history on 2026-08-04.
2. Red-proofs — mutation asserted applied each time
| # | Mutation | Outcome |
|---|---|---|
| 1 | the rejected proxy (hub fingerprint vs the CURRENT key, at render) | FAIL — Scenario B and Scenario D flip back to promising. Yes, the false promise reproduced. This is the evidence for choosing the pin |
| 2 | pin re-read at render instead of used from the decision | FAIL — B and D promise again |
| 3 | empty pin backfilled from the current value | FAIL — a legacy countdown gets promised at |
| 4 | emptiness guards dropped | PASSED — and that was a finding about my own test, see below |
| 4b | same mutation, against a new both-sides-empty test | FAIL — two absences compared equal and became a promise |
| 5 | condition forced false | FAIL — Scenario A loses the clause; the guard is reachable in both directions, not merely always-off |
Red-proof 4 is worth reading. My Scenario E (pin present, hub hash empty) passed with the
cur != "" guard removed, because its pin is non-empty so the equality fails on its own. The test
guarded the sentence, not the guard. The state where emptiness actually bites is both sides empty —
a legacy countdown on a box whose hub reports a legacy package. Added ScenarioE2, which fails as it
should. Without running the mutation I would have shipped a guard nothing pinned.
3. The three strings as shipped
Always, both surfaces:
A korábbi távoli mentéseidet {{N}} nap múlva ({{dátum}}) véglegesen töröljük, a kérésed szerint.
Retrieval clause, only when the pin matches:
Addig még visszaszerezheted őket a helyreállítási kóddal.
Cautious branch, everything else:
Hogy ezek még visszaszerezhetők-e a helyreállítási kóddal, azt innen nem tudjuk megállapítani — ha vissza szeretnéd kapni őket, írj nekünk a törlés előtt.
Composed from explicit codepoints and hex-verified end to end: é=c3a9 ő=c591 á=c3a1 í=c3ad ó=c3b3 —=e28094 ü=c3bc ö=c3b6, no double-encoding, no replacement characters, in both templates.
4. A legacy countdown renders the cautious branch
A countdown started before v0.213.0 has no pin, so it renders the deletion sentence plus „Hogy ezek
még visszaszerezhetők-e … írj nekünk a törlés előtt." Pinned by ScenarioD, and deliberately not
backfilled.
5. The stem guard — and why it became a claim guard
The stem cannot be banned, and this is the honest answer to §5's last question. The replacement copy
contains visszaszerezhet, inside a question about knowability. A guard forbidding the stem would
force the product to avoid a normal Hungarian verb — a guard shaping the product around itself.
So scripts/retrieval_promise_gate.py registers each claim with a reason and fails on unregistered
ones. Plant → convict → remove → pass run for all three historical wordings: each convicted (rc=1),
all cleared on removal (rc=0).
The full sweep of all 36 templates found five sites, and I do NOT believe "nothing else" would have been the right answer — given the same promise surfaced one at a time across three sessions, the sweep finding two new instances is exactly what the history predicts:
| site | verdict |
|---|---|
backups.html, backups_apps.html |
local backup/restore, unrelated to the escrow claim — allowlisted |
backups_remote.html (RecoveryOffer entry) |
true where it renders; deliberately left, per the previous session |
backups_remote.html (abandon block) |
FOURTH instance — same condition applied. Fixing the strip and not the page would have left one contradicting the other |
layout.html (the banner) |
the subject of this session |
recovery.html (abandon confirmation) |
FIFTH instance — deliberately LEFT. It renders at the moment of the decision, where the promise is true by construction: that is the package about to be pinned |
One instrument defect found and fixed on the way: the gate's first draft matched by proximity window and reported two live entries as stale, because the promise and the disclaimer sit ~100 characters apart. It now matches by span.
6. Was R-296 correctly closed? Yes.
Its sentence was backups_remote.html:98; v0.212.0 replaced it and the stem guard covers it. Verified
before closing, not assumed.
7. Observations, not acted on
- R-303 —
markOrphanedhas no guard against an active countdown (offbox.go:804). This session makes the co-render harmless, not impossible. Ranked LOW, deliberately: it is a coherence question, not a correctness one, and the tempting fix — suppressing the orphan card during a countdown — would hide a genuine second fault (the box's new store also being unopenable). - The cautious sentence now appears on both the strip and the page below it when both render. Each is self-contained; I read it as reinforcement rather than a defect, and did not churn copy to avoid it.
8. Out of scope, so it does not read as forgotten
The drill session unblocking the two unpublished installer fixes; the hub half of the code naming (its
file:line enumeration is still owed); the CI runs that fail with no log; the twenty unread facts; the
nine grey claims; and proving that a retained key can actually open an old store — still unshown,
and the same knowledge this whole design turns on.