v0.256.0: the box sends its own sentence in the household's language (R-558 Part B)
gates / gates (push) Successful in 24s
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:
@@ -1,70 +1,56 @@
|
||||
# REPORT — the globe on the sign-in-flow pages, fixed (controller v0.255.0)
|
||||
# REPORT — localisation slice 3 Part B: the box sends its sentence in the household's language
|
||||
|
||||
**2026-09-18 · base `2e9d402` (v0.254.0) · MinAgent 0.131.0, unchanged · no hub release.**
|
||||
Architecture named: `felhom.eu/documentation/architecture/10-localisation.md` §3 (who picks the
|
||||
language, and where the switch lives).
|
||||
**controller v0.256.0** · base `8fb2f9ef9d5a` · 2026-09-18 · R-558 Part B · MinAgent 0.131.0 (unchanged)
|
||||
|
||||
## 1. Claims in the prompt that live source disproved — named first
|
||||
## What shipped
|
||||
|
||||
| the prompt said | source says |
|
||||
|---|---|
|
||||
| "only the three shells lack `?v=`" | **FIVE do**: `login`, `claim`, `recovery`, **and both guest share pages** (`launcher_shared`, `launcher_share_password`). The share pages carry no globe, but the stale-stylesheet fault is the same for any CSS change and their visitor is the likeliest to hold an old copy. All five fixed — which is why 3 fixtures outside the named three changed, against the prompt's "zero re-captures outside the three shells". (8 first-boot wizard templates also lack it; out of scope, R-554 deletes them.) |
|
||||
| "`.Version` is already in their data" | **Only in two.** `login` (auth.go:343) and `claim` (claim.go:289) set it; `recovery` and both share pages did not. Rather than add it three times, it is set once in `executeTemplateLang` — the choke point every shell renders through — so the next shell cannot miss it. |
|
||||
| "`login.html` L11 … `style.css` L3683-3684" | Confirmed, line for line. |
|
||||
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.
|
||||
|
||||
## 2. What was wrong, and why no test saw it
|
||||
- **`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 globe rendered unstyled** for anyone whose browser had `style.css` cached from before v0.254.0:
|
||||
the shells requested it with no `?v=`, so the cached copy — which has no `.lang-globe` rules — kept
|
||||
being served. The markup was correct, which is why every existing test passed: **they all read the
|
||||
HTML, and the fault was in which CSS file the browser fetched.** It took a screenshot to see it.
|
||||
## The Hungarian did not move, measured twice
|
||||
|
||||
**And the globe floated outside the card**, pinned to the corner of the viewport, reading as a stray
|
||||
browser control rather than part of the page.
|
||||
- `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).
|
||||
|
||||
## 3. The fix
|
||||
## Three guards had to learn the change, and one caught me
|
||||
|
||||
- `?v={{.Version}}` on all five shells; `Version` set in `executeTemplateLang`.
|
||||
- `.shell-lang` is now `display:flex; justify-content:center; margin-top:1.5rem` — a plain block inside
|
||||
the card. The absolute positioning and the menu-direction override are **deleted**, so the shared
|
||||
`.lang-globe-menu` rule applies and the dashboard and the shells cannot drift apart.
|
||||
- The div moved to the end of each card: under the footer on `login` and `claim`, last in the card on
|
||||
`recovery` (which has no footer paragraph).
|
||||
- **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.
|
||||
|
||||
## 3b. A third defect, caught by an existing test
|
||||
## A mistake, named
|
||||
|
||||
Putting the version on the guest share pages would have printed the controller build onto a page **a
|
||||
stranger with a capability URL can open**. `TestShareGuest_HeadersTilesNoAdminChrome` already refused
|
||||
that, and refused it here — a good test earning its keep. Those two pages now take an **opaque
|
||||
per-build tag** instead (`AssetTag`): same cache-busting, no disclosure.
|
||||
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.
|
||||
|
||||
The fill is one function, `addShellAssetData`, called by `executeTemplateLang` **and** by the parity
|
||||
harness. Slice 2 release C got the fixture/production split wrong twice; sharing the function is what
|
||||
makes a third time impossible rather than merely unlikely.
|
||||
## What is NOT converted, and why
|
||||
|
||||
## 4. Tests, red-proofed
|
||||
- **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.
|
||||
|
||||
`TestGlobeOnAnonymousShells` gained: the stylesheet carries a **non-empty** `?v=`; the globe is inside
|
||||
the card; the globe is below the footer where one exists. Each was red-proofed by restoring the
|
||||
defect's exact shape — the unversioned link (convicts, naming the stylesheet) and the globe put back
|
||||
before the card (convicts, "floats outside it").
|
||||
## Green
|
||||
|
||||
`testServer` gained `version: "test"`: an empty `?v=` busts a cache exactly once and never again, and
|
||||
baking that into a fixture would have hidden it. The test now refuses an empty one.
|
||||
|
||||
## 5. Parity
|
||||
|
||||
15 fixtures re-captured — 1 login, 4 claim, 7 recovery, 3 guest share — and **91 identical, including
|
||||
every dashboard page**. Four change shapes: the three shells gained the moved globe AND the buster;
|
||||
the two guest pages gained only the buster, as an opaque tag. The whole diff is the `?v=` attribute and the moved block, nothing else:
|
||||
`felhom.eu/documentation/audits/i18n-slice2-2026-09-18/D/parity-diff.txt`.
|
||||
|
||||
## 6. Green gate
|
||||
|
||||
`go build ./... && go vet ./... && go test ./...` green; all controller gates OK.
|
||||
|
||||
## 7. Row
|
||||
|
||||
**R-579** — the cache-buster gap: found, fixed and closed in this session, with the general form
|
||||
recorded (a template that loads a versioned asset without the version is invisible to every test that
|
||||
reads markup).
|
||||
`go build` / `go vet` / `go test ./...` clean. All 17 controller gates OK. All 23 decoys behave.
|
||||
|
||||
Reference in New Issue
Block a user