From d9aa02a93f127c0dbc49b858f82ff869ea6ba275 Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Sun, 20 Sep 2026 14:44:02 +0200 Subject: [PATCH] REPORT: the pilot's English quoted in full for the operator's read (R-560) The three apps' English text, the per-app table, the unverified UI labels for the slice-6 walk, the gate's five checks and the three defects its own decoys found in it, and the live proof on both demo boxes. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS --- REPORT.md | 221 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 196 insertions(+), 25 deletions(-) diff --git a/REPORT.md b/REPORT.md index 3b01304..2f94ba4 100644 --- a/REPORT.md +++ b/REPORT.md @@ -1,32 +1,203 @@ -# REPORT — vaultwarden closed by default, paperless-ngx sized for a batch (2026-09-15) +# REPORT — localisation slice 5, Part B: the copy freeze, the gate, and the English pilot (R-560) -Task: *before the volunteer — the big night's P1 fixes*, Part E. No image or version change. +2026-09-20 · catalog `main` `e81d41e` · needs controller **v0.257.0** to render · Part C not started. -## What changed -- **vaultwarden (R-512):** `SIGNUPS_ALLOWED` defaults to `false`; the select explains both choices; „Első lépések" is - invite-first (admin panel with the generated token → invite → create account); the compose header no longer tells - anyone to change a setting after install. -- **paperless-ngx (R-514, R-515):** `PAPERLESS_TASK_WORKERS=1`, `THREADS_PER_WORKER=1`, webserver `memory: 1280M` - (`mem_limit` hint 1664M); `default_creds: admin / admin` removed; first steps point at the generated password. +--- -## Measured first -- **E.1 spike** (throwaway container on scratch 9202, SMTP off as on a box without app-email): stranger register **400**, - admin invite **200**, invited register **200**, second stranger **400**. So invite-first needs no controller change. -- **E.2** (1 worker × 1 thread, no cap): 20 three-page PDFs → **20/20**, `memory.peak` 783 294 464 B → cap = peak × 1.5 - rounded up to 256M = **1280M**. Caveat: the PDFs carried text, so OCR on scanned images may need more. +## For the operator — the one thing you have to do -## Proven live after the change (scratch 9202, deployed from the catalog through the controller API) -- Vaultwarden: container `SIGNUPS_ALLOWED=false`; stranger `send-verification-email` via traefik → **400 „Registration - not allowed or user already exists"**; the app page shows the invite steps (fragment 1, negative control 0). - *One invalid attempt first: a hand-built register body got 422 (did not parse) — marked invalid in the evidence.* -- Paperless: 20 PDFs posted at once → tasks **20 SUCCESS**, documents **20**, limit 1 342 177 280 B, `memory.peak` - **772 370 432 B**, OOMKilled false, 0 kernel OOM lines. -- Forcing an OOM (cap 128M) showed Docker reports nothing in an LXC guest (R-528, a controller/agent row). **Mistake, - stated:** restoring the cap on the throwaway with a broad `sed` also changed its redis cap; moot, the stack was removed. +**Read the English below (it is short) and say "go", or say what to change.** Fifty more apps follow +whatever you say. Ten minutes now against a day of rework later. Everything else in this report is +for the record. + +--- + +## The three pilot apps, in full, for your read + +### PrivateBin + +> **What it is:** Encrypted note and text sharing +> **Tagline:** Encrypted text sharing - the server never sees the content + +**What it is for** +- Share sensitive text safely +- End-to-end encryption - the server cannot reach the content +- You choose how long it lasts (5 minutes to 1 year, or never) +- Optional: delete it automatically after it is read +- Password protection for extra safety + +**First steps** +1. Open paste.DOMAIN in your browser +2. Type your text and select Send +3. Share the link you get - the encryption key is part of the URL + +**Install settings:** Domain — "The server domain name" · Subdomain — "The subdomain this app +answers on" + +### Paperless-ngx + +> **What it is:** Digitise your documents and keep them in order +> **Tagline:** A digital filing cabinet - scanning, OCR and automatic sorting + +**What it is for** +- Turn paper documents into files and keep them in order +- Automatic OCR text recognition on scanned documents +- Smart automatic sorting and tagging +- Full text search across every document +- Documents that arrive by e-mail are processed automatically + +**First steps** +1. Open paperless.DOMAIN in your browser +2. Sign in: user "admin". The password is on the Settings page, under Automatically generated values +3. Upload a document in the app, OR drop it into the import/paperless folder in the File manager + (FileBrowser) - it is read in and processed with OCR from there. The File manager sign-in is on + the File manager app page +4. You can upload many documents at once: they are processed one by one, and a larger batch takes a + few minutes +5. Create tags and correspondents so new documents sort themselves + +**Before you start** +- An external hard drive is recommended to keep the documents on +- At least 1 GB of free RAM (for the OCR work) + +**Install settings:** Database password · Encryption key · Admin user name · Admin password ("For +the first sign-in. You can change it in the app afterwards.") · Data storage path ("The path to the +external hard drive where the documents are kept") · OCR language (Hungarian / English / Hungarian + +English / German + English — "The language the text recognition reads") · Folder label: "Documents +to read in" + +### RomM + +> **What it is:** Retro game collection manager +> **Tagline:** Retro game collection manager, browser and player + +**What it is for** +- Sort and browse a retro game collection in your browser +- Game details download themselves - cover art, descriptions, ratings +- Filter and search the whole collection by platform +- Upload and download ROM files in your browser +- Several people in the household can have their own account + +**First steps** +1. Open arcade.DOMAIN in your browser +2. Sign in with the default admin / admin account +3. Change the password straight away, in the Settings menu +4. Upload the ROM files into the roms/ folder in the File manager (FileBrowser), sorted into + platform folders (for example roms/gba/, roms/snes/) +5. Start a Scan from the menu on the left to read the ROMs in +6. Optional: set up metadata providers so cover art and descriptions download themselves (see below) + +**Before you start** +- An external hard drive is needed to keep the ROM files and cover art on +- At least 1 GB of free RAM is recommended (MariaDB + Redis + RomM) +- ROM files sorted into platform folders (for example roms/gba/, roms/snes/) + +**Optional settings — "Metadata providers":** "So that cover art, descriptions and ratings download +themselves. IGDB is the one worth setting up first. All of them are free after you sign up." · six +key fields with their own sign-up instructions · Folder label: "ROM collection" + +--- + +## Per-app table + +| app | copy strings | English | list-length exceptions | push | live-checked | +|---|---|---|---|---|---| +| privatebin | 14 | 14 | none | pilot | **yes** — app page, Apps list | +| paperless-ngx | 33 | 33 | none | pilot | **yes** — app page, deploy page, Apps list | +| romm | 42 | 42 | none | pilot | **yes** — app page, deploy page, Apps list | +| the other 50 | 943 | 0 | — | — | — | +| **total** | **1 032** | **89** | **none** | | | + +No app needed a list-length exception: every English list has exactly as many entries as its +Hungarian twin, which is what the gate requires unless the file carries a stated reason. + +## Unverified UI labels — for the slice-6 walk (R-561) + +These English lines name a button or a menu in the app's OWN interface. No gate and no endpoint can +tell whether the app actually shows that word in English; somebody has to open it. + +| app | the line | what has to be checked | +|---|---|---| +| privatebin | "Type your text and select **Send**" | PrivateBin's send button's English label | +| paperless-ngx | "under **Automatically generated values**" | this is Felhom's own Settings page — taken from the controller's English bundle, so it is right by construction unless that bundle changes | +| paperless-ngx | "Create **tags and correspondents**" | Paperless's English words for these two | +| romm | "Change the password straight away, in the **Settings** menu" | RomM's English menu label | +| romm | "Start a **Scan** from the menu on the left" | RomM's English button label | + +## What changed in this repo + +**Three commits, in this order, and the order is the point.** + +1. `0c19b45` — **the freeze alone.** `scripts/copy_freeze/hu.json`: every customer-facing Hungarian + string in the catalog, 1 032 of them across 53 apps, captured from the commit before any + translation existed. Its own commit so that a baseline cannot be said to have arrived with the + checker that reads it. +2. `84e0584` — **the gate.** `scripts/check-copy-i18n.py`, fifth row of `catalog_gates.py`, static + and in the pre-push hook: the Hungarian freeze, the English block's structure, its language, its + credential tokens, and a coverage ratchet. 18 new decoy cases. +3. `e81d41e` — **the pilot.** Three apps, 89 strings, `EN_MISSING_CEILING` 1032 → 943. + +**No image, no pin, no `catalog_since`, no compose line changed.** A translation is not a version +bump of an app. + +## What the gate checks, and what it cannot + +| # | check | convicts on | +|---|---|---| +| 1 | FREEZE | any Hungarian copy string that differs from the freeze, is new, or has gone. Runs on all 53 apps whatever scope is named — a scoped push that quietly edits a neighbour is what a freeze is for. A new app must be admitted with `--add-app NAME --reason "…"` | +| 2 | STRUCTURE | a key the English block may not carry; an `env_var`, option `value`, `match_group`, `target` or `path` with no Hungarian twin (it would be INERT on the box and the translator would never learn); a list whose length differs from the Hungarian | +| 3 | LANGUAGE | an accented Hungarian letter; **ASCII-only Hungarian**; "please"/"kindly"; an English retrieval promise the Hungarian does not make; a dropped app name or „Felhom" | +| 4 | CREDENTIALS | a login token inside `default_creds` or an initial-credentials note that did not survive translation, matched on WORD boundaries | +| 5 | RATCHET | a coverage count above **or** below `EN_MISSING_CEILING`, counted over the whole catalog whatever scope is named | + +**It cannot judge whether the English says what the Hungarian says**, and it cannot judge whether an +app's first steps match that app's real screens. The first is your read above; the second is the +table before it. + +## Numbers that were wrong in the plan, corrected by measurement + +| | the plan said | measured on `94bc5febaca2` | +|---|---|---| +| copy strings | 835 | **1 032** (it omitted 13 `placeholder` values, and every ASCII-only label) | +| with a Hungarian letter | 832 | **832** ✔ | +| ASCII-only Hungarian | three — „Igen", „Nem", „Nincs" | **~120**, and those three do not occur in this catalog at all | + +The last row decides an instrument rather than a footnote. „Aldomain" appears 53 times and „A szerver +domain neve" 53 times; both are Hungarian with no accent in them. **A gate that scans for accents +passes every one of them inside an English block.** So check 3 folds the text and matches word-bounded +stems, and prints a positive and two negative controls on every run. + +## Three defects in the gate, each found by a decoy rather than by reading it (R-592) + +1. **Coverage was counted only for the apps named on the command line.** `check-copy-i18n.py + privatebin` reported 47 more untranslated strings than the same tree unscoped — a ratchet anybody + could loosen by naming one app. +2. **The credential check matched its token as a bare substring**, so „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. 33 decoy cases in total, every one seen to convict or to pass as +intended. + +## Live proof + +Endpoint-level, from inside the guest, with the customer `Host` header and a real session — the same +handlers and templates the browser drives, only the drawing skipped. Said plainly because "the page +shows X" has to name how it was seen. + +- **demo-hp (controller 0.257.0):** the three English app pages, the Apps list and two deploy pages + show the English catalog text. The seven **Hungarian** pages are byte-identical before and after the + push apart from the per-session CSRF token. +- **demo-felhom (controller 0.255.0, deliberately old):** with the pilot synced onto the box — + confirmed positively, the sync named the three apps and the block is present in both the cache and + the stack copy — its pages hash identically before and after and its log carries no parse warning, + in a 93-line window that includes the sync's own lines. + +Evidence: `felhom.eu/documentation/audits/i18n-slice5-2026-09-20/`. ## Teardown -Machine: scratch 9202's throwaway `paperless-ngx` and `vaultwarden` stopped and removed (volumes removed; the paperless -data folder on the scratch drive kept, the product default). Host: nothing. Hub: nothing (9202 reports to no hub). -## Gates -`catalog_gates.py --fast` OK on every push. Evidence: `felhom.eu/documentation/audits/evidence-p1fixes-2026-09-15/E1-*`, `E2-*`, `teardown-9202.txt`. +Nothing installed, nothing removed, no app deployed. Three template files changed on each demo box, +which is what a catalog sync does. The staged password file and the capture scripts were shredded from +both Proxmox hosts and both guests. Both boxes left on Hungarian.