diff --git a/CONTEXT.md b/CONTEXT.md
index 30e46a9a..9f2ea46e 100644
--- a/CONTEXT.md
+++ b/CONTEXT.md
@@ -30,15 +30,29 @@ accent-only scan passes every one of them inside an English block**, which is R-
arriving again in a different repo. The catalog gate folds and matches WORD-BOUNDED stems, with a
positive and two negative controls printed every run.
-**Part C (the other 50 apps) is deliberately not started.** The §16 default was to stop after the
-pilot for the operator's read of the three apps' English; it is quoted in
-`app-catalog-felhom.eu/REPORT.md`.
+**Part C shipped the same day.** The operator read the pilot and said go; the other fifty followed in
+three pushes (17 / 17 / 16 apps). **1 031 of 1 032 strings are English.** The one that is not is
+papra's `AUTH_SECRET` description — a Hungarian defect (R-593) left to fall back rather than
+translated wrongly, and **that is why `EN_MISSING_CEILING`'s floor is 1 rather than 0**, stated in the
+ceiling's own comment so a later session cannot "reach zero" by editing Hungarian.
-**Still the operator's:** raise the fleet floor to **0.257.0**. Until then only demo-hp can read an
-English app block at all.
+**[DESIGN, decided by CC] The English blocks are GENERATED from a flat `{path: english}` map.** A
+mistyped `env_var` in a hand-written block is INERT on the box rather than an error; the generator can
+only write paths that exist on the Hungarian side.
-**Gaps filed:** R-589, R-590, R-591, R-592. Evidence:
-`documentation/audits/i18n-slice5-2026-09-20/`.
+**Measured: the English Apps list shows ZERO Hungarian app descriptions across all 53 apps.** The only
+Hungarian on it is the „Naprakész" badge (R-589) and the language picker naming itself. The Hungarian
+Apps list is identical to the pre-slice capture once the CSRF token AND Docker's own „Up N hours"
+string are normalised — both normalisations stated, not applied quietly.
+
+**FLEET FLOOR RAISED to 0.257.0** (operator asked), `min_agent` 0.131.0 declared, above the vouched
+golden 0.246.0 so the declaration carries it (R-472). Hub `managed floor SERVED … from declared`;
+demo-felhom went **0.255.0 → 0.257.0 by itself in under 12 s**, healthy, `settle-gate: GO`, **and then
+rendered the English tagline** — the floor delivered the FEATURE, not a version string. Peti's box and
+tester-1 are DOWN and take it unattended when they return.
+
+**Gaps filed:** R-589, R-590, R-591, R-592 (closed same session), R-593, R-594. **R-560 CLOSED.**
+Evidence: `documentation/audits/i18n-slice5-2026-09-20/`.
## Decisions 2026-09-17 (afternoon) — the product in more than one language (localisation starter)
diff --git a/REPORT.md b/REPORT.md
index e5ea4e6a..638be722 100644
--- a/REPORT.md
+++ b/REPORT.md
@@ -4,14 +4,15 @@
**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.
-## What the operator has to do
+## Where it ended
-**Read the English of the three pilot apps** — quoted in full in `app-catalog-felhom.eu/REPORT.md` —
-and say "go", or say what to change. Fifty more apps follow whatever is said. Ten minutes now against
-a day of rework later. This is the §16 default of the plan and it was taken: Part C is not started.
+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.
-**And, separately: raise the fleet floor to 0.257.0.** Until it moves, only demo-hp can read an
-English app block at all. Nothing breaks if it waits.
+**Nothing is waiting on the operator from this work.**
## What was proven, and how it was seen
@@ -21,7 +22,9 @@ session — the same handlers and templates a browser drives, with only the draw
| claim | evidence |
|---|---|
-| The English app pages show English catalog text | demo-hp on 0.257.0: privatebin, paperless-ngx, romm app pages, the Apps list, two deploy pages |
+| 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 |
@@ -52,6 +55,7 @@ The Apps list also shows fifty Hungarian descriptions: those are the apps nobody
| "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
@@ -59,11 +63,13 @@ The Apps list also shows fifty Hungarian descriptions: those are the apps nobody
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).
+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).
-**Updated:** R-560 — Parts A and B done, Part C waiting on the operator's read.
+**Closed:** R-560.
-Register: 281 → 285 rows.
+Register: 281 → 287 rows.
## Documents changed here
diff --git a/STATUS.md b/STATUS.md
index fb459158..e69f96fe 100644
--- a/STATUS.md
+++ b/STATUS.md
@@ -1,49 +1,47 @@
# STATUS — what works, what's broken, what's next
-**Updated 2026-09-20 — the apps can describe themselves in English. Three of them do; fifty wait for you.**
+**Updated 2026-09-20 (evening) — every app in the catalog now describes itself in English, and every box can read it.**
> **Ready for a volunteer: yes.**
-**What changed.** On an English dashboard the last Hungarian left was the app text: each app's
-one-line description, its „what is it for" list, its „first steps", and the labels under every
-install setting. That text comes from the app catalog, and the catalog was Hungarian only.
+**What changed.** This morning an English dashboard still showed Hungarian app text — each app's
+description, its „what is it for" list, its „first steps", the labels under every install setting.
+That text lives in the app catalog, and the catalog was Hungarian only.
-Now each app's file can carry an English block next to its Hungarian one, in the same file, so a
-reviewer sees one app whole. The box reads the English **line by line**: any line that has no English
-yet shows the Hungarian one, and a box running an older version ignores the block completely. That is
-what makes it safe to do fifty apps a batch at a time instead of all at once.
+All 53 apps now carry an English version beside the Hungarian one, in the same file. **1 031 of the
+1 032 pieces of text are done.** You read three of them at lunchtime and said go; the other fifty
+follow that same voice.
-**Three apps are done as a pilot** — PrivateBin, Paperless and RomM. I picked those three because
-between them they use every shape the mechanism has to handle, and because all three run on the demo
-box, so I could look at the real pages instead of reasoning about them.
+**The one piece left is not an oversight.** One app's install page explains a security key with the
+sentence that belongs on a different field — it is wrong in Hungarian. I am not allowed to change
+Hungarian words in this kind of release, and translating a wrong sentence would spread the mistake
+into a second language. So that one line still shows the Hungarian. There is a row open to fix the
+Hungarian first.
-**What I checked, on the real boxes.** The three English app pages show English. The Hungarian pages
-are **identical, byte for byte**, before and after — seven pages, same size, same content. And on the
-second demo box, which runs an older version on purpose, the pages are identical too and its log says
-nothing: an old box simply does not see the new block.
+**What I checked, on the real boxes.** The English app list shows **no Hungarian app text at all**,
+across all 53. The Hungarian pages are identical to before, down to the byte. I checked the same on
+a second box that was deliberately left on an older version — it simply ignored the new text, which
+is what lets this be safe.
-**Two things are still Hungarian on an English app page, and I did not fix them today** — the „up to
-date" tag on each app, and the sentence under a data folder that says whether it is backed up. Both
-come from the box's own code, not from the catalog. Rows are open for both. The second one matters
-more: it makes a promise about somebody's files.
+**I raised the box floor to the new version, as you asked.** The second demo box picked it up **by
+itself in under twelve seconds**, came back healthy, and then showed the English text. Two machines
+that are switched off — the tester's box and one other — will take it when they next come on.
-**Rows.** Four opened, one of them already closed.
+**Two things are still Hungarian on an English app page**, and both come from the box's own code
+rather than the catalog: the small „up to date" tag on each app, and the sentence under a data
+folder that says whether it is backed up. Rows are open for both. The second matters more, because
+it makes a promise about somebody's files.
-**Needs you — one read, ten minutes.** Before I translate the other fifty apps, please read the
-English of the three pilot apps (they are quoted in the catalog's report, and live on the demo box in
-English). Say "go", or say what to change in tone or wording. If the tone is wrong, catching it now
-costs ten minutes; catching it after fifty apps costs a day of rework.
+**Rows.** Six opened today, one of them already closed.
-**If you do nothing:** nothing breaks. The three apps stay English, the other fifty stay Hungarian,
-and every Hungarian household sees exactly what it saw yesterday.
+**Needs you — nothing urgent.** The only open question is whether to change the shared demo password.
-**Also still open from before:** raise the box floor — now to **0.257.0**, so every box can read the
-English app text at all. Until the floor moves, only the demo box can. Nothing breaks if it waits.
-And whether to change the shared demo password.
+**If you do nothing:** nothing breaks.
## Previous note
+
**Updated 2026-09-18 (night) — the new installer is published, and the box's screen speaks English too.**
> **Ready for a volunteer: yes.**
diff --git a/documentation/architecture/10-localisation.md b/documentation/architecture/10-localisation.md
index d953fe14..1196cdc5 100644
--- a/documentation/architecture/10-localisation.md
+++ b/documentation/architecture/10-localisation.md
@@ -259,7 +259,7 @@ on another, and both matter to the gate:
|---|---|---|
| copy strings | 835 | **1 032** (incl. 13 placeholders the table omitted, and every ASCII label) |
| with a Hungarian letter | 832 | **832** ✔ |
-| ASCII-ONLY Hungarian | „Igen", „Nem", „Nincs" — three | **~120**, and those three do not occur at all |
+| ASCII-ONLY Hungarian | „Igen", „Nem", „Nincs" — three | **~120**. Those three do not occur; the three ASCII-only OPTION labels are „Magyar", „Angol", „Magyar + Angol" — language names, not yes/no words |
The ASCII-only count is the one that decides an instrument: „Aldomain" (53×), „A szerver domain neve"
(53×), „Jelentkezz be: …" (5×), „Magyar", „Angol", „Titkos kulcs", „Oszd meg a linket". **An
@@ -674,6 +674,47 @@ R-592 (three defects inside the new gate, each found by its own decoy).
**Evidence:** `documentation/audits/i18n-slice5-2026-09-20/`.
+**PART C SHIPPED THE SAME DAY.** The operator read the pilot's English and said go, so the other
+fifty followed its voice in three pushes — 17, 17 and 16 apps; 319, 317 and 306 strings. **1 031 of
+the catalog's 1 032 customer-facing strings now carry an English twin.**
+
+**[DESIGN, decided by CC] The blocks are GENERATED from a flat `{path: english}` map, not
+hand-written.** Fifty nested blocks whose keys must match the Hungarian side exactly is fifty
+chances to mistype an `env_var` — and **a mistyped key is INERT on the box, not an error**, so the
+translator never learns. The generator builds from the same flat paths the freeze uses, which are
+derived from the Hungarian file itself, so a key that does not exist on the Hungarian side cannot be
+written at all. The review then happens on the map, where one line is one string, instead of on
+YAML indentation.
+
+**[FACT] The one string left untranslated, on purpose.** papra's
+`deploy_fields[AUTH_SECRET].description` reads „Az alkalmazás aldomainje" — the sentence that belongs
+on `SUBDOMAIN`, sitting on a session-signing key (R-593). §1 forbids changing the Hungarian in a
+localisation release, and translating a wrong sentence faithfully would ship the error in a second
+language. So it falls back. **That is why `EN_MISSING_CEILING`'s floor is 1 rather than 0, and it is
+written into the ceiling's own comment** so a later session does not "reach zero" by editing
+Hungarian.
+
+**[FACT] Measured on the English Apps list, all 53 apps: ZERO Hungarian app descriptions.** The only
+Hungarian left on that page is the „Naprakész" badge (R-589, ten occurrences) and the language
+picker naming itself. The Hungarian Apps list is identical to the pre-slice capture once the
+per-session CSRF token and Docker's own „Up N hours" string are normalised.
+
+**[FACT] The gate convicted two of the translator's own sentences and was HALF right.** Vaultwarden's
+invite step ended „…can open an account", and the English retrieval-promise pattern reads `can …
+open` as the claim that sealed backups can be opened. Opening an ACCOUNT is not that claim, so the
+conviction was a false positive — and the wording was also the weaker wording, so it became „can
+sign up". **But the gate has no way to REGISTER a true occurrence**, which the shared vocabulary's
+own design calls for; R-594.
+
+**[FACT] The fleet floor was raised to 0.257.0** the same session (operator asked), `min_agent`
+0.131.0 declared — above the vouched golden 0.246.0, so the declaration is what carries it (R-472).
+Hub: `managed floor SERVED for demo-felhom: floor 0.257.0, agent requirement "0.131.0" from declared
+(golden 0.246.0)`. **demo-felhom went 0.255.0 → 0.257.0 by itself in under 12 seconds**, healthy,
+its own log reading `settle-gate: GO — at/above floor 0.257.0`, and it then rendered the English
+tagline — the floor delivered function, not just a version string. Peti's box and tester-1 are DOWN
+and take it unattended when they return; untested on this version.
+
+
## 11. Operator decisions
These are rulings, not proposals. Anything specced against a different assumption is wrong.
diff --git a/documentation/audits/i18n-slice5-2026-09-20/C1/b1-after/adventurelog.en.html b/documentation/audits/i18n-slice5-2026-09-20/C1/b1-after/adventurelog.en.html
new file mode 100644
index 00000000..4103c630
--- /dev/null
+++ b/documentation/audits/i18n-slice5-2026-09-20/C1/b1-after/adventurelog.en.html
@@ -0,0 +1,642 @@
+
+
+
+
+
Travel journal - keep your trips with a map and photos
+
+
+ ~100M RAM
+ travel
+
+ Runs on Pi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Move to another storage
+
You can move this app’s data to another connected storage. The app stops briefly during the move, and the data is deleted from the old place only after the check and a successful restart.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
What is it for?
+
+
Keep your trips with pictures and notes
See everywhere you have been on a map
Plan and organise trips before you go
Statistics - the countries and cities you have visited
Utazási napló - utazások dokumentálása térképpel és fotókkal
+
+
+ ~100M RAM
+ travel
+
+ Pi kompatibilis
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Áthelyezés másik tárhelyre
+
Ennek az alkalmazásnak az adatait másik csatlakoztatott tárhelyre helyezheted át. Az alkalmazás az áthelyezés alatt rövid időre leáll, az adatok pedig csak az ellenőrzés és a sikeres újraindítás után törlődnek a régi helyről.
A privacy-first PDF toolbox - your files never leave your own server
+
+
+ ~100M RAM
+ tools
+
+ Runs on Pi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Move to another storage
+
You can move this app’s data to another connected storage. The app stops briefly during the move, and the data is deleted from the old place only after the check and a successful restart.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
What is it for?
+
+
Merge, split and rotate PDFs
Convert PDFs to images and images to PDFs
Password protection and encryption
Add a watermark to a document
Everything happens on your own server - no file goes to an outside service
Adatvédelmi fókuszú PDF eszköztár - a fájlok soha nem hagyják el a szervered
+
+
+ ~100M RAM
+ tools
+
+ Pi kompatibilis
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Áthelyezés másik tárhelyre
+
Ennek az alkalmazásnak az adatait másik csatlakoztatott tárhelyre helyezheted át. Az alkalmazás az áthelyezés alatt rövid időre leáll, az adatok pedig csak az ellenőrzés és a sikeres újraindítás után törlődnek a régi helyről.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Mire használható?
+
+
PDF összefűzés, szétválasztás és forgatás
PDF konvertálás képekké és képekből
Jelszóvédelem és titkosítás
Vízjel hozzáadása dokumentumokhoz
Minden feldolgozás a szerveren - a fájlok nem kerülnek külső szolgáltatóhoz
+
+
+
+
+
+
+
Első lépések
+
+
Nyisd meg a pdf.DOMAIN címet a böngészőben
Válaszd ki a kívánt műveletet
Töltsd fel a PDF fájlt és kattints a feldolgozásra
A simple wiki platform - shelves, books, chapters and pages
+
+
+ ~150M RAM
+ productivity
+
+ Runs on Pi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Move to another storage
+
You can move this app’s data to another connected storage. The app stops briefly during the move, and the data is deleted from the old place only after the check and a successful restart.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
What is it for?
+
+
A family knowledge base - recipes, manuals, house rules
Project documentation with a structure you can follow
Book > Chapter > Page, so a large set stays readable
Full text search and tags
A visual editor and a Markdown editor
+
+
+
+
+
+
+
First steps
+
+
Open wiki.DOMAIN in your browser
Sign in: admin@admin.com / password
Change the admin password and e-mail address straight away
Ennek az alkalmazásnak az adatait másik csatlakoztatott tárhelyre helyezheted át. Az alkalmazás az áthelyezés alatt rövid időre leáll, az adatok pedig csak az ellenőrzés és a sikeres újraindítás után törlődnek a régi helyről.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Mire használható?
+
+
Családi tudásbázis - receptek, kézikönyvek, szabályok
Projekt dokumentáció strukturált formában
Könyv > Fejezet > Oldal hierarchia az áttekinthetőségért
Teljes szöveges keresés és címkék
WYSIWYG és Markdown szerkesztő
+
+
+
+
+
+
+
Első lépések
+
+
Nyisd meg a wiki.DOMAIN címet a böngészőben
Jelentkezz be: admin@admin.com / password
Változtasd meg azonnal az admin jelszót és email címet
Hozd létre az első polcot és könyvet
Kezdj el írni!
+
+
+
+
+
+
+
+
+
+
+
Alapértelmezett belépés
+
admin@admin.com / password
+
Az első bejelentkezés után azonnal változtasd meg!
Utazási napló - utazások dokumentálása térképpel és fotókkal
+
+
+ ~100M RAM
+ travel
+
+ Runs on Pi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Move to another storage
+
You can move this app’s data to another connected storage. The app stops briefly during the move, and the data is deleted from the old place only after the check and a successful restart.
Utazási napló - utazások dokumentálása térképpel és fotókkal
+
+
+ ~100M RAM
+ travel
+
+ Pi kompatibilis
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Áthelyezés másik tárhelyre
+
Ennek az alkalmazásnak az adatait másik csatlakoztatott tárhelyre helyezheted át. Az alkalmazás az áthelyezés alatt rövid időre leáll, az adatok pedig csak az ellenőrzés és a sikeres újraindítás után törlődnek a régi helyről.
Adatvédelmi fókuszú PDF eszköztár - a fájlok soha nem hagyják el a szervered
+
+
+ ~100M RAM
+ tools
+
+ Runs on Pi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Move to another storage
+
You can move this app’s data to another connected storage. The app stops briefly during the move, and the data is deleted from the old place only after the check and a successful restart.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
What is it for?
+
+
PDF összefűzés, szétválasztás és forgatás
PDF konvertálás képekké és képekből
Jelszóvédelem és titkosítás
Vízjel hozzáadása dokumentumokhoz
Minden feldolgozás a szerveren - a fájlok nem kerülnek külső szolgáltatóhoz
+
+
+
+
+
+
+
First steps
+
+
Nyisd meg a pdf.DOMAIN címet a böngészőben
Válaszd ki a kívánt műveletet
Töltsd fel a PDF fájlt és kattints a feldolgozásra
Adatvédelmi fókuszú PDF eszköztár - a fájlok soha nem hagyják el a szervered
+
+
+ ~100M RAM
+ tools
+
+ Pi kompatibilis
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Áthelyezés másik tárhelyre
+
Ennek az alkalmazásnak az adatait másik csatlakoztatott tárhelyre helyezheted át. Az alkalmazás az áthelyezés alatt rövid időre leáll, az adatok pedig csak az ellenőrzés és a sikeres újraindítás után törlődnek a régi helyről.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Mire használható?
+
+
PDF összefűzés, szétválasztás és forgatás
PDF konvertálás képekké és képekből
Jelszóvédelem és titkosítás
Vízjel hozzáadása dokumentumokhoz
Minden feldolgozás a szerveren - a fájlok nem kerülnek külső szolgáltatóhoz
+
+
+
+
+
+
+
Első lépések
+
+
Nyisd meg a pdf.DOMAIN címet a böngészőben
Válaszd ki a kívánt műveletet
Töltsd fel a PDF fájlt és kattints a feldolgozásra
Egyszerű wiki platform - polcok, könyvek, fejezetek és oldalak
+
+
+ ~150M RAM
+ productivity
+
+ Runs on Pi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Move to another storage
+
You can move this app’s data to another connected storage. The app stops briefly during the move, and the data is deleted from the old place only after the check and a successful restart.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
What is it for?
+
+
Családi tudásbázis - receptek, kézikönyvek, szabályok
Projekt dokumentáció strukturált formában
Könyv > Fejezet > Oldal hierarchia az áttekinthetőségért
Teljes szöveges keresés és címkék
WYSIWYG és Markdown szerkesztő
+
+
+
+
+
+
+
First steps
+
+
Nyisd meg a wiki.DOMAIN címet a böngészőben
Jelentkezz be: admin@admin.com / password
Változtasd meg azonnal az admin jelszót és email címet
Ennek az alkalmazásnak az adatait másik csatlakoztatott tárhelyre helyezheted át. Az alkalmazás az áthelyezés alatt rövid időre leáll, az adatok pedig csak az ellenőrzés és a sikeres újraindítás után törlődnek a régi helyről.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Mire használható?
+
+
Családi tudásbázis - receptek, kézikönyvek, szabályok
Projekt dokumentáció strukturált formában
Könyv > Fejezet > Oldal hierarchia az áttekinthetőségért
Teljes szöveges keresés és címkék
WYSIWYG és Markdown szerkesztő
+
+
+
+
+
+
+
Első lépések
+
+
Nyisd meg a wiki.DOMAIN címet a böngészőben
Jelentkezz be: admin@admin.com / password
Változtasd meg azonnal az admin jelszót és email címet
Hozd létre az első polcot és könyvet
Kezdj el írni!
+
+
+
+
+
+
+
+
+
+
+
Alapértelmezett belépés
+
admin@admin.com / password
+
Az első bejelentkezés után azonnal változtasd meg!
Share code snippets - a private GitHub Gist alternative
+
+
+ ~30M RAM
+ dev
+
+ Runs on Pi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Move to another storage
+
You can move this app’s data to another connected storage. The app stops briefly during the move, and the data is deleted from the old place only after the check and a successful restart.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
What is it for?
+
+
Share code snippets and pieces of text
Syntax highlighting for many languages
Private and public gists
Stored in Git, so every version is kept for you
Markdown support and embedding
+
+
+
+
+
+
+
First steps
+
+
Open gist.DOMAIN in your browser
Create your account (the first user becomes the admin)
Create your first gist - type the code in and save it
Kód snippetek megosztása - privát GitHub Gist alternatíva
+
+
+ ~30M RAM
+ dev
+
+ Pi kompatibilis
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Áthelyezés másik tárhelyre
+
Ennek az alkalmazásnak az adatait másik csatlakoztatott tárhelyre helyezheted át. Az alkalmazás az áthelyezés alatt rövid időre leáll, az adatok pedig csak az ellenőrzés és a sikeres újraindítás után törlődnek a régi helyről.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Mire használható?
+
+
Kód snippetek és szövegek megosztása
Szintaxis kiemelés sok programozási nyelvhez
Privát és nyilvános gistek
Git-alapú tárolás - verziókezelés automatikusan
Markdown támogatás és beágyazás
+
+
+
+
+
+
+
Első lépések
+
+
Nyisd meg a gist.DOMAIN címet a böngészőben
Hozd létre a fiókodat (az első felhasználó admin lesz)
Hozd létre az első gistet - írd be a kódot és mentsd
Import Hungarian recipe sites without fuss - one at a time or in bulk, into Mealie and Tandoor
+
+
+ ~30M RAM
+ tools
+
+ Runs on Pi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
What is it for?
+
+
Import recipes from 6 Hungarian sites: mindmegette.hu, streetkitchen.hu, nosalty.hu, sobors.hu, kiskegyed.hu and gastrohobbi.hu - ingredients, steps, pictures and tags are picked out for you
Bulk import: paste several addresses at once, either reviewing each recipe or letting it run on its own
Edit before importing - structured ingredients (amount, unit, food, note), changes to the steps, and the tags
Mealie and Tandoor Recipes at the same time - pick one, or import into both at once
For a site it does not know, it reads schema.org JSON-LD instead (recipeIngredient, recipeInstructions, keywords)
+
+
+
+
+
+
+
First steps
+
+
Open rimport.DOMAIN in your browser
Go to the Settings page and enter the Mealie and/or Tandoor address and API key (Mealie: Profile -> API Tokens; Tandoor: Settings -> API Browser -> Auth Token)
Set a user name and password to keep it to yourself
Paste a recipe address on the import page, select Process, then select Import once you have checked it
+
+
+
+
+
+
+
Before you start
+
+
Mealie and/or Tandoor Recipes installed and reachable on the network
An API key created in the target app (Mealie and/or Tandoor)
Mealie és Tandoor Recipes egyidejű támogatás — választhatsz célrendszert, vagy mindkettőbe importálhatsz egyszerre
Ismeretlen oldalak esetén schema.org JSON-LD alapú automatikus feldolgozás (recipeIngredient, recipeInstructions, keywords)
+
+
+
+
+
+
+
Első lépések
+
+
Nyisd meg a rimport.DOMAIN címet a böngészőben
Menj a Beállítások oldalra és add meg a Mealie és/vagy Tandoor URL-t és API kulcsot (Mealie: Profil → API Tokens; Tandoor: Beállítások → API Browser → Auth Token)
Állíts be felhasználónevet és jelszót a hozzáférés védelméhez
Illeszd be egy recept URL-jét az importálás oldalon, kattints a Feldolgozás gombra, majd ellenőrzés után az Importálás gombra
+
+
+
+
+
+
+
Előfeltételek
+
+
Mealie és/vagy Tandoor Recipes telepítve és elérhető a hálózaton
API kulcs a célalkalmazásban (Mealie és/vagy Tandoor) létrehozva
A password manager - Bitwarden-compatible, on your own server
+
+
+ ~50M RAM
+ security
+
+ Runs on Pi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
What is it for?
+
+
Keep your passwords safely and let them fill themselves in
Every Bitwarden client works (browser, phone, desktop)
Share a password with the household inside an organisation
Keep two-factor (TOTP) codes
Keep secure notes and card details
+
+
+
+
+
+
+
First steps
+
+
Open vault.DOMAIN/admin and sign in with the admin panel token (Settings -> Automatically generated values)
On the "Users" tab, use "Invite User" to invite your own and the household's e-mail addresses - signing up is closed by default, so only an invited address can sign up
Open vault.DOMAIN, choose "Create account" with the invited address, and set a strong master password
Install the Bitwarden extension in your browser
Install the Bitwarden app on your phone
Import the passwords you already have (Chrome, Firefox, LastPass and so on)
Jelszókezelő - Bitwarden kompatibilis, a saját szerveren
+
+
+ ~50M RAM
+ security
+
+ Pi kompatibilis
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Mire használható?
+
+
Jelszavak biztonságos tárolása és automatikus kitöltése
Bitwarden kliensek teljes kompatibilitása (böngésző, mobil, asztali)
Jelszavak megosztása családtagokkal szervezeten belül
Kétfaktoros hitelesítés (TOTP) kódok tárolása
Biztonságos jegyzetek és bankkártya adatok tárolása
+
+
+
+
+
+
+
Első lépések
+
+
Nyisd meg a vault.DOMAIN/admin címet, és lépj be az admin panel tokenjével (Beállítások → Automatikusan generált értékek)
A „Users" fülön az „Invite User" mezőben hívd meg a saját és a családtagok e-mail címét — a regisztráció alapból le van zárva, csak meghívott cím nyithat fiókot
Nyisd meg a vault.DOMAIN címet, válaszd a „Create account" lehetőséget a meghívott címmel, és adj meg erős mesterjelszót
Telepítsd a Bitwarden bővítményt a böngésződbe
Telepítsd a Bitwarden alkalmazást a telefonodra
Importáld a meglévő jelszavaidat (Chrome, Firefox, LastPass, stb.)
+
+
+
+
+
+
+
+
+
+
diff --git a/documentation/audits/i18n-slice5-2026-09-20/README.md b/documentation/audits/i18n-slice5-2026-09-20/README.md
index a1db9d15..eb56ba4b 100644
--- a/documentation/audits/i18n-slice5-2026-09-20/README.md
+++ b/documentation/audits/i18n-slice5-2026-09-20/README.md
@@ -1,7 +1,8 @@
# Localisation slice 5 — the app catalog's own words (R-560), 2026-09-20
-Controller **v0.257.0** (the read path) + the catalog **pilot** (privatebin, paperless-ngx, romm).
-Part C — the other fifty apps — is **not started**: the pilot stops for the operator's read.
+Controller **v0.257.0** (the read path) + the catalog **pilot**, then — after the operator read the
+pilot and said go — **all fifty remaining apps in three batches**, and then **the fleet floor raised
+to 0.257.0**. 1 031 of the catalog's 1 032 customer-facing strings are English.
Method: **endpoint-level**. No browser is available on DooPlex, so every page below was fetched with
`curl` from inside the guest at the controller's container address, with the customer `Host` header
@@ -12,14 +13,34 @@ the rendering skipped. Said plainly because a claim of "the page shows X" has to
| path | what |
|---|---|
-| `B/live/cap-before/` | demo-hp guest 9201 on **0.257.0**, BEFORE the catalog push — 7 pages × hu/en |
+| `B/live/cap-before/` | demo-hp guest 9201 on **0.257.0**, BEFORE the pilot push — 7 pages × hu/en |
| `B/live/cap-after/` | the same 7 pages × hu/en AFTER the push and a forced template sync |
| `B/old-controller/old-before/` | demo-felhom guest 9201 on **0.255.0**, before the block reached it |
| `B/old-controller/old-after/` | the same, after the block reached it (sync confirmed positively) |
| `B/hungarian-parity.txt` | the before/after comparison of every Hungarian page |
| `B/english-leftovers.txt` | the accent + ASCII-folded scan of every English page, with its controls |
+| `C1/b1-before/`, `C1/b1-after/` | four batch-1 apps × hu/en, around that push's sync |
+| `C3/final/`, `C3/final2/` | after the LAST batch: the whole Apps list in both languages, and five batch-3 apps |
-## The three results
+## Part C, and the floor
+
+**The English Apps list shows ZERO Hungarian app descriptions, across all 53 apps** (`C3/final/`).
+The only Hungarian on that page is the „Naprakész" update badge (R-589, ten occurrences) and the
+language picker naming itself, which is correct — a picker names each language in its own tongue.
+
+**The Hungarian Apps list is identical to the pre-slice capture**, once two things are normalised:
+the per-session CSRF token, and Docker's own „Up N hours" container-status string, which moved
+because two hours of wall clock passed between the captures. Nothing else differs. Both
+normalisations are stated here rather than applied quietly.
+
+**The floor was raised to 0.257.0** with `min_agent` 0.131.0 declared — above the vouched golden
+0.246.0, so the declaration is what carries it. Hub log: `managed floor SERVED for demo-felhom:
+floor 0.257.0, agent requirement "0.131.0" from declared (golden 0.246.0)`. demo-felhom went
+**0.255.0 → 0.257.0 by itself in under 12 seconds**, healthy, `settle-gate: GO — at/above floor
+0.257.0`, **and then rendered the English tagline**. Peti's box and tester-1 are DOWN and take it
+unattended when they return.
+
+## The three results of the pilot phase
**1. The English pages show the English catalog text.** privatebin's tagline, use cases and first
steps, paperless-ngx's select options and folder label, romm's optional-config group — all English on
diff --git a/documentation/backlog/OPEN-ITEMS.md b/documentation/backlog/OPEN-ITEMS.md
index b5dff120..13f31b7d 100644
--- a/documentation/backlog/OPEN-ITEMS.md
+++ b/documentation/backlog/OPEN-ITEMS.md
@@ -736,7 +736,7 @@ class (an image `VOLUME` at an unmounted path) is still live — `immich-server`
| **R-557** | **[P3-LOW] Localisation slice 2 — Go-side customer strings follow the language.** PLAN 2026-09-17 (10 §10). Inventory §2.2: 947 shown + 184 error literals in 84 files; 237 format strings, 111 concatenations, 42 numeric `%d` (English plurals). Flash messages travel inside the redirect URL (`?flash=`) and must become keys; `cloudflare/countries.go` (113 country names); alert texts; handler errors printed with `err.Error()`. **After R-553** (the four compare-not-show sites). Cost 16–20 CC-hours. **DEPENDENCY added 2026-09-17 (R-553 shipped, v0.251.0):** the behaviour-by-wording sites are fixed, so this slice is unblocked — EXCEPT one producer: `"Sikeres — nincs mentésre jelölt alkalmazás"` (controller/internal/backup/offbox.go) must stay Hungarian until **R-570** closes, because the page's legacy fallback still reads it on boxes that have not run off-site since 0.251.0. Everything else this slice touches is now decided by a kind, not by its words. **RELEASE A SHIPPED 2026-09-18 (controller v0.252.0):** 226 Go literals converted -- flash-as-key (8 writers, 8 readers, legacy prose still shown verbatim), page data and view-model text, the `internal/api` JSON answers, the alert banners (`Alert.MessageKey`), 237 country names at DISPLAY (the cloudflare table is untouched -- only CODES are on the wire, the task claimed otherwise), and the four app-named page titles (R-566 CLOSED). New gate `i18n_go_parity.py` + `i18n_go_base.json` (7 467 base-commit literals, frozen) refuses any key whose Hungarian is not byte-identical; three decoys. Wire goldens freeze `internal/monitor` and `internal/notify` -- the hub MAILS the event message when it has no `customerMessages` entry, so those stay Hungarian until R-558. `HU_FORMAL_CEILING` 16 -> 18 (measured, no word changed). **RELEASE B SHIPPED 2026-09-18 (controller v0.253.0): all 179 error literals carry a key** via `util.MsgError` -- `Error()` is still the Hungarian byte for byte, `errors.Is` answers for the kind AND a wrapped cause, an error ARGUMENT renders recursively, and a foreign error (restic/docker/ssh/stdlib) prints verbatim. 76 display sites go through `errText`, pinned by `TestNoErrErrorInPageOutput`. `memoryVerdict` returns an error; `UpdateRefusal` gained a `Cause`. Plurals are a BUNDLE rule (a key with `.one`/`.other` takes its count first), not a call-site flag. **ZERO Hungarian error literals remain** (ASCII search with both controls, case-insensitive). Two tooling defects found and filed: R-576 (the converter dropped concatenations and the gate could not see it) and the case-sensitive counter. New gap: R-575. **RELEASE C SHIPPED 2026-09-18 (controller v0.254.0) -- SLICE 2 CLOSED.** ~70 saved-note producers write in the BOX language at write time (s16 option 1; a household that switches sees the previous run's note in the old language until the next run). `EndRestoreOp` takes no Hungarian literal from anywhere. The switch became a GLOBE on the dashboard and on the pages outside the dashboard chrome; a visitor with no session gets a display-only `felhom_lang` cookie that `langFor` reads ONLY when there is no session, and a successful CLAIM carries it into the setting (s16). Two parity blocks, measured with a real diff: 3 change shapes across 106 fixtures (footer; the recovery globe posting to the household switch; the login/claim globe posting to /lang), 5 byte-identical. **A DEADLOCK was introduced and caught by the suite hanging (R-578).** Gaps filed: R-572..R-578. | **CLOSED 2026-09-18 - controller v0.252.0 + v0.253.0 + v0.254.0** |
| **R-558** | **[P3-LOW] Localisation slice 3 — the hub's customer e-mails follow the household's language; the operator sets it at customer creation.** PLAN 2026-09-17 (10 §3, §10), operator decision 2. The box already reports `"language"` (controller v0.247.0); nothing hub-side reads it. Build: a per-customer language on the hub (default hu) set at creation and rendered into `controller.yaml` beside `customer.*` (`hub/internal/configgen/configgen.go`), used by the box only while `settings.json` has no choice; the dispatcher picks the language the box REPORTS; English for the 39 `customerMessages`, the 4 severity labels, the body wrapper, the claim/re-enroll/reset/claimed/self-bind mails and the public bind page (inventory §2.3). Delete the `language` allowlist entry in `wire_contract_gate.py` when the field is read. Cost 6-8 CC-hours, one hub + one controller release. **THE WIRE SURVEY (R-557 release A, 2026-09-18) HANDS THIS ROW ITS INPUT LIST:** (1) `internal/notify/notifier.go` -- 31 event messages. The task assumed the hub composes its own mail from the event kind; it does NOT. `FormatCustomerEmail` uses `customerMessages[eventType]` when it has one and **falls back to the controller's message when it has none**, and appends it as „- Üzenet: %s” whenever the two differ -- several types carry no entry precisely so the controller's dynamic sentence IS the mail (hub `api/handler.go` L2034/L2045/L2066). So an English household's mail is Hungarian until this row ships. (2) `internal/monitor/healthcheck.go` -- 5 storage sentences in report `health.warnings`/`health.issues`, operator-facing. Both are frozen by wire goldens in those packages, so no later slice can translate them by accident; this row is what unfreezes them. **SLICE 3 SHIPPED AND CLOSED 2026-09-18 — hub v0.118.0/v0.118.1 + controller v0.256.0/v0.256.1.** The hub reads the language the box reports and writes the household's e-mail in it; nothing an operator reads moved. 56 mail goldens per language captured from hub v0.117.0 BEFORE any string moved, and all 56 Hungarian ones pass unchanged. Order: last reported -> created-with -> hu. `message_customer` carries the sentences the box composes and the hub cannot translate; 19 producers render both from ONE key, and their Hungarian is byte-identical by the Go parity gate. A Hungarian household sends no second copy, so the fleet's payload is unchanged. The bind page is per-language with `expired` pinned to Hungarian (the language would otherwise be the oracle the text refuses to be). Proven live twice: a real English e-mail read in the inbox and the Hungarian one 74 s later (Part A), and the box's push log showing `[hu-only]` then `[+household(en)]` for the same event 57 s apart (Part B). Gaps filed: R-581 (received_at ties), R-582 (the English guard), R-583 (the test mail), R-584 (credential litter), R-585 (six unconverted producers). R-555 closed with it. | **CLOSED 2026-09-18 - hub v0.118.1 + controller v0.256.1** |
| **R-559** | **[P3-LOW] Localisation slice 4 — the console banner and the download page in English.** IN SCOPE — operator ruling 2026-09-17 evening („yes", 10 §11 1b). PLAN 2026-09-17 (10 §10, open decision 1b): the starter listed them; the operator's scope ruling names „the controller, emails, guide, app catalog" and not them. Inventory §2.4: 34 banner lines (`scripts/iso/felhom-bootstrap.sh`, printf to the console; `/etc/issue` byte-coupled to `iso/pkg/debian/postinst`, console font avoids ő/ű) and 32 strings on `website/letoltes.html`. Cost 4–6 CC-hours plus an ISO release train. **SLICE 4 SOURCE SHIPPED 2026-09-18 (ISO 1.29.0 source + the English download page); the IMAGE IS NOT PUBLISHED — that is the operator's step.** The three console texts are bilingual: Hungarian block byte-for-byte as before, then English, inside the same frame; the GRUB entries gain an English half; `postinst`'s byte-coupled copy of the issue text changed identically. The Hungarian is a GOLDEN captured before any English existed, and the harness also pins no-Hungarian-letter-in-English (Hungarian block as the positive control), ≤ 80 columns, and ≤ 25 ROWS — the pairing banner is 24 on a 25-row console, one row of margin. `felhom.eu/en/download` is LIVE, linked both ways, and a site gate refuses the two download pages naming different installer files or checksums. **The release gate's G16 required every Felhom string to be Hungarian and would have stopped this**; ruling 1b (2026-09-17) supersedes that scope, so G16 was REWRITTEN, not waived. Built and gate-checked mechanically: `felhom-installer-1.29.0-pve9.2-1.iso`, sha256 `c67ceaa3…fb02`. Publishing needs a proof install on BOTH menu entries plus a reboot. Gaps filed: R-586, R-587, R-588. **PUBLISHED 2026-09-18: ISO 1.29.0, sha256 `dceacae5…e94829`, live at iso.felhom.eu, and both download pages now name it.** Proof installs on BOTH menu entries (graphical VM 323, text VM 325), each with first boot AND one reboot: `/etc/issue` bilingual with 0 hits for 8006, `pvebanner` masked, package 1.29.0 installed, unit enabled and fired, pairing code present, and the installed script byte-identical to repo HEAD. G11 round trip: the downloaded bytes hash to the published checksum. **A defect was caught between builds by looking at the screen**: the second menu entry's English half was cut off at `Instal` by the GRUB box width, so it was shortened and the image rebuilt. VMs destroyed, the two unclaimed appliance registrations discarded, guest 9201 untouched (23 containers before and after). | **CLOSED 2026-09-18 — ISO 1.29.0 published** |
-| **R-560** | **[P3-LOW] Localisation slice 5 — catalog cards, settings and first steps in English.** PLAN 2026-09-17 (10 §7, §10). Inventory §2.5: 835 strings, ~4 984 words across all 53 `.felhom.yml` (use_cases 262, first_steps 233, deploy_fields descriptions 79 / labels 68, prerequisites 60, description 56, tagline 53). Proposed format: an `i18n: {en: {...}}` block inside each `.felhom.yml` (controller's `yaml.Unmarshal` ignores unknown keys, so older controllers are unaffected), field-by-field fallback. Needs a controller change to read it and catalog copy gates with an English rule. Cost 12–16 CC-hours. **PART A SHIPPED 2026-09-20 (controller v0.257.0)** — `Metadata.For(lang)` merges the block FIELD BY FIELD (absent or blank English shows Hungarian, so a half-translated app is shippable); `For("hu")` is the parsed struct with `I18n` cleared, measured against all 53 real catalog files copied into `internal/stacks/testdata/catalog/`; lists replace WHOLE and every other list is matched by its own key (`env_var`, option `value`, `match_group`, `target`, `path`), never by position; `For` never writes through the shared metadata. Pages reach copy only via `LocalizeStacks`/`LocalizeStackPtr`/`MetaFor`, pinned by `TestNoDirectMetaCopyReadOnPages`'s named allow-list. Eight red-proofs; TWO of them convicted a hollow TEST rather than the code (a struct copy shares its slices' backing arrays, so the obvious DeepEqual check passed a broken merge; a one-entry fixture cannot tell key matching from position matching). **PART B SHIPPED 2026-09-20 (catalog `e81d41e`)** — the freeze (`scripts/copy_freeze/hu.json`, its own commit, 1 032 strings across 53 apps), the `copy-i18n` gate (freeze + structure + language + credentials + ratchet) with 18 decoy cases, and the PILOT: privatebin, paperless-ngx and romm, 89 strings, `EN_MISSING_CEILING` 1032 → 943. **PROVEN LIVE on demo-hp** (0.257.0): the three English app pages and the Apps list show the English catalog text, and the HUNGARIAN pages are byte-identical before and after the push apart from the CSRF token (7 pages). **PROVEN on an OLD controller** (demo-felhom, 0.255.0): with the block synced onto the box, its pages hash identically before and after and its log carries no parse warning — in a 93-line window that includes the sync lines, so the absence is real. **MEASURED AGAINST THIS ROW'S OWN NUMBERS:** 1 032 copy strings, not 835; 832 of them carry a Hungarian letter (that half was right); the ASCII-only Hungarian is ~120 strings, not three — „Aldomain" and „A szerver domain neve" alone are 53 each, and „Igen"/„Nem"/„Nincs" do not occur in this catalog at all. **PART C (the other 50) IS NOT STARTED** — the pilot stops for the operator's read of the three apps' English (§16 default). Gaps filed: R-589, R-590, R-591, R-592. | **PART A+B DONE 2026-09-20 (ctrl v0.257.0 + catalog pilot) — PART C waits on the operator's read of the pilot; rank P3-LOW; owner: CC** |
+| **R-560** | **[P3-LOW] Localisation slice 5 — catalog cards, settings and first steps in English.** PLAN 2026-09-17 (10 §7, §10). Inventory §2.5: 835 strings, ~4 984 words across all 53 `.felhom.yml` (use_cases 262, first_steps 233, deploy_fields descriptions 79 / labels 68, prerequisites 60, description 56, tagline 53). Proposed format: an `i18n: {en: {...}}` block inside each `.felhom.yml` (controller's `yaml.Unmarshal` ignores unknown keys, so older controllers are unaffected), field-by-field fallback. Needs a controller change to read it and catalog copy gates with an English rule. Cost 12–16 CC-hours. **PART A SHIPPED 2026-09-20 (controller v0.257.0)** — `Metadata.For(lang)` merges the block FIELD BY FIELD (absent or blank English shows Hungarian, so a half-translated app is shippable); `For("hu")` is the parsed struct with `I18n` cleared, measured against all 53 real catalog files copied into `internal/stacks/testdata/catalog/`; lists replace WHOLE and every other list is matched by its own key (`env_var`, option `value`, `match_group`, `target`, `path`), never by position; `For` never writes through the shared metadata. Pages reach copy only via `LocalizeStacks`/`LocalizeStackPtr`/`MetaFor`, pinned by `TestNoDirectMetaCopyReadOnPages`'s named allow-list. Eight red-proofs; TWO of them convicted a hollow TEST rather than the code (a struct copy shares its slices' backing arrays, so the obvious DeepEqual check passed a broken merge; a one-entry fixture cannot tell key matching from position matching). **PART B SHIPPED 2026-09-20 (catalog `e81d41e`)** — the freeze (`scripts/copy_freeze/hu.json`, its own commit, 1 032 strings across 53 apps), the `copy-i18n` gate (freeze + structure + language + credentials + ratchet) with 18 decoy cases, and the PILOT: privatebin, paperless-ngx and romm, 89 strings, `EN_MISSING_CEILING` 1032 → 943. **PROVEN LIVE on demo-hp** (0.257.0): the three English app pages and the Apps list show the English catalog text, and the HUNGARIAN pages are byte-identical before and after the push apart from the CSRF token (7 pages). **PROVEN on an OLD controller** (demo-felhom, 0.255.0): with the block synced onto the box, its pages hash identically before and after and its log carries no parse warning — in a 93-line window that includes the sync lines, so the absence is real. **MEASURED AGAINST THIS ROW'S OWN NUMBERS:** 1 032 copy strings, not 835; 832 of them carry a Hungarian letter (that half was right); the ASCII-only Hungarian is ~120 strings, not three — „Aldomain" and „A szerver domain neve" alone are 53 each, and „Igen"/„Nem"/„Nincs" do not occur in this catalog at all. **PART C SHIPPED 2026-09-20, THE SAME DAY** — the operator read the pilot and said go, so the other fifty followed its voice in three pushes: batch 1 (17 apps, 319 strings), batch 2 (17 apps, 317), batch 3 (16 apps, 306). `EN_MISSING_CEILING` 1032 → 943 → 624 → 307 → **1**. **1 031 of the 1 032 strings carry an English twin**; the one that does not is papra's `AUTH_SECRET` description, a Hungarian defect (R-593) deliberately left to fall back rather than translated wrongly — that one string is why the ceiling's floor is 1 and not 0, and it is written into the ceiling's own comment. **The blocks are GENERATED from a flat `{path: english}` map**, not hand-written: a mistyped `env_var` is INERT on the box rather than an error, and the generator can only write paths that exist on the Hungarian side. **PROVEN LIVE, both boxes:** the English Apps list on demo-hp shows **zero** Hungarian app descriptions across all 53 (the only Hungarian left on it is the „Naprakész" badge, R-589, and the language picker naming itself); the Hungarian Apps list is identical to the pre-slice capture once the per-session CSRF token and Docker's own „Up N hours" are normalised. **THE FLEET FLOOR WAS RAISED to 0.257.0** (operator asked; `min_agent` 0.131.0 declared, above the vouched golden 0.246.0 so the declaration carries it, R-472): hub `managed floor SERVED for demo-felhom: floor 0.257.0 … from declared`, and demo-felhom went **0.255.0 → 0.257.0 by itself in under 12 seconds**, healthy, its own log `settle-gate: GO — at/above floor 0.257.0`, and it then rendered the English tagline. **Peti's box and tester-1 are DOWN and take it unattended when they return** — untested on this version. Gaps filed: R-589, R-590, R-591, R-592, R-593, R-594. | **CLOSED 2026-09-20 — controller v0.257.0, catalog fully translated, fleet floor 0.257.0** |
| **R-561** | **[P3-LOW] Localisation slice 6 — the volunteer guide in English, then a stranger's first hour in English; closes R-516.** PLAN 2026-09-17 (10 §10). `runbooks/VOLUNTEER-first-hour.md`: 44 paragraphs, ~1 579 words. Then the 2026-09-14 walk repeated by an English speaker on a fresh box, R-516 closed against `audits/I18N-INVENTORY-2026-09-17.md`. Depends on R-556..R-560. Cost 6–8 CC-hours plus the attended walk. | **READY - rank P3-LOW; owner: CC** |
| **R-562** | **[P3-LOW] Dates and sizes are not formatted for any locale — and the Hungarian pages disagree with themselves.** FOUND 2026-09-17 by the i18n inventory §2.8: the two template date layouts differ (`2006. 01. 02. 15:04` Hungarian vs `2006-01-02 15:04` ISO); 10 layout literals in `internal/web` Go and 25 elsewhere pick formats ad hoc; sizes print a decimal POINT (`%.1f GB`, 4 helpers) where Hungarian uses a comma; `timeAgo`/`nextRunLabel`/`pruneLabel` produce Hungarian words outside the three converted pages. Not changed by v0.247.0 (Hungarian bytes are frozen by the parity rule). **Fix shape:** one date and one size formatter per language in `internal/i18n`, the Hungarian output deliberately changed in ONE reviewed release with the parity fixtures re-captured for that release only and the change named in its CHANGELOG. Needs an operator word on the Hungarian format (comma, date style). | **READY - rank P3-LOW; owner: CC** |
| **R-564** | **[P3-LOW] The retrieval-promise gate's Hungarian stems cannot see a SPLIT verb — „csak akkor állíthatók vissza", „hozod vissza" — so those Hungarian sentences were never scanned; the English translation exposed them.** FOUND 2026-09-17 by slice 1 release B (R-556): after the gate learnt English (`EN_PATTERNS`), seven English retrieval phrases on `backups_remote`, `backups_escrow`, `backups_restore` and `backups_restore_wizard` had NO Hungarian registration, because their Hungarian carries the verb particle after the verb („A távoli mentések csak akkor állíthatók vissza …", „a távoli mentések CSAK ezzel a kóddal állíthatók vissza", „csak a hiányzó fájlokat hozod vissza"). The stems (`visszaállíthat`, `visszaszerezhet`, `visszahozhat`, `visszanyit`) match only the joined form. The seven were registered in English with reasons (none is a false promise: two are preconditions, five describe the action on the same page). **Fix shape:** add split-form patterns to the Hungarian scan (`állíthatók? vissza`, `(hoz|szerez|nyit)\w* vissza`), register the Hungarian occurrences found, decoy with a planted split-verb promise. | **READY - rank P3-LOW; owner: CC** |
@@ -768,6 +768,8 @@ class (an image `VOLUME` at an unmounted path) is still live — `immich-server`
| **R-590** | **[P3-LOW] The data-folder card tells an English household, in Hungarian, whether its files are backed up.** FOUND 2026-09-20 live on demo-hp (0.257.0), same pass as R-589: `/apps/paperless-ngx?lang=en` renders „Ide másold a feldolgozandó fájlokat. Az alkalmazás beolvassa, majd törli innen — ez a mappa átmeneti, és nem készül róla biztonsági mentés." and `/apps/romm?lang=en` renders „Itt tárolódnak a fájljaid. Biztonsági mentés készül róla." `controller/internal/web/datapath_card.go` `consequenceFor` (L33-48) returns four raw Hungarian literals chosen by BACKUP CLASS. The R-75 `label` beside them IS translated now (it is catalog copy), so the English page reads „Documents to read in" followed by a Hungarian sentence — the mixed line is worse than either language whole. **This one carries a promise about the customer's files**, which is why it ranks with R-589 rather than below it: the sentence exists to say a folder is temporary and unbacked, and a household that cannot read it may leave originals in a drop-zone the backup filter drops at every tier. **Fix shape:** four keys, class-keyed exactly as now (the comment's whole point is that the promise is class-driven and never per-app), plus a render test per class in both languages. | **READY - rank P3-LOW; owner: CC (controller)** |
| **R-591** | **[P3-LOW] `Stack.Copy()` is a deep copy with one shallow field, and the field is new.** FOUND 2026-09-20 while adding the catalog's English overlay: `controller/internal/stacks/manager.go` `Copy()` deep-copies `Meta.DeployFields` (with nested `Options`), `Meta.OptionalConfig` (with nested `Fields`), `Meta.Integrations`, `Meta.HealthCheck` and `Meta.InitialCreds` — and does NOT copy the new `Meta.I18n` map, which the struct assignment leaves shared between the original and the "copy". **It is safe TODAY and that is exactly the shape worth filing:** `Metadata.For` reads the overlay and never writes to it (pinned by `TestForDoesNotMutateTheReceiver`), so nothing can observe the sharing yet. The hole is in the CONTRACT — a function whose whole purpose is "a snapshot the caller may mutate" now has a field that is not one, and the next person to write through an overlay will find a bug with no failing test in front of it. **Fix shape:** deep-copy `I18n` in `Copy()` and pin it with a test that mutates the copy's overlay and asserts the original is unchanged. Alternatively state in `Copy()`'s comment that `I18n` is deliberately shared and immutable, and pin THAT with a test. Either is fine; silence is not. | **READY - rank P3-LOW; owner: CC (controller)** |
| **R-592** | **[P3-LOW] Two defects in the new catalog copy gate, each found by its own decoy rather than by reading it.** FOUND AND FIXED 2026-09-20 building `app-catalog-felhom.eu/scripts/check-copy-i18n.py` (R-560 slice 5). (1) **Coverage was counted only for the apps NAMED on the command line**, so `check-copy-i18n.py privatebin` reported 47 more untranslated strings than the same tree unscoped — a ratchet anybody could loosen by naming one app, and either number could have been made to "pass". (2) **The credential check searched for its token as a bare substring**, so a `default_creds` of „admin / adminadmin" translated to "administrator / hunter2" PASSED: "admin" is inside "administrator". (3) **The ASCII-Hungarian stems matched as bare substrings too**, so „ird be" convicted "the third best" and „angol" convicted "Angola". All three now have their own case in `scripts/test_gate_decoys.py` (33 cases, every one seen to convict or pass as intended). **Recorded rather than left in a commit message** because the general form is worth the row: every one of the three was a check that matched a LABEL where the FACT was a word, a login or a whole catalog — the R-421 shapes, inside the gate written to enforce R-421. | **CLOSED 2026-09-20 — fixed in the same session, decoys added** |
+| **R-593** | **[P3-LOW] papra's session-signing key is described as „the app's subdomain".** FOUND 2026-09-20 translating the catalog (R-560 slice 5, batch 1). `templates/papra/.felhom.yml` `deploy_fields[AUTH_SECRET].description` reads **„Az alkalmazás aldomainje"** — the sentence that belongs on `SUBDOMAIN`, on a field that signs sessions. `SUBDOMAIN` itself has NO description at all in that file, so this is a copy-paste that landed one field too low and took the original with it. A customer opening papra's install page reads a wrong explanation under a key they must not regenerate. **A localisation release may not change Hungarian bytes (10 §1)**, so it was not fixed there; and translating a wrong sentence faithfully would have shipped the error in a second language, so **that one field was left untranslated** — it falls back to the Hungarian exactly as today, and it is the ONE string keeping papra at 13/14 and the catalog ceiling off zero. **Fix shape:** move the sentence to `SUBDOMAIN` and give `AUTH_SECRET` its own („A munkamenetek aláírásához használt kulcs" or similar), re-capture that app's two entries in `scripts/copy_freeze/hu.json` in the same commit with the reason, then add the English. Owned by R-516 as a Hungarian-words change. | **READY - rank P3-LOW; owner: CC (catalog)** |
+| **R-594** | **[P3-LOW] The catalog copy gate can CONVICT a retrieval promise but has no way to REGISTER a true one.** FOUND 2026-09-20 translating batch 3 (R-560 slice 5). Vaultwarden's invite step and its sign-up setting both ended „…can open an account", and the English retrieval-promise pattern reads `can … open` as the claim that sealed backups can be opened. **The conviction was a FALSE POSITIVE** — opening an account is not opening a backup — and the two sentences were reworded to „can sign up", which is also the better copy, so nothing is blocked today. **The gap is structural.** The shared vocabulary this gate copies (`scripts/customer_copy_vocab.py`) states the design explicitly: these stems are NOT banned, because each carries a claim that is sometimes TRUE, and *"an occurrence must be REGISTERED with a reason in the consuming gate's allowlist"*. The hub gate has `ALLOWLIST_EN`; `app-catalog-felhom.eu/scripts/check-copy-i18n.py` has none, so the only ways past it are to reword or to bypass the gate — and a catalog app whose English genuinely says a file can be restored (a backup app, a versioned document store) has no honest third option. **Fix shape:** an `ALLOWLIST_EN` of `(app, path, reason)` in the gate, a decoy proving a REGISTERED occurrence passes and an unregistered one still convicts, and a check that every entry still matches something (a stale allowlist entry was R-299's shape, and the retrieval gate has gone red on stale entries before). | **READY - rank P3-LOW; owner: CC (catalog)** |
| **R-537** | **[P1-HIGH] The app-backup page labels the tier-1 backup „DB + Konfig + Adatok" and prints the app's data-drive size next to it — but the tier-1 unit contains NO drive-side app data at all.** MEASURED 2026-09-16 on the drill box (fresh install, controller 0.243.0, one drive, tier 2 and tier 3 both „Nincs beállítva"): five photos (3 000 000 B) were uploaded into Nextcloud through its own WebDAV interface, then the customer-visible „Mentés most" was pressed (`POST /api/backup/run` → 200, the unit grew 25 337 B → 978 MB). The resulting unit's `manifest.json` lists `db-dumps` + three **docker volume** dumps and nothing else; listing the 781 MB `nextcloud_nextcloud_html.tar` (29 346 entries, positive control `version.php` = 3 hits) gives **`Fotok` = 0 and `nyaralas` = 0**, and `./data/` is the empty bind-mount point. A `find` over the whole `backups/` tree for `*appdata*` / `*Fotok*` returns nothing. The page nevertheless renders „1. mentés … DB + Konfig + Adatok" and „Nextcloud Adatlemez 65.1 MB" — a size measured on exactly the data it does not copy (`internal/web/handlers.go:1176-1178`, `BackupContents`). **This is a truth defect, not a design defect:** `07-backup-architecture.md` §6.2 places nextcloud's file leg at **Tier 2 and Tier 3 only**, and its „[FACT] What the whole-guest tiers do NOT carry" says `mp8 /mnt/felhom-drives` is out of vzdump scope (confirmed live: „excluding bind mount point mp8 … (not a volume)"). So on a one-drive box with no off-site tier — the state every fresh install starts in — the household's files are in **no backup**, while the page says „Adatok". Same family as R-517/R-518. **Fix shape:** render tier-1 contents from the capture set actually written (`ComputeCaptureSet`), so a unit with no file leg reads „DB + Konfig" and the drive size is not shown beside it; and say on the page that the app's files need tier 2 or tier 3. Evidence: `audits/evidence-drill-0243-2026-09-16/phase2-f10.txt`. **CLOSED 2026-09-16 — controller v0.244.0, proven live.** The contents label is computed PER TIER from what that tier captures: Tier 1 says „Adatok" only when the app's data really is in the volumes the unit captured, and a class-A app carries one sentence saying where its files ARE protected. Proven on demo-hp through the page the customer opens: Paperless-ngx reads „1. mentés … DB + Konfig" with „Az alkalmazás fájljait a távoli másolat (és a második meghajtó) védi …", while its „2. mentés" row still reads „DB + Konfig + Adatok". Red-proof: restoring the old app-shaped label fails `TestAppBackupRows_Tier1LabelDoesNotClaimFilesItCannotHold`. **RE-PROVEN 2026-09-16 on a FRESH box** (installed from the built ISO 1.28.0, controller 0.244.0, off-site on by default): the Nextcloud row read „1. mentés … DB + Konfig" with the new sentence, „2. mentés … Nincs 2. (off-drive) másolat", „3. mentés Sikeres restic → …your-storagebox.de"; „DB + Konfig + Adatok" appeared ZERO times while the local unit held no file leg. | **CLOSED 2026-09-16 — controller v0.244.0 (proven live on demo-hp)** |
| **R-538** | **[P1-HIGH] A tier-1 app restore reports plain success and leaves Nextcloud listing files whose bytes were never in the backup — and it destroys the app's own trash, the customer's last copy.** MEASURED 2026-09-16 on the drill box, F10 („a child deletes the photo folder"): the five photos were deleted through Nextcloud (DELETE 204, PROPFIND 404), then restored through the page exactly as a customer would (`POST /backup/restore` `stack_name=nextcloud` `snapshot_id=helyi` → 302, finished in **35 s**, „A(z) nextcloud: 3 adatkötet és az adatbázis visszaállítva — az alkalmazás újraindult."). Afterwards the folder is back and **lists all five photos**, and **none of them opens**: `GET nyaralas-1..5` = 404 / 503×4 with `Sabre\DAV\Exception\NotFound`, while the positive controls at the same moment pass (`status.php` 200, WebDAV PUT 201, GET 200). Cause: the replayed MariaDB dump (11:01:45Z) knows the photos, the bytes live on `mp8` and were never captured (R-537). **Worse:** the bytes were still on the drive in Nextcloud's own trash (`appdata/nextcloud/admin/files_trashbin/files/Fotok.d1789556707/nyaralas-1..5.jpg`, all five present) and the restored database no longer references them — the trash listing comes back **empty**, so „restore from trash", the one route that would have worked, is gone. The customer is left with five unopenable photos, a success message, and no warning. **Fix shape:** before replaying a database whose app has an uncaptured file leg, refuse or warn („ennek az alkalmazásnak a fájljai nincsenek ebben a mentésben — a visszaállítás után a fájlok hiányozni fognak"); and never present a DB-only restore of a class-A app as a complete one. Evidence: `audits/evidence-drill-0243-2026-09-16/phase2-f10.txt`. **CLOSED 2026-09-16 — controller v0.244.0, proven live.** A unit restore refuses before anything is touched when the unit cannot return the app's drive-side files, and names the route that can. Fired live on demo-hp: `POST /backup/restore` for paperless-ngx → 302 with „Ez a mentés nem tartalmazza az alkalmazás fájljait, ezért nem állítjuk vissza az adatbázist föléjük — a fájlok így a helyükön maradnak. A fájlok a távoli másolatból állíthatók vissza …", and the app read `running` before AND after, so nothing was stopped and no trash was made unreachable. The database-and-settings-only path exists as a separately worded second step. Red-proof: disabling the guard fails `TestUnitRestore_RefusesWhenTheUnitCannotHoldTheFiles`. **RE-PROVEN 2026-09-16 on a FRESH box, and this time the refusal had somewhere to point:** after five photos were deleted, `POST /backup/restore` was refused with „…a fájlok így a helyükön maradnak. A fájlok a távoli másolatból állíthatók vissza: … „Teljes visszaállítás (fájlok + adatbázis)"", the app read `running` before AND after, and the wastebasket was untouched. The off-site route then returned all five photos — 200 with the exact uploaded sizes and sha256 IDENTICAL to the originals, 5/5, with a negative control. Evidence: `audits/evidence-backup-promise-2026-09-16/phaseE-photos.txt`. | **CLOSED 2026-09-16 — controller v0.244.0 (proven live on demo-hp)** |
| **R-525** | **[P3-LOW] FileBrowser has its own login; putting it behind the dashboard session (traefik forwardAuth or Quantum proxy auth) is a new mechanism nobody has measured.** Filed 2026-09-15 by the P1-fixes task (B.5). R-513 closed the default-password hole with a generated password; a household still has two logins. **What it needs:** a spike on a scratch guest — forwardAuth to the controller session, and what FileBrowser Quantum does with a trusted header. | **READY — rank P3-LOW; owner: CC (spike)** |