v0.256.0: the box sends its own sentence in the household's language (R-558 Part B)
gates / gates (push) Successful in 24s

MinAgent: 0.131.0 (unchanged). Needs hub v0.118.0+, which shipped first and
tolerates a box that sends none of this - every box in the fleet is that box
until this release reaches it.

The hub writes a household's e-mails in their language now, but about a third
of those mails carry a sentence the BOX composed, naming a drive, an app or a
number. The hub cannot translate one. So the box sends it twice.

- message_customer on POST /api/v1/event, omitempty. A HUNGARIAN household
  sends nothing extra at all, so its payload stays byte-for-byte what every box
  sends today and the hub's fallback path keeps being the one production
  exercises rather than a branch nobody takes.
- 19 producers render both sentences from ONE bundle key. `message` stays
  Hungarian always: it is what the operator is mailed and what the hub logs.
- customer.language bootstraps a new box - stored choice, then config, then
  Hungarian. The config value is NEVER written into settings.json: that would
  record a choice the household never made.

The Hungarian did not move, measured twice: the wire golden from the slice-2
base commit, and the Go parity gate over all 19 new keys.

Three guards had to learn the change and one caught me: the test seam now
carries the new field; the R-329 severity register reported two dynamic sites
as no longer existing the moment they moved off PushEvent (the walk now checks
36 severity literals, up from 20); and TestConfigLanguageIsWiredInMain reads
main.go, because cmd/ is gitignored and ripgrep does not.

A mistake, named: the first pass dropped displayName from three producers,
which would have mailed customers "Alkalmazás telepítve: %!s(MISSING)". Caught
reading the diff; now pinned by a test that refuses %!/MISSING/%s/%d in either
language.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-09-18 16:54:20 +02:00
parent 8fb2f9ef9d
commit bef39598d0
16 changed files with 1601 additions and 1068 deletions
+31 -1
View File
@@ -3614,7 +3614,7 @@ without reaching `Images()`.
---
### 18. Dashboard language (i18n) (v0.247.0–v0.254.0)
### 18. Dashboard language (i18n) (v0.247.0–v0.256.0)
Design: `felhom.eu/documentation/architecture/10-localisation.md`. Inventory:
`felhom.eu/documentation/audits/I18N-INVENTORY-2026-09-17.md`.
@@ -3820,6 +3820,36 @@ controller/
## Configuration
#### 18.5 The e-mails the hub sends (v0.256.0, slice 3)
**The hub writes a household's e-mails in the household's language** from hub v0.118.0. It learns
which language from the box: every report carries `"language"` (since v0.247.0), and the hub prefers
the last reported one over the operator's creation-time default. Nothing here needs a setting.
**The box sends about a third of those sentences itself**, and the hub cannot translate one — it
arrives as finished text naming a drive, an app or a number. So `POST /api/v1/event` carries
**`message_customer`**: the same sentence in the household's language, beside the unchanged Hungarian
`message`.
- `message` is **always Hungarian**. It is what the operator is mailed, what the hub logs and what
`notification_log` records; a household switching language moves nothing an operator reads.
- A **Hungarian household sends no second copy at all** (`omitempty`), so its payload is byte-for-byte
what every box has always sent.
- 19 producers render both from ONE bundle key (`event.*`): health ×3, controller started/updated/
update-failed, storage disconnected/reconnected, backup target absent/restored, app deployed/
deploy-started/deploy-failed/removed, crossdrive ×2, disaster recovery ×2, db-dump completed.
- An **untranslatable tail** (a docker error, a validator's sentence) is appended to both renderings.
- **Not converted, deliberately:** the operator-tier types (the hub keeps them off the customer
channel) and the producers whose sentence is composed in another package and reaches the notifier
already finished. Those still send Hungarian only, so an English household can still see one
Hungarian line in some mails. Tracked as a row.
**A new box starts in the language the operator picked.** The hub renders `customer.language` into
`controller.yaml`; `GetLanguage` prefers the household's stored choice, then that, then Hungarian.
The config value is **never written into `settings.json`** — persisting it would record a choice the
household never made.
### Controller config (`controller.yaml`)
Single YAML file per customer, infrastructure-only. Does **not** contain app-specific config.