# REPORT — localisation starter (English first): inventory, spike, design, plan — 2026-09-17 **Task:** STARTER — the product in more than one language. **Baselines (re-verified at start, all matched the prompt):** felhom-controller `89dd3e94b1de` v0.246.0 · felhom-agent `d9864a94bf62` v0.132.0 · felhom.eu `851198af7ff0` hub v0.117.0 · app-catalog-felhom.eu `94bc5febaca2`. Highest row R-552. **Architecture read:** `02-controller-module-map.md`, `05-hub-architecture.md`, `09-update-architecture.md` §3. ## Claims in the prompt that live source disproved — first Six, beyond the four the prompt already named — `documentation/audits/I18N-INVENTORY-2026-09-17.md` §0. The one that matters: **the time and size helpers DO exist** (`fmtTime`, `timeAgo`, `fmtBytes` and nine more copy-producing ones; four size helpers, not one). The count claims (template lines 1 613, Go 1 234 / 99 files, `fmtMB` 10×, 13 `.Format(`) were each measured lower; the afternoon template figure was not reproduced by any of four method variants — the difference is stated, not explained away. ## Deliverables | deliverable | where | |---|---| | inventory + script + hash | `documentation/audits/I18N-INVENTORY-2026-09-17.md`, `scripts/i18n_inventory.py` (sha256 `be69b48d…40f0c`), raw `audits/i18n-2026-09-17/inventory.{md,json}` | | the mechanism on three pages, Hungarian unchanged | controller v0.247.0 — `felhom-controller/REPORT.md` | | parity fixtures + test | `felhom-controller/controller/internal/web/testdata/i18n_parity/` (14 states), `i18n_parity_test.go` | | English pages (no screenshots: no browser on DooPlex — the rendered HTML is the evidence) + ASCII-control lines | `audits/i18n-2026-09-17/live/` | | hub report line carrying `language` | `audits/i18n-2026-09-17/live/hub-report-language.txt` (`en` 12:54:43Z, `hu` 12:55:22Z) | | `10-localisation.md` | `documentation/architecture/10-localisation.md` | | sliced plan with costs | 10 §10 (slices 1–6, 56–74 CC-hours total) | | decisions in the §3 shape | 10 §11 — four operator rulings recorded, two CC decisions, two open (1b, 7) | | rows | R-553..R-562 opened; R-516 extended; register **248 → 258** open (closed-register gate) | ## Findings worth knowing - **Moving copy out of templates staled one gate and blinded three** — fixed in v0.247.0 by reading templates expanded; decoys prove it. - **The wire-contract gate reads comments** (R-555): `language` passed without an allowlist entry. - **Four behaviour-by-wording sites** (R-553) must be fixed before any Go string is translated. - **The first-boot wizard is reachable** whenever bootstrap ingestion leaves `customer.id` empty — inventory §2.7 lists every such path. Deletion is R-554. ## Gates `python3 scripts/repo_gates.py` — run by the pre-push hook on both felhom.eu pushes, all OK. `unproven.py --summary`: NOT WALKED 35 of 55 — unchanged by this session. ## Teardown Machine: demo-hp guest 9201 left on Hungarian with controller 0.247.0; temp files and secrets shredded. Host: nothing left on demo-hp. Hub: nothing written (DB copy read and shredded). The fleet floor was not raised; no golden. Nothing provisioned.