# REPORT — localisation slice 5: the catalog read path, the copy gate, and the pilot (R-560) 2026-09-20. Three repos touched: **felhom-controller v0.257.0** (the read path), **app-catalog-felhom.eu** (freeze + gate + pilot), **felhom.eu** (this file, the architecture document, the register, STATUS, the audit). Hub, agent, ISO and website untouched. ## Where it ended The operator read the pilot and said go, so **Part C shipped the same day**: the other fifty apps in three pushes. **1 031 of the catalog's 1 032 customer-facing strings are English**, and the one that is not is a Hungarian defect deliberately left to fall back (R-593). **The fleet floor was then raised to 0.257.0**, as the operator asked, and the second demo box took it by itself in under twelve seconds and rendered English. **Nothing is waiting on the operator from this work.** ## What was proven, and how it was seen Endpoint level. No browser exists on DooPlex, so every page was fetched with `curl` from inside the guest at the controller's container address, with the customer `Host` header and a real logged-in session — the same handlers and templates a browser drives, with only the drawing skipped. | claim | evidence | |---|---| | The English app pages show English catalog text | demo-hp on 0.257.0: twelve apps opened individually across the pushes | | **The English Apps list has NO Hungarian app text left** | all 53 apps on one page: the only Hungarian is the „Naprakész" badge (R-589) and the language picker naming itself | | The floor delivered the FEATURE, not a version string | demo-felhom self-updated 0.255.0 → 0.257.0 in under 12 s, then rendered the English tagline | | **The Hungarian did not move** | the same seven pages in Hungarian, before and after the catalog push: byte-identical apart from the per-session CSRF token — equal byte counts and equal hashes once normalised | | **An old controller ignores the block** | demo-felhom on **0.255.0**: with the block synced (confirmed positively — the sync named the three apps and the block is in both the cache and the stack copy), pages hash identically before and after, and **no** parse warning in a **93-line** log window that contains the sync's own lines | | The gate can convict | 33 decoy cases in the catalog repo, every one seen to convict or to pass as intended | | The read path is not hollow | nine red-proofs in the controller, each seen to fail and then revert | ## What is still Hungarian on an English app page Measured with an accent scan AND an ASCII-folded stem scan, each with a positive and a negative control. Three things; the first is correct. 1. The language picker's own „Magyar" button — a picker names each language in its own tongue. 2. The update badge „Naprakész" and its tooltip — **R-589**. Slice 1 listed it; slice 2 was to take it and closed without it. 3. The data-folder card's consequence sentence — **R-590**. It makes a promise about the customer's files, and the label above it is already English, so the line reads half and half. The Apps list also shows fifty Hungarian descriptions: those are the apps nobody has translated yet. ## Claims in the plan that turned out wrong | the plan said | measured | |---|---| | "835 strings and the table is the complete list of copy fields" | **1 032** copy strings; the table omitted `deploy_fields[].placeholder` (13 of them) and counted only the strings with an accent | | "832 with a Hungarian letter" | **832** ✔ | | "three are ASCII-only Hungarian words — „Igen", „Nem", „Nincs"" | **~120** are ASCII-only Hungarian, and those three do not occur in this catalog at all. This is the one that chose an instrument: an accent-only gate passes „Aldomain" (53×) and „A szerver domain neve" (53×) inside an English block | | "catalog copy reaches 13 templates" | **four**: `dashboard.html` (the app rows' second line), `stacks.html` (the Apps list), `app_info.html` (the app page, including the data-folder cards) and `deploy.html`. A fifth, `app_export.html`, reads `.Stack.Meta.Subdomain` — configuration, not copy. Five handler sites feed them | | "no gate reads copy at all" | ✔ correct — none did | | "the sync is 15 min with no pin" | ✔ correct; a manual trigger exists (`POST /api/sync`, the dashboard's "Sablonok frissítése") and was used | | "`yaml.Unmarshal` is non-strict" | ✔ correct, and stronger than stated: this repo constructs **no** `yaml.Decoder` at all, so there is no `KnownFields` anywhere that could be turned on | | the line numbers (`metadata.go` L15/L123/L158/L316) | ✔ all correct | | "„Igen", „Nem", „Nincs" are the ASCII-only option labels" | the three ASCII-only option labels are **„Magyar", „Angol", „Magyar + Angol"** — language names, not yes/no words. „Igen" and „Nem" DO open vaultwarden's two option labels, but both of those carry accents later in the string and were already counted | ## Rows **Opened:** R-589 (the update badge is Hungarian on an English page), R-590 (the data-folder card's backup promise is Hungarian on an English page), R-591 (`Stack.Copy()` deep-copies five `Meta` fields and not the new `I18n` map — safe today, which is why it is a row and not a fix), R-592 (three defects inside the new catalog gate, **closed the same session**, each found by its own decoy rather than by reading it), R-593 (papra describes a session-signing key as „the app's subdomain" — the one string left untranslated), R-594 (the catalog gate can CONVICT a retrieval promise but has no way to REGISTER a true one, which the shared vocabulary's own design calls for). **Closed:** R-560. Register: 281 → 287 rows. ## Documents changed here - `documentation/architecture/10-localisation.md` — §7 rewritten from **[DESIGN, proposed]** to **[FACT] measured**, with the corrected numbers, the key-matching rules, and the gate's five checks; new §10.6 for the slice. - `documentation/backlog/OPEN-ITEMS.md` — the four rows above, and R-560's progress. - `STATUS.md` — the operator note, in plain language, with the one read that is being asked for. - `documentation/audits/i18n-slice5-2026-09-20/` — the captures from both boxes, the Hungarian parity table, the English leftover scan with its controls, and a README saying what was NOT proven. ## Teardown, three layers - **Machine:** nothing installed or removed on either demo box; no app deployed; no VM created. Guest 9201 on demo-hp was restarted onto the new controller image, which is the deploy itself. - **Host:** the staged password file and the capture scripts were shredded from both Proxmox hosts and both guests; `ls` confirms they are gone. - **Hub:** nothing. No floor change, no golden, no vouch, no appliance registration. Both boxes left on Hungarian.