v0.259.0 — the claim page and the backup warnings answer in the reader's language (R-596, R-598)
gates / gates (push) Successful in 28s
gates / gates (push) Successful in 28s
The 2026-09-20 English drill ended one screen short: the claim page was English and its answers were Hungarian, so a household who mistyped the code from their e-mail could not tell a typo from a dead code. Fourteen call sites carrying nine messages now go through s.msg; the backup page's two protection warnings — which are promises about whether the customer's files are safe — follow the same route. Hungarian is byte-identical, proved structurally by the go-parity gate against the frozen base capture and red-proofed on a single added full stop. data["Title"] was DEAD (claim.html is standalone; .Title is layout.html's) and is deleted rather than translated — a translated dead field is a permanent false signal about where the page's title comes from. Six existing copy-contract tests were kept, not weakened: each now resolves its key through the real bundle, so it still convicts on a reworded Hungarian sentence. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -1,83 +1,66 @@
|
||||
# REPORT — v0.258.0: the last four Hungarian things, and the walk that judged them (R-561 slice 6)
|
||||
# REPORT — controller v0.259.0: the claim page and the backup warnings in the reader's language
|
||||
|
||||
2026-09-20 · `main` at the v0.258.0 commit · image `gitea.dooplex.hu/admin/felhom-controller:0.258.0`
|
||||
· live on demo-hp guest 9201 and on the drill box built from scratch the same day. MinAgent 0.131.0,
|
||||
unchanged. Hungarian byte-identical.
|
||||
**R-596 (P1), R-598.** Base `f6909492cc6e` → v0.259.0. MinAgent 0.131.0 unchanged.
|
||||
|
||||
Architecture read first and named: `felhom.eu/documentation/architecture/10-localisation.md` §1 (the
|
||||
Hungarian must not move), §4 (fallback), §5 (voice per language), §10.6b (this slice).
|
||||
## Claims in the task that turned out wrong
|
||||
|
||||
1. **"Sixteen Hungarian literals reach that page."** Fifteen literal sites reach it, carrying **ten**
|
||||
distinct messages (four are repeats). Of the fifteen, **one is dead**: `data["Title"]` is read only
|
||||
by `layout.html`, and `claim.html` is standalone with its own bundle-backed `<title>`. So
|
||||
**fourteen live sites, nine messages** were converted and the dead one was deleted.
|
||||
2. **"`backup_handlers.go` (12 Hungarian literals)."** Nine are code; the other three are Hungarian
|
||||
inside COMMENTS (`"Mentés most"`, `"Rendszermentés"`, a label quoted in a struct doc). The offer
|
||||
file's ten is right.
|
||||
3. **"the recovery code (10 words — find its caller)" in the hub.** The hub does not mint it.
|
||||
**felhom-agent** does, in `internal/escrow`, from the **EFF large wordlist** — so the recovery code
|
||||
**has always been English**, ten words, ≈129 bits. R-597's recovery-code leg needed no work and
|
||||
this repo does not own that secret. No row was added for it: inventing a second definition here is
|
||||
how two sources of truth start.
|
||||
4. **"the mail says 'three words'."** No claim mail states a count; they say `Setup code: %s`. The
|
||||
only count wording in the product is the **bind page's** passphrase hint/placeholder ("five
|
||||
words" / „öt szó"). The English pair is now count-free; the Hungarian is untouched.
|
||||
5. **§16's phone-safe filter** ("no two words differing by one letter within the first six") was
|
||||
measured before adoption: it removes **5270 of 7772** words, 12.92 → 11.29 bits/word. **Not
|
||||
adopted** — see the hub REPORT for the three reasons and what replaced it.
|
||||
6. **Line numbers** in the task were accurate. **"29 633 words"** is right to the line (29 634 lines,
|
||||
29 609 after dedup). **"`customer.language` reaches the anonymous claim page"** is TRUE and is now
|
||||
pinned by a test rather than assumed.
|
||||
7. **"the box checks a hash and needs no change" (for R-597)** is TRUE — verified and pinned by
|
||||
`TestClaimAcceptsAnEnglishWordCode`.
|
||||
|
||||
## What shipped
|
||||
|
||||
Four rows, all of them Go-side — which is why neither the template parity fixtures nor
|
||||
`TestI18nEnglishPages` could see them, and why **slice 5's LIVE proof is what found them**.
|
||||
- `internal/web/claim.go` — 14 sites → `s.msg(r, "claim.msg.*")`; the dead `Title` deleted with the
|
||||
reason recorded in place.
|
||||
- `internal/web/backup_target_offer.go` — three copy constants → bundle keys; `degradedMessageFor`
|
||||
returns the KEY (decision language-free, in one place); `backupTargetView(ctx, lang)`.
|
||||
- `internal/web/backup_handlers.go` — `buildTierViews`/`backupTargetLabel`/`loadGuestBackup` take the
|
||||
reader's language, the `buildDataPathCards` shape.
|
||||
- 23 new keys in both bundles; all 23 listed in `scripts/i18n_go_keys.json`.
|
||||
|
||||
| row | what | how |
|
||||
|---|---|---|
|
||||
| **R-589** | the update badge („Naprakész" + its tooltip) and the abandoned-lifecycle badge | bundle-backed forms in `localeFuncs`, reusing `compareInstalledToTemplate` and `EffectiveLifecycle` so **the decision cannot drift between languages — only the words do**; the badge's `Class` is asserted equal across languages for the same stack |
|
||||
| **R-590** | the data-folder card's backup sentence — **a promise about the customer's files** | `consequenceFor` takes its lookup as a parameter; the test asserts the CONSEQUENCE in both languages, and that the two languages do not produce the same string |
|
||||
| **R-573** | the agent-channel and endpoint-drift banners | keyed by the checker's own CLASSIFICATION, with the composed sentence kept as a **fail-open** fallback: an unmapped reason renders it verbatim rather than a blank banner or a raw key |
|
||||
| **R-572** | **not what the row said** | the row claimed a template renders „vasárnap" on an English page. Measured: **no template and no Go file called `pruneLabel` or `nextPruneLabel`.** Dead func-map entries returning Hungarian — **deleted**, not translated |
|
||||
## Evidence
|
||||
|
||||
`lifecycleBadge` was not in any row. It is the same builder one function from `updateBadge`, and
|
||||
leaving a known identical defect there would have been a choice.
|
||||
|
||||
## Why deleting was the right direction for R-572, and how that was proven
|
||||
|
||||
Translating dead code would have added machinery with no reader and a test pinning a fiction.
|
||||
Deletion is the **fail-loud** direction: `html/template` refuses to parse a template naming an
|
||||
undefined function, and `loadTemplates` parses every template once per language at startup. Proven
|
||||
rather than asserted — a template naming the removed function makes the parity test panic with
|
||||
`function "pruneLabel" not defined`. `fmtDuration`, named in the same row, produces no Hungarian at
|
||||
all ("< 1s", "5s", "2m 3s") and was left alone.
|
||||
|
||||
## Red-proofs — five, each seen to fail and then revert
|
||||
|
||||
| what was broken | what convicted |
|
||||
| Check | Result |
|
||||
|---|---|
|
||||
| the `updateBadge` override removed from `localeFuncs` | English read „Naprakész" |
|
||||
| `MessageKey` dropped from `SetAgentChannelAlert` | English read the Hungarian sentence |
|
||||
| the folder sentence hard-coded back to Hungarian | the English arm convicted on three assertions |
|
||||
| one Hungarian byte changed in a badge key | `TestLocaleFuncsHungarianBundleMatchesFuncMap` named both sides |
|
||||
| a template naming a deleted helper | startup panic in the parity test |
|
||||
| `go build ./... && go vet ./... && go test ./...` | green |
|
||||
| `controller_gates.py --fast` (17 gates) | all OK |
|
||||
| `scripts/i18n_go_parity.py` | OK — 718 keys, byte-for-byte against the frozen base |
|
||||
| `scripts/i18n_missing_gate.py` | English missing **0** (ceiling 0); Hungarian formal 18 (ceiling 18) |
|
||||
| `scripts/test_gate_decoys.py` | 23/23 |
|
||||
|
||||
**The fourth says something about the gate, not the code.** `i18n_go_parity.py` did NOT convict that
|
||||
changed byte, because `localeFuncs` keys sit under `_preexisting` and are deliberately not measured
|
||||
against the base capture. The citation to the test is what carries them — so the test had to be made
|
||||
real, and it was extended to compare `hu.json` against the frozen funcmap forms word for word.
|
||||
**Red-proofs, both seen failing:**
|
||||
- One added full stop on `claim.msg.bad_code` in `hu.json` → go-parity named both sides.
|
||||
- The wrong-code Hungarian literal restored in `claim.go` → the English test convicted twice (the
|
||||
English sentence absent AND the Hungarian sentence present on the English page).
|
||||
|
||||
## Proven live, twice
|
||||
## Two things the tests caught that review did not
|
||||
|
||||
- **demo-hp (0.258.0):** the English app page shows "Up to date" with an English tooltip while the
|
||||
Hungarian page still says „Naprakész"; the folder sentence is English on one and unchanged on the
|
||||
other; the free-space line reads "47.9 GB free" / „47.9 GB szabad". After the fixes, a scan of the
|
||||
English app pages and the Apps list finds **zero** Felhom-authored Hungarian — the only hit is the
|
||||
language picker naming itself „Magyar", which is correct.
|
||||
- **A box installed from scratch that day**, walked by an English speaker: the update badge and the
|
||||
time helpers were English there too, on hardware that had never run an older controller.
|
||||
- **An apostrophe never renders.** `"The system backup's drive…"` is escaped to `'` by
|
||||
`html/template` and no `strings.Contains` on the page ever matched it. Reworded; all 23 English
|
||||
values are now free of `' " < > &`.
|
||||
- **"please" is not this product's voice.** The i18n gate convicted two of my English sentences for
|
||||
pleading. Rewritten to plain second person.
|
||||
|
||||
## What the walk then found, which this release does not fix
|
||||
## Open
|
||||
|
||||
The walk is `felhom.eu/documentation/audits/DRILL-first-hour-en-0258-2026-09-20.md`. Its verdict is
|
||||
**not yet ready for an English-speaking tester**, and the blocker is in this repo:
|
||||
|
||||
- **R-596 (P1)** — `internal/web/claim.go` carries **sixteen** raw Hungarian literals, every one a
|
||||
message the claim page shows. The page's chrome is English; its answers are not. Same shape as
|
||||
R-573, one screen earlier in the journey, on the one screen between a household and their box.
|
||||
- **R-598** — `backup_handlers.go` (12) and `backup_target_offer.go` (10): the Backup page's two
|
||||
protection warnings and its two target names.
|
||||
|
||||
Both are the *composed-sentence-into-page-data* shape. That shape now has three instances on file
|
||||
(R-573, R-596, R-598) and is worth naming as a class the next converter looks for.
|
||||
|
||||
## Needs the operator
|
||||
|
||||
**Raise the fleet floor to 0.258.0.** Nothing breaks if it waits — the four fixes simply do not reach
|
||||
the other boxes. The drill box already ran 0.258.0, because the golden baked today is 0.258.0 and a
|
||||
golden above the floor is served normally (`managed floor SERVED … floor 0.257.0 … golden 0.258.0`).
|
||||
|
||||
## Teardown
|
||||
|
||||
Nothing installed or removed on demo-hp; guest 9201 restarted onto the new image, which is the
|
||||
deploy. The drill VM and its hub customer are torn down in three layers — see the drill document.
|
||||
Every staged credential was shredded from both hosts and both guests.
|
||||
Nothing from this release. The live proof and the floor are in the felhom.eu report.
|
||||
|
||||
Reference in New Issue
Block a user