hub v0.119.0 — English households get English words for their codes (R-597); R-596/R-598 closed
gates / gates (push) Successful in 24s
gates / gates (push) Successful in 24s
The setup code and the owner passphrase now follow the household's language,
one word longer in English so the entropy never drops (setup 3 hu / 4 en,
passphrase 5 hu / 6 en). List and count are chosen together so a caller cannot
pair an English list with a Hungarian count. Hungarian is byte-unchanged.
Three claims in the row were wrong and are recorded as such:
- the RECOVERY CODE is minted by felhom-agent from the EFF list and has
always been English; the hub does not own it and no row was added.
- no claim mail states a word count; the only count wording was the bind
page's passphrase hint, whose English half is now count-free.
- the proposed phone-safe filter removes 68% of the list (5270 of 7772
words) and was measured, then declined, with the reason in source.
Also: guide_quote_gate binds the English volunteer guide's three quoted
messages to the controller's English bundle — nothing did, so the guide would
have gone on quoting Hungarian after the fix. Seven decoys, all convicting,
including the name-for-fact one.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -356,3 +356,50 @@ token is real. Pinned by `TestBindExpiredIsAlwaysDefaultLanguage`.
|
||||
56 goldens captured from v0.117.0 before any string moved, in
|
||||
`hub/internal/notify/testdata/mail_goldens/hu/`, with the English set beside them. The claim is a
|
||||
diff, not a reading. A golden is never regenerated to make a change pass.
|
||||
|
||||
### 15.6 The CODES a household types, per language [hub v0.119.0, R-597]
|
||||
|
||||
A mail in English that carries three Hungarian words with accents is not an English mail. The 2026-09-20
|
||||
drill received exactly that, and could paste the code but not read it to anyone.
|
||||
|
||||
**Two secrets this repo mints follow the household's language**, list and word count chosen together
|
||||
by `configgen.RandomPassphraseFor(lang, use)`:
|
||||
|
||||
| Secret | hu | en | who calls it |
|
||||
|---|---|---|---|
|
||||
| Setup / reset code | 3 words, 44.6 bits | **4 words, 51.7 bits** | `claim.Engine` via `CustomerLanguage` |
|
||||
| Owner passphrase | 5 words, 74.3 bits | **6 words, 77.5 bits** | the three `configs.go` sites |
|
||||
|
||||
**The rule is per use: English ≥ Hungarian, in bits.** The English list (EFF large, 7772 words after
|
||||
filtering) carries 12.92 bits/word against the Hungarian list's 14.85, so English takes one more
|
||||
word. The test computes both sides from the embedded lists rather than comparing a constant with
|
||||
itself, so shrinking a list or lowering a count fails.
|
||||
|
||||
**A third secret is NOT minted here and must not be added.** The customer **recovery code** is minted
|
||||
by `felhom-agent` (`internal/escrow`) from the same EFF list, ten words, ≈129 bits — it has been
|
||||
English since it was written. R-597's row listed it here; that was wrong. Writing a row for it in
|
||||
this table would create a second definition of a secret the hub does not own, which is the drift
|
||||
`backupTargetAbsentText` already demonstrates across two repos.
|
||||
|
||||
**Which language, and when.** The setup code follows `Store.CustomerLanguage` — the same order the
|
||||
mail carrying it follows (reported → created-with → `hu`), so a code and its e-mail can never
|
||||
disagree. Two consequences, both deliberate:
|
||||
|
||||
- **A household created as `hu` whose box later reports `en`** keeps every code already issued
|
||||
exactly as it was; the **next** code issued is English. A code is a hash on the box, never
|
||||
retranslated.
|
||||
- **At customer creation there is no stored customer yet**, so the Owner passphrase generated on that
|
||||
form reads the language from **the form field**, not from `CustomerLanguage` — which would answer
|
||||
Hungarian for every English household created. The store's `createdLanguage` applies the same
|
||||
default to an absent value, so the two agree.
|
||||
|
||||
**The box needs no change for any of this.** It stores and compares a bcrypt hash of whatever was
|
||||
minted and has no notion of which list the words came from — pinned by the controller's
|
||||
`TestClaimAcceptsAnEnglishWordCode`. The TTL, the single-use generation and the five-attempt lockout
|
||||
are untouched and language-blind.
|
||||
|
||||
**Count wording.** No claim mail states a word count; they say `Setup code: %s`. The only place a
|
||||
count appeared was the bind page's passphrase hint, and its English half is now count-free ("The word
|
||||
phrase you received from your operator during setup") — because "five words" stops being true for an
|
||||
English household, and was already wrong for one whose passphrase predates this release. The
|
||||
Hungarian „öt szó" is correct and unchanged.
|
||||
|
||||
@@ -749,9 +749,9 @@ everything else held.
|
||||
|
||||
| what | why | row |
|
||||
|---|---|---|
|
||||
| the **claim page's messages** („Hibás vagy lejárt kód", „A jelszónak legalább 12 karakter…", the lockout) | composed sentences passed into page data, the R-573 shape one screen earlier | **R-596 (P1)** |
|
||||
| the **setup code itself** (and the recovery code and owner passphrase) | one Hungarian wordlist, not chosen per language | **R-597** |
|
||||
| the **Backup page's two protection warnings** and its two target names | composed sentences in `backup_handlers.go` / `backup_target_offer.go` | **R-598** |
|
||||
| ~~the **claim page's messages**~~ | ~~composed sentences passed into page data~~ | **R-596 CLOSED**, controller 0.259.0 |
|
||||
| ~~the **setup code** and the **owner passphrase**~~ | ~~one Hungarian wordlist~~ | **R-597 CLOSED**, hub 0.119.0 |
|
||||
| ~~the **Backup page's two protection warnings** and its two target names~~ | ~~composed sentences in Go~~ | **R-598 CLOSED**, controller 0.259.0 |
|
||||
| the menu word **"Debug"** | it is already English; the complaint was the Hungarian household's | R-516 item 1 |
|
||||
| the **operator's copy** of every event | operator-tier is Hungarian **by design** (ruling 1) | — |
|
||||
| the **18 formal „ön" forms** | a localisation release may not change Hungarian bytes (§1); counted, ratcheted | R-516 |
|
||||
@@ -769,6 +769,57 @@ walk cannot see them.
|
||||
**R-214 closed as a side effect** — the console's last paint is now the bilingual "the box is linked"
|
||||
banner. The 2026-09-14 walk recorded it as still reproducing.
|
||||
|
||||
### 10.6c Slice 6's residue, closed (controller v0.259.0 + hub v0.119.0, 2026-09-21)
|
||||
|
||||
The three rows above are closed. What is worth keeping is not that they closed but **what each one
|
||||
turned out to be**, because two of the three were not what the row said.
|
||||
|
||||
**R-596 — the claim page.** Fourteen live call sites carrying **nine** distinct messages, not the
|
||||
sixteen literals the row counted; one of the sixteen (`data["Title"]`) was **dead** — `claim.html` is
|
||||
standalone and `.Title` belongs to `layout.html` — and was deleted rather than translated. The
|
||||
anonymous, cookie-less page takes its language from `customer.language` in `controller.yaml`
|
||||
(`langFor` → `settings.GetLanguage` → `configLanguage`); that chain was an unpinned assumption and is
|
||||
now a test.
|
||||
|
||||
**R-598 — the backup warnings.** `degradedMessageFor` now returns a **key**, so the decision stays
|
||||
language-free and in one place while the words are chosen by whoever knows the reader. The English
|
||||
is asserted to carry the same NEGATION the Hungarian does — *protects against corrupted files, but
|
||||
**not** against a disk failure*. An English sentence that promised disk-failure protection would be
|
||||
worse than leaving it Hungarian.
|
||||
|
||||
**R-597 — the codes.** Two of the row's three secrets were mis-attributed:
|
||||
|
||||
- **The recovery code was never Hungarian.** `felhom-agent` mints it from the **EFF large wordlist**
|
||||
and always has — ten English words, ≈129 bits. The hub does not own it, and no row was added for
|
||||
it: a second definition of that secret is exactly the drift this section exists to prevent.
|
||||
- **No claim mail states a word count.** The only count wording in the product is the bind page's
|
||||
passphrase hint, and its English half is now count-free.
|
||||
- The setup code and the owner passphrase now follow the household's language, one word longer in
|
||||
English so the entropy **never drops**: setup 3 hu (44.6 bits) → 4 en (51.7); passphrase 5 hu
|
||||
(74.3) → 6 en (77.5). The floor is computed from the embedded lists at test time, not asserted
|
||||
against a constant.
|
||||
|
||||
**[FACT] The defect class is now four instances deep** — R-573, R-590, R-596, R-598: *a composed
|
||||
sentence handed to a renderer as page data*. Nothing structural sees it. A template-parity fixture
|
||||
renders the field faithfully; `TestI18nEnglishPages` reads a template, not a struct; the Go-parity
|
||||
gate proves the Hungarian is unchanged and says nothing about which language reached the page. **The
|
||||
only instruments that find it are a live English page and a handler-level render test**, and this
|
||||
release added the second for both surfaces.
|
||||
|
||||
**[FACT] A method finding worth more than the result.** The first live check of the backup page used
|
||||
the `felhom_lang` cookie and got the **Hungarian** page for `en`. That is correct: `langFor` step 2
|
||||
says a request carrying a **session** reads the household's saved setting and deliberately ignores
|
||||
the visitor cookie. The cookie is the right instrument for the anonymous claim page and the **wrong**
|
||||
one for any signed-in page — where `?lang=` is. A session that had run only the cookie probe would
|
||||
have concluded R-598 was unfixed and fixed it again. Recorded in
|
||||
`audits/i18n-closing-2026-09-21/live/backups-page.md`.
|
||||
|
||||
**What did NOT get a live walk:** the degraded and absent-drive warnings themselves. Guest 9201 has a
|
||||
real backup drive, so it is healthy and renders nothing — by design (E-2 Scenario E) — and producing
|
||||
either state would mean un-assigning a live box's backup target. They are covered by render tests
|
||||
through the real handler. **The next English walk on a one-drive machine is what actually closes
|
||||
that**, and it is the same walk R-516 is waiting for in the other language.
|
||||
|
||||
## 11. Operator decisions
|
||||
|
||||
These are rulings, not proposals. Anything specced against a different assumption is wrong.
|
||||
|
||||
Reference in New Issue
Block a user