REPORT: v0.213.0 pinned-fingerprint condition, red-proofs, claim guard
gates / gates (push) Successful in 12s
gates / gates (push) Successful in 12s
This commit is contained in:
@@ -1,66 +1,104 @@
|
|||||||
# REPORT — v0.212.0: the orphan card's second promise (2026-08-12)
|
# REPORT — v0.213.0: the banner promises only what the box can still see is true (2026-08-12)
|
||||||
|
|
||||||
Commit `68f3e12`. Green gate: build/vet clean, **28 packages ok, 0 FAIL**; all ten controller gates OK.
|
Commit `8971256`. Green gate: build/vet clean, **28 packages ok, 0 FAIL**; all **eleven** controller
|
||||||
Golden 0.212.0 baked and published; **the Day-0 vouch is the operator's and was not made here.**
|
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.
|
||||||
|
|
||||||
## R-299 — the same claim, one paragraph up, in the plural
|
## 1. Is the pinned fingerprint provably the right key? — NO. It is a recorded assumption.
|
||||||
|
|
||||||
`internal/web/templates/backups_remote.html` line 98 — the **always-visible** half of the orphan card —
|
Asked first, as instructed. **Nothing on the box records which key wrote the set-aside copies** — that
|
||||||
still ended *„a hozzájuk tartozó helyreállítási kóddal később **visszaállíthatók lehetnek**"*. The
|
key is gone, which is why they were set aside. What is pinned is the package the hub held at the
|
||||||
paragraph fixed in v0.211.0 renders only after the customer clicks „Új távoli mentés indítása…", so on
|
decision, which in the ordinary rebuilt-box story IS the pre-rebuild escrow covering the pre-rebuild
|
||||||
first view **the sentence a customer actually read was the one still promising.**
|
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.**
|
||||||
|
|
||||||
It survived for two independent reasons:
|
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.
|
||||||
|
|
||||||
1. `SPEC-orphan-card-copy-2026-08-10.md` §1 listed the line as *"Accurate; keep"* — corrected.
|
What it *does* detect, and what the rejected proxy could not: the package being **replaced** after the
|
||||||
2. **The regression guard matched one inflection.** It asserted `visszaállítható lehet` (singular); the
|
decision — the exact act that cost both demo boxes their history on 2026-08-04.
|
||||||
card carried `visszaállíthatók lehetnek` (plural), which does not contain that substring. **A guard
|
|
||||||
matching one inflection of a Hungarian verb guards one sentence, not the claim.**
|
|
||||||
|
|
||||||
Guard now matches the stem `visszaállíthat`. The plain forms the rest of the UI uses („visszaállítás",
|
## 2. Red-proofs — mutation asserted applied each time
|
||||||
„visszaállítani") do not contain it, so it does not over-match.
|
|
||||||
|
|
||||||
**Shipped copy** (the two knowable halves kept — declining a promise must not become telling the
|
| # | Mutation | Outcome |
|
||||||
customer less than we know):
|
|---|---|---|
|
||||||
|
| 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 |
|
||||||
|
|
||||||
> A távoli tárhelyen lévő mentések egy korábbi, már nem elérhető kulccsal készültek (jellemzően
|
**Red-proof 4 is worth reading.** My Scenario E (pin present, hub hash empty) **passed with the
|
||||||
> újratelepítés után). Emiatt új mentés jelenleg nem írható a tárolóba. **A meglévő mentések nem
|
`cur != ""` guard removed**, because its pin is non-empty so the equality fails on its own. The test
|
||||||
> sérültek. Azt viszont ez a gép nem tudja megállapítani, hogy később megnyithatók-e — ez attól függ,
|
guarded the sentence, not the guard. The state where emptiness actually bites is **both sides empty** —
|
||||||
> megvan-e még a hozzájuk tartozó kulcs. Ha szükséged van rájuk, írj nekünk.**
|
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.
|
||||||
|
|
||||||
Bytes verified as hex: `á/é/ő/ü/ú/í/ó` and `—` all correct, no double-encoding, no replacement chars.
|
## 3. The three strings as shipped
|
||||||
|
|
||||||
## Plant → convict → remove → pass
|
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.
|
||||||
|
|
||||||
| step | result |
|
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 |
|
||||||
|---|---|
|
|---|---|
|
||||||
| plant the exact shipped plural | stem guard **FAILS**, quoting the sentence back |
|
| `backups.html`, `backups_apps.html` | local backup/restore, unrelated to the escrow claim — allowlisted |
|
||||||
| would the OLD narrow guard have caught it? | **No** — `"visszaállítható lehet" in plural` is `False`, shown as a pure string fact rather than a source grep (my first attempt at that check was contaminated by my own template comment) |
|
| `backups_remote.html` (RecoveryOffer entry) | true where it renders; deliberately left, per the previous session |
|
||||||
| remove the plant | 5/5 orphan-card tests pass |
|
| `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 |
|
||||||
|
|
||||||
Two branches of the gate are covered: card shown, and a healthy store seeing none of it.
|
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.
|
||||||
|
|
||||||
## Instrument defect fixed in the guard itself
|
## 6. Was R-296 correctly closed? Yes.
|
||||||
|
|
||||||
Its failure message sliced the rendered HTML at a **byte** offset, which cuts Hungarian mid-character
|
Its sentence was `backups_remote.html:98`; v0.212.0 replaced it and the stem guard covers it. Verified
|
||||||
and printed a replacement char — a garbled failure message reads like an encoding bug in the product
|
before closing, not assumed.
|
||||||
rather than in the message. It now slices on rune boundaries.
|
|
||||||
|
|
||||||
## Does the card read coherently as a whole?
|
## 7. Observations, not acted on
|
||||||
|
|
||||||
**Mostly yes, with one thing I did not touch and one I introduced.**
|
- **R-303 — `markOrphaned` has 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.
|
||||||
|
|
||||||
- **Not touched, and reportable: `layout.html:143`.** The abandon countdown says *"Addig még
|
## 8. Out of scope, so it does not read as forgotten
|
||||||
visszaszerezheted őket a helyreállítási kóddal"* — the retired promise a third time and **un-hedged**.
|
|
||||||
It is probably TRUE where it renders (gated on an active abandon of a recovery offer that exists),
|
|
||||||
which is why I left it; but it renders on **every page**, and a rebuilt box can have an active
|
|
||||||
countdown while its store is orphaned. **Filed as R-301** with the wording question, not improvised.
|
|
||||||
- **Introduced: a repetition.** Once the customer clicks through, "we cannot determine / depends on the
|
|
||||||
key / write to us" appears in both the explanation and the confirm block. On first view — the common
|
|
||||||
case — only the explanation shows, and each is self-contained. I read this as reinforcement at the
|
|
||||||
decision point rather than a defect, and left it rather than churn customer copy.
|
|
||||||
|
|
||||||
## NOT DONE
|
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
|
||||||
- The Day-0 vouch (the operator's).
|
nine grey claims; and **proving that a retained key can actually open an old store** — still unshown,
|
||||||
- No box was deployed to, so this is unit- and render-proven only, not exercised through a live endpoint.
|
and the same knowledge this whole design turns on.
|
||||||
|
|||||||
Reference in New Issue
Block a user