## v0.251.0 — Nothing decides by reading a Hungarian word (2026-09-17, R-553 + R-563)
**MinAgent: 0.131.0** (unchanged). **No hub release needed.** Nothing a household reads changes: every
Hungarian sentence is byte-identical, and the hub report is unchanged (pinned by a wire test).
Five places branched on their own customer-facing copy. Localisation slice 2 translates exactly those
words, and each one would then have taken the other branch, silently. Each now reads a signal set where
the message is made — `internal/util.KindErrorf` builds the same bytes `fmt.Errorf` did while carrying a
sentinel for `errors.Is`.
| # | decision | read before | reads now |
|---|---|---|---|
| 1 | deploy HTTP status (`api.deployStatusFor`) | „kötelező", „memória", "does not exist", "already deployed" | `stacks.ErrRequiredField` / `ErrPathMissing` / `ErrNotEnoughMemory` (400), `ErrAlreadyDeployed` (409) |
| 2 | off-site failure class (`ClassifyOffsiteFailure`) | „tárhelykeretet" | `backup.ErrOffsiteQuota` |
| 3 | where a disk warning is shown (`web/alerts.go`) | „meghajtó"/„adattároló" in the warning | `monitor.WarnKindStorageNotSeparate`, carried in `HealthReport.WarningKinds` |
| 4 | the stale „nothing selected" note (`offboxWarningDisplay`) | „nincs mentésre jelölt alkalmazás" in the PERSISTED text | `settings.OffboxTarget.LastWarningKind` = `backup.OffboxWarnNoAppsSelected` |
| 5 | the remote-backup poll (`backups_remote.html`) | the displayed word „Fut" | `data-status="running"` on the status element (R-563) |
- **The restic / ssh signatures in the classifier stay text matches on purpose** — that output is not
ours and is never translated. Listed as external in REPORT.md.
- **Site 4 legacy:** a box upgraded to 0.251.0 still carries the old persisted text with no kind until
its next off-site run. The text test survives ONLY for `kind == ""`, with a removal row (R-570);
**slice 2 must not translate that producer before R-570 closes.**
- **Site 5 is the one rendered byte that changed:** the `data-status` attribute (plus the poll line).
12 `backups_remote` fixtures re-captured; each differs from its predecessor by exactly those two
things, the other 94 are byte-identical. „Fut…" is now `{{T "backups_remote.fut"}}` (en „Running…"),
so the English page finally sees a running backup.
- **The wire is untouched:** `internal/report/builder.go` copies Status/Issues/Warnings only;
`TestR553_HubReportWarningsAreUnchangedOnTheWire` pins the field set and the bytes.
- New in REUSE.md §1: „Error kinds — never branch on a customer-facing sentence".
**Red-proofs** (`felhom.eu/documentation/audits/r553-2026-09-17/redproofs.txt`): every site's pre-fix
predicate restored and watched failing — deploy statuses fall to 500/400-for-anything, the translated
quota error reads „ismeretlen okból", the translated disk warning jumps to the top banner, the stale
note returns, and both languages lose the poll. The detector (`felhom.eu/scripts/i18n_inventory.py`)
was re-run: template compares 1 → 0, and planted decoys prove it still convicts.
## v0.250.0 — Every dashboard page in English; the language switch shown to every household (2026-09-17, R-556 release C)
**MinAgent: 0.131.0** (unchanged). **No hub release needed.** **A Hungarian household sees one new thing:
a „Magyar / English" switch in the sidebar footer.** Everything else in Hungarian is byte-identical.
- **Converted (608 markers):** `storage` (162), `storage_network` (70), `storage_init` (42),
`storage_attach` (27), `sharing` (74), `login` (9), `claim` (21), `launcher_shared` (4),
`launcher_share_password` (6), `catchall` (4), `debug` (189). All 31 slice-1 templates are done; the
English gap is 0.
- **Parity:** 24 fixture states captured from the UNCONVERTED templates (`0555091`). Those cases had
invented page titles; they now carry the handlers' real titles and the 12 affected fixtures were
re-captured from `0555091` (diff: the `
` line, and the nav highlight on the two drive wizards).
- **Sign-in, claim, guest share (both), catch-all follow the language** through `executeTemplateLang`
(no session CSRF, no escrow reminder). `renderLogin` takes the request. Tests:
`TestDirectRenderHandlersFollowLanguage` (the real routes, en and hu), `TestI18nDirectRenderPagesHaveNoAdminChrome`
(escrow reminder genuinely due; absent from the page data of all six pages and from the guest page in both languages).
- **The switch for everyone:** the hide condition in `addLanguageData` is deleted. 89 layout fixtures
re-captured; each differs from its predecessor by exactly one inserted switch form placed after the
version span (89 of 89 byte-for-byte after removing the form); the 17 standalone fixtures are unchanged.
`TestLanguageSwitch_EndToEnd` now asserts a Hungarian household with no `?lang=` sees the form.
- **Titles:** `TitleKey` for storage, network storage, both drive wizards, sharing.
`TestHandlerTitleKeysMatchHungarianTitle` pins every handler's Hungarian title literal to its hu.json value.
- By-eye review found six ASCII-only Hungarian JS fragments the extractor missed („, majd a(z)",
„FIGYELEM:", „jelenlegi:", „mp", „p", „ db"); converted by hand. No test would have caught them on the
English page (row filed).
- `HU_FORMAL_CEILING` 12 → 16 (R-516) — and the stem list sees only 4 of at least 22 formal forms on these pages (R-516 extended).
- `r400_debug_routes_test.go` and `debug_route_gate.py` still read `debug.html` raw: correct, they match
addresses and identifiers, and the bundles hold no `/api/` string (measured 0).
**Red-proofs** (`felhom.eu/documentation/audits/i18n-slice1-2026-09-17/C/redproofs.txt`): parity (one letter of
`sharing.megosztott_mappak` → 6 sharing cases), English page (`storage.eleresi_ut` removed → 2 cases),
marker coverage (a marker in an unrendered branch), title keys (reworded hu value; deleted handler line),
direct routes (all five back on `s.tmpl` → five English rows fail), no admin chrome (`addEscrowBanner`
added to `executeTemplateLang` → fails per page), the switch (hide condition restored → end-to-end test
and 89 parity cases fail).
## v0.249.0 — English for the backup pages, Hungarian byte-identical (2026-09-17, R-556 release B)
**MinAgent: 0.131.0** (unchanged). **No hub release needed.** Nothing changes for a Hungarian household.
- **Converted:** `backups_apps`, `backups_remote`, `backups_restore`, `backups_restore_wizard`,
`backups_escrow`, `tier2_config`, `recovery`, and the restore-progress JS in `backups_shared`
(`restore_banner_js`, which v0.247.0 had left Hungarian).
- **Parity:** 41 fixture states captured from the UNCONVERTED templates (commit `f8ebc47`), plus
`backups_apps_stale_copy` captured from `f8ebc47` for a condition inside a confirm text.
- **`recovery` follows the language** through the new `executeTemplateLang` — the language-aware render
for pages outside the dashboard chrome, WITHOUT `executeTemplate`'s CSRF injection and escrow bar.
Tests: `TestI18nDirectRenderPagesFollowLanguage` (hu = fixture bytes, en = English) and
`TestRecoveryHandlerFollowsLanguage` through `renderRecovery` (red-proofed by restoring `s.tmpl`).
- **Deliberately not converted:** „Fut…" and the JS `indexOf('Fut')` on `backups_remote` — the page
decides its progress poll by reading that word (R-563). Code values (`snapshot_id=helyi`) stay.
- **Retrieval-promise gate, English:** 13 English claims registered with reasons; six mirror Hungarian
registrations. **Seven exposed a Hungarian blind spot**: split verbs („állíthatók vissza", „hozod
vissza") escape the Hungarian stems, so those sentences were never scanned in Hungarian (row filed).
- Extractor review found ASCII-only Hungarian it missed: Konfig, Megtartva, helyi, pl. (×3), Befejezve,
automatikus, (jelenleg:), kedd/szerda/szombat, „1. szint"/„2. szint", and a confirm text split by
`{{if .Tier2StaleCopy}}`; converted by hand, words added to its list.
- Title keys for the backup sub-pages and the escrow page. `HU_FORMAL_CEILING` 10 → 12 (R-516).
**Red-proofs** (`felhom.eu/documentation/audits/i18n-slice1-2026-09-17/B/redproofs.txt`): parity (one byte of
`backups_escrow.kod_letrehozasa` → both escrow cases name the line); recovery routing (render back on
`s.tmpl` → English lost, test fails).
## v0.248.0 — English for apps and settings: ten more pages, Hungarian byte-identical (2026-09-17, R-556 release A)
**MinAgent: 0.131.0** (unchanged). **No hub release needed.** Nothing changes for a Hungarian household:
the switch is still shown only on English pages (decision 6 stands until release C).
- **Converted:** `dashboard`, `stacks`, `logs`, `monitoring`, `app_import`, `app_export`, `deploy`,
`settings_system`, `settings_security`, `settings_notifications` (572 markers). `app_row`,
`meta_badge`, `icons` carry no copy (verified). 16 repeated strings now share `common.*` keys
where the meaning is the same everywhere; „Mentés" (Save/Backup), „Frissítés" (Update/Refresh),
„Indítás" (Start/Boot) deliberately stay per page.
- **Parity:** 25 new fixture states captured from the UNCONVERTED templates (commit `6be55a0`) before
any of these pages carried a marker. Five v0.247.0 fixtures were re-captured from v0.246.0
(`89dd3e94`) because their one-word Hungarian data had to become multi-word (below).
- **New test — `TestI18nParityCoversEveryMarker`:** every marker occurrence must be rendered by some
parity case. It found two gaps in v0.247.0's own pages (the app page's Install button; one „Due"
tag), closed with two new cases captured from v0.246.0.
- **English page test widened:** only fixture strings of 2+ words or 12+ characters are masked; titles
go through `addLanguageData`. Measured: with one English nav key deleted, the old test flagged 8
cases and missed the 6 launcher cases; the new one flags all 14.
- **Retrieval-promise gate reads English** (`EN_PATTERNS`, `ALLOWLIST_EN`): HEAD passed a planted
„Your old backups can be restored at any time." in `en.json`; the gate now convicts it and accepts the
same place carrying a sentence that promises nothing. Decoys in `test_gate_decoys.py`.
- **Go-side copy on these pages:** titles via `TitleKey` (dashboard, stacks, monitoring, the three
settings pages); `infraMeta` descriptions (and samba's name) from the bundle, Hungarian pinned equal
to `inframeta.go`.
- **Found, not converted:** `backups_remote.html` decides with `indexOf('Fut')` against its own
Hungarian status text (row filed); converting that word would silently break the English page's
progress poll. Composite page titles (logs, deploy, export) and `lifecycleBadge`/`updateBadge`
remain Hungarian — slice 2.
- **Extractor:** ASCII-only Hungarian it missed on these pages — Mind, Folyamat, Titkos, Processzor,
Hamarosan, aldomain, „Az adatai itt voltak", Figyelem, pelda@email.hu — converted by hand; words added
to its list (not „Mind": an English homograph). It also learnt that a JS string can start inside an
attribute value.
- `HU_FORMAL_CEILING` 6 → 10: the converted copy carries four more „ön" forms (R-516), unchanged by rule.
- Old wording tests (`TestDiskMeter_*`, `TestNetworkBadgeTemplates_DistinctStrings`,
`TestSettingsSectionInventory`) read the Hungarian expansion (`huTemplateSource`), not the raw file.
- `loadTemplates` logs its parse duration per language (DEBUG).
**Red-proofs** (`felhom.eu/documentation/audits/i18n-slice1-2026-09-17/A/redproofs.txt`): parity (one byte
of `dashboard.lemezek_allapota` → 4 dashboard cases name line and bytes); coverage (a marker in an
unreachable launcher branch → named, while parity stayed green); mask widening (8 vs 14 cases);
retrieval gate (HEAD rc 0 on the planted promise → fixed gate convicts, negative control accepted).
## v0.247.0 — the dashboard can speak English: mechanism proven on three pages, Hungarian byte-identical (2026-09-17, i18n spike)
**MinAgent: 0.131.0** (unchanged — nothing here talks to the agent). **No hub release needed:** the
report gains an additive `language` field the hub stores raw and does not read yet.
**Nothing changes for a household.** Hungarian stays the default and the only language shown; the
switch appears only on an English page or a request carrying `?lang=`.
- **Mechanism — a flat message bundle, expanded BEFORE the template is parsed.**
`internal/i18n/locales/{hu,en}.json` (embedded; hu authoritative). Converted templates carry
`{{T "key"}}` markers; `loadTemplates` parses one template set per language after `i18n.Expand` has
replaced them, so the Hungarian set is parsed from the same bytes, in the same escaping contexts, as
before. Chosen over `golang.org/x/text/message` because the inventory found no gender and only
count-plurals (English `key.one`/`key.other`; Hungarian has one form), and over a runtime `T` func
because the contextual escaper would change Hungarian bytes (`+`, `'`, `"`) and need per-context
handling inside `