Files
felhom-controller/REPORT.md
T
admin bef39598d0
gates / gates (push) Successful in 24s
v0.256.0: the box sends its own sentence in the household's language (R-558 Part B)
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
2026-09-18 16:54:20 +02:00

3.3 KiB

REPORT — localisation slice 3 Part B: the box sends its sentence in the household's language

controller v0.256.0 · base 8fb2f9ef9d5a · 2026-09-18 · R-558 Part B · MinAgent 0.131.0 (unchanged)

What shipped

The hub half (v0.118.0/0.118.1) writes a household's e-mails in their language. This is the other half: about a third of those mails carry a sentence the BOX composed — naming a drive, an app, a number — and the hub cannot translate one. The box now sends it twice.

  • message_customer on the event wire: the same sentence in the household's language, beside the unchanged Hungarian message. omitempty, and a Hungarian household sends nothing extra, so its payload stays byte-for-byte what every box in the fleet sends today.
  • 19 producers converted to bundle keys, both renderings from ONE key.
  • customer.language bootstraps a new box: stored choice → config → Hungarian. The config value is never persisted into settings.json; doing so would record a choice nobody made.

The Hungarian did not move, measured twice

  • TestEventMessageWireTextIsFrozen — goldens captured at the slice-2 base commit.
  • The Go parity gate — all 19 new keys checked byte-for-byte against the base-commit literals (688 slice-2 keys listed, 34 pre-existing, 484 named in Go, gate OK).

Three guards had to learn the change, and one caught me

  • The test seam pushFn now carries messageCustomer. A seam that cannot see a new field cannot test it — the lesson this repo recorded one release ago when PushEvent had to become the seam.
  • The R-329 severity contract walks call sites by FUNCTION NAME. Converting producers moved two dynamic-severity sites off PushEvent and the register reported them as no longer existing — the "a stale register entry is also a failure" half doing its job. The three new helpers are registered; the walk now checks 36 severity literals, up from 20.
  • TestConfigLanguageIsWiredInMain reads main.go and asserts the setter is CALLED. cmd/ is gitignored, so ripgrep skips main.go and a reviewer's search finds nothing — which is exactly how a seam gets built and never wired in this repo. Red-proofed by deleting the call.

A mistake, named

The first pass of the conversion dropped the displayName argument from three producers (app_deployed, app_deploy_started, app_removed). Shipped, that would have mailed customers Alkalmazás telepítve: %!s(MISSING). Caught by reading my own diff, and now pinned by a test that refuses any sentence containing %!, MISSING, %s or %d in either language.

What is NOT converted, and why

  • The operator-tier types (15 of them, listed in the hub's operatorOnlyEvents): the operator reads Hungarian, and these never reach a customer.
  • Producers whose sentence is composed in another package and reaches the notifier already finished — backup_failed, db_dump_failed, backup_integrity_ok/_failed, offbox_enlarge_blocked, local_api_endpoint_drift. They still send Hungarian only, so an English household can still see one Hungarian line in some mails. Filed as a row rather than left as prose.
  • The R-570 sentence, which stays Hungarian until that row closes.

Green

go build / go vet / go test ./... clean. All 17 controller gates OK. All 23 decoys behave.