# I18N INVENTORY — every Hungarian string a household meets, counted (2026-09-17) **Run class:** spike, Phase 0 of the localisation starter. **Operator:** Claude Code on DooPlex. **Baselines:** felhom-controller `89dd3e94b1de` (v0.246.0) · felhom-agent `d9864a94bf62` (v0.132.0) · felhom.eu `851198af7ff0` (hub v0.117.0) · app-catalog-felhom.eu `94bc5febaca2`. **Instrument:** `scripts/i18n_inventory.py`, sha256 `be69b48d4d98ac47c0cec531cae63bee8ef009cacbbe2b5c45725cfb2fd40f0c`. Raw output and per-string JSON: `audits/i18n-2026-09-17/inventory.md`, `inventory.json`. **What was counted:** the controller at its baseline commit (a clean worktree of `origin/main`, so the spike's own conversion is NOT in these numbers), the other three repos at their baselines. **Design this feeds:** `architecture/10-localisation.md`. --- ## 0. Claims in the starter prompt that live source disproved Named first, as the prompt asked. Four were already named in its §1; these are further ones. 1. **„`fmtTime`, `fmtBytes`, `timeAgo` — none of these exist. The FuncMap has one size helper, `fmtMB`."** — **Wrong, and it is the claim that matters most for localisation.** All three exist (`internal/web/funcmap.go` `timeAgo` L265, `fmtTime` L318, `fmtBytes` L403), and so do **nine more helpers whose output is copy or locale-shaped**: `fmtGB`, `humanBytes`, `timeAgoStr`, `fmtTimeStr`, `fmtTimeShort`, `fmtDuration`, `nextRunLabel` („ma"/„holnap"), `pruneLabel` („vasárnap"/„naponta"), `nextPruneLabel`, `statusText`, and `stateLabel` (the app-state words). There are **four** size helpers (`fmtMB`, `fmtGB`, `fmtBytes`, `humanBytes`), not one. `timeAgo` builds Hungarian with `%d` („%d perce") — the plural problem lives there. 2. **„`fmtMB`, used 10× in templates"** — **8×** (`grep -c` over templates, and the script agrees). 3. **„~13 `.Format(` calls in `internal/web/*.go` (`2006-01-02` ×6, `2006-01-02 15:04` ×4, `15:04` ×2, `01-02 15:04` ×1)"** — at the baseline: `2006-01-02` **×4**, `2006-01-02 15:04` **×3**, `15:04` **×2**, `01-02 15:04` ×1 = **10** layout literals, plus **8** `time.RFC3339` (machine, locale-free). The two template layouts are as stated and do disagree (`2006. 01. 02. 15:04` vs `2006-01-02 15:04`). 4. **Template line count „1 613 (afternoon) / ~1 838 (morning)"** — **1 553**, by two independent methods (this script, and `grep -cP` on the concatenated templates under `LC_ALL=C.UTF-8`). Neither prompt figure was reproduced. Tried: adding typographic quotes „ ” (1 556), adding dashes and ellipsis – — … (1 751), counting `style.css` too (1 559). The afternoon figure is **+60 (3.9 %)** and its method is unknown; the morning figure is closest to the dash-inclusive variant. **Lines are the wrong unit anyway** — see §1: the string count is 1 867. 5. **Go literal count „1 234 in 99 files (afternoon) / ~1 971 in 125 (morning)"** — **1 141 literals in 84 files** by a Go lexer (comments skipped), first-boot wizard excluded. A `grep` of quoted Hungarian on non-comment lines gives 1 106 lines in 85 files, so the two methods agree. Counting lines that hold an accented letter **including comments** gives 1 360 in 107 files; including the wizard and `cmd/`, 1 375 in 108. The prompt's figures sit between the comment-free and comment-inclusive counts; **comments explain most of the gap** (Hungarian quoted in Go comments is common here). 6. **Console banner „33 Hungarian lines"** — 33 by accented letter, **34** once ASCII-only Hungarian words are counted. Not an error; a method difference, stated. Confirmed as the prompt states: 36 page templates + `style.css`; 33 carry Hungarian; the second template set and its one helper (`internal/setup/handlers.go` L79 `timeNow`); 8 wizard pages, **86** Hungarian lines; `customerMessages` in the hub; 53 catalog files with `first_steps` under `app_info`; no i18n library, no `Accept-Language`, no bundle anywhere. --- ## 1. Controls — the counts below mean something Hungarian is matched by accented letter (the letters written as `\u` escapes, so the script itself is ASCII) **or** by one of 46 ASCII-only Hungarian words („Fut", „Nincs", „Hiba", „Csak", „Megszakadt"…), case-insensitive. Every surface prints a positive control (an ASCII fragment of a Hungarian word known to be there, whose lines the matcher must flag) and a negative control (a fragment known absent; an English sentence that must not be flagged). | surface | positive fragment | lines holding it | flagged | negative hits | English line flagged | verdict | |---|---|---|---|---|---|---| | controller templates | `pult` | 20 | 20 | 0 | no | ok | | controller Go | `ment` | 832 | 278 | 0 | no | ok | | hub customer Go | `ment` | 35 | 18 | 0 | no | ok | | installer banner | `Felhom` | 10 | 5 | 0 | no | ok | | catalog | `Alkalmaz` | 5 | 5 | 0 | no | ok | | guide | `Felhom` | 14 | 13 | 0 | no | ok | **Measured limit of the ASCII word list.** The spike's conversion tool first used a 40-word list and **missed eight Hungarian strings on the three pages** („Megszakadt:", „Elavult", „Csak x86", „Pi kompatibilis", „Rendszermonitor", „Most nem", „sikertelen", „ismeretlen"); a by-eye review of what was left found them, and they were added. **An ASCII-only Hungarian word that is not on the list is still invisible to every count here.** The counts below are therefore floors, not totals. --- ## 2. The tables ### 2.1 Controller page templates (`internal/web/templates/`, 36 files) **1 867 strings: 1 161 text runs + 88 attribute values + 618 inline-JS string literals.** 1 553 lines carry an accented letter. A *run* is text up to the next block tag or control action — the unit a translator needs. | template | HU lines | text | attr | JS | |---|---|---|---|---| | deploy.html | 156 | 87 | 8 | 77 | | storage.html | 110 | 43 | 9 | 98 | | debug.html | 92 | 41 | 16 | 79 | | layout.html (on every page) | 88 | 35 | 1 | 70 | | backups_remote.html | 77 | 87 | 0 | 10 | | settings_system.html | 84 | 58 | 0 | 36 | | backups_apps.html | 80 | 79 | 7 | 6 | | … 26 more | | | | | Full per-file table: `audits/i18n-2026-09-17/inventory.md`. **One third of all template copy (618) is inside `