diff --git a/CONTEXT.md b/CONTEXT.md index 3cb89221..c4aa470d 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -16,6 +16,18 @@ > and holds nothing of its own; this file does hold its own content, namely the standing rulings below. +> **2026-10-22 morning — the operator's five yeses, carried out.** Controller **0.338.0** released (image +> `sha256:e8a529f3…`, MinAgent 0.158.1): Tester 1, demo-hp, demo-felhom through per-customer floors, checks green +> (https-only 28/28, 0 unhealthy, 0 errors), then the global floor 0.338.0 (read back with the WAL). Agent **0.162.0** +> released (`5fd7a23b…` = the soak's bytes) and delivered by signed job to the same three; **the vouch is the +> operator's**. Hub **0.164.0** deployed (only `Deployment/hub` synced). ISO **1.30.0** (W1, W7) built, gated (G1–G16, +> G12 not re-read) and proof-installed from both menu entries on demo-hp, published, round trip `590d7b9b…`; both +> download pages point at it and carry the W2 button. Operator answer: Tester 2's laptop was installed with our +> installer (R-1207). **Found:** the host-swap check (agent WARN, hub `host_swap_short`, the controller's install +> sentence) compares host swap with the guests' WHOLE swap allowance, so every box with a guest above ~8 GB trips it +> (demo-hp, demo-felhom mailed) though the soak burst used 2.7 GB — R-1216, decision D28. The runbook's G16 command +> was stale (now `scripts/iso_bootstrap_gate.py`). Record: `REPORT-morning-2026-10-22.md`. + > **2026-10-21 night (unattended; nothing released, deployed, published or vouched).** Operator rulings recorded: > **D22 = yes (20:05)** — D20's put-back extended to the local unit restore, the second-drive restores and a restore cut by > a power loss (`07` §6.3, the 2026-10-21 `[DESIGN]` paragraph; controller `d582feb`, proven on 9202 with 0.338.0-rc.1: diff --git a/REPORT-morning-2026-10-22.md b/REPORT-morning-2026-10-22.md new file mode 100644 index 00000000..fc5a5a24 --- /dev/null +++ b/REPORT-morning-2026-10-22.md @@ -0,0 +1,61 @@ +# REPORT — the morning of 2026-10-22: the operator's five yeses + +**Operator answers:** release controller 0.338.0 — yes; release and vouch agent 0.162.0 — yes; deploy hub 0.164.0 — yes +(Tester4 host deleted); Tester 2's laptop — installed with our installer; publish items — yes, all. Design read: +`07` §6.3 (restore put-back), `03` §9 (guest sizing), the felhom-build-deploy runbooks, `runbooks/iso-release-gate.md`. + +## Decisions taken by CC + +None new. The night's R-1199 decision (a box with no saved notification choice pushes its page's default list) now +ships in controller 0.338.0 — *operator may reverse*. + +## What was done + +| | what | result | +|---|---|---| +| agent | `release-agent.sh 0.162.0` from a clean clone at `b310773` | sha256 `5fd7a23bfe319cb521c4bc399612d5fb3413f1e695f79bc663c386f69c757928` (= the soak's bytes), bundle `ac772967…60b5a5`, tag `v0.162.0`, round trip OK | +| agent | one signed `agent_update` per box: demo-hp, Tester 1, demo-felhom (07:41 UTC) | all three `update committed`, `ok=76 total=76`, `guest-swap: raised` for 9201 (512 MB → RAM); `pct config` swap = memory on all three | +| hub | manifest `0.163.0 → 0.164.0` (`0b7a5ab3`), only `Deployment/hub` synced | running `sha256:931594e3…` (= the night's build), log `felhom-hub 0.164.0 starting` | +| controller | `build.sh 0.338.0 --push` from `7900a32` | `sha256:e8a529f395bfe8c0e7b87d5d98929a6f8e9834aa13c0ab77bd214ee9e7e53433` | +| controller | per-customer floors (tester-1, demo-hp, demo-felhom), MinAgent 0.158.1 | all three on 0.338.0 within 10 s (agent `controller-swap: new controller healthy`); https-only 28/28 + control; 10/24/9 containers, 0 unhealthy, 0 restarting; 0 `level=ERROR` | +| controller | global floor 0.338.0 / MinAgent 0.158.1 with CC's hub token | `303 → flash=floor_set`; hub DB (with WAL): `min_controller_version=0.338.0`, `0.338.0=0.158.1`; the three per-customer floors cleared | +| website | the W2 patch (`6b391a63`), site gates OK | live on felhom.eu/letoltes.html and /en/download | +| ISO | 1.30.0 `--release` from `115f15c8` | `590d7b9b3ccbc7644536a1971a44deb2d1bf7136f69eae2b4dc42961e74d5cc1`, 1 705 324 544 B; gate G1–G16 PASS (G12 not re-read); proof installs from BOTH entries (VMs 9341, 9342), first boot + one reboot; W1 seen on screen; published, round trip identical; both download pages point at 1.30.0 | + +Evidence: `documentation/audits/morning-2026-10-22/release/`, `documentation/tests/iso-release-1.30.0-2026-10-22/`. + +## What broke + +- **The host-swap check is too strict (R-1216, D28).** Within minutes of agent 0.162.0 demo-hp (host swap 8191 MB vs + guests 25898 MB) and demo-felhom (8191 vs 12288) warned and the hub mailed `host_swap_short`. The check compares host + swap with the guests' whole swap allowance; the installer gives at most 8 GB, the soak's burst used 2.7 GB. The same + comparison drives the controller's install-page sentence. Not fixed: the threshold is the operator's pick. +- **A stale runbook command (fixed).** `iso-release-gate.md` G16 mounted `scripts/iso` as `/work`; the harness needs + `golden/` and `postinst` staged, so 10 checks failed on a correct tree. Now names `scripts/iso_bootstrap_gate.py` + (73 checks green). My first run with the old line left harness scratch files in `scripts/iso/` (root-owned); removed + by name before any commit. + +## Rows + +Before 184, after 178. Opened 1 (R-1216). Closed 7: R-1192, R-1177, R-1178, R-1180, R-1195, R-1199, R-1210. Updated: +R-1194 (released; WATCHING for the next fresh install; owner CC), R-1207 (Tester 2 = our installer). Section headers +recounted (Backup & restore read 44, held 42). + +## Waiting on the operator + +1. **Vouch agent 0.162.0** (Configs → Day-0 artifacts). If not: new installs get 0.161.0, without the swap fix. +2. **Discard appliances 47 and 48** (the proof installs). If not: two „unclaimed" rows stay. +3. **D28** — loosen the host-swap check (A, CC's pick) or keep it (B). +4. **Tester 2** is off; when it is back, CC sends it agent 0.162.0. +5. The secret names `REHEARSAL_2026_10_20_*`, `FIXES_2026_10_21_*`, `NIGHT_2026_10_21_*` are KEPT (the proof installs + used the night's root password); say „remove" to drop them. + +## Teardown + +- **Machine:** VMs 9341, 9342 destroyed (names checked); ISO 1.30.0 kept in demo-hp `local:iso`. No thin-pool write. +- **Host:** demo-hp, Tester 1, demo-felhom now on agent 0.162.0 and controller 0.338.0 — intended, not torn down. +- **Hub:** appliances 47, 48 for the operator to discard; floors: global 0.338.0, no per-customer floor left. + +## Instruction files / poster + +No instruction file changed. No system-poster fact changed (versions are not poster facts). diff --git a/STATUS.md b/STATUS.md index 5e5ec88d..8c053d8a 100644 --- a/STATUS.md +++ b/STATUS.md @@ -1,8 +1,8 @@ # STATUS — what works, what's broken, what's next -**Ready for the first real tester (Tester 2)? No — three morning yeses left:** release the controller (restore put-back, first-hour words), release and vouch the agent (the swap fix — the night soak says yes), deploy the hub. Tester 2 is off; nothing was sent to it. +**Ready for the first real tester (Tester 2)? Nearly — one click left:** vouch agent 0.162.0 (Configs → Day-0 artifacts), so new boxes install it. Tester 2 is off; nothing was sent to it. -**Updated 2026-10-22 (morning, after the night run).** A failed or cut restore now puts the data back and starts the app (proven on the scratch box); clearer first-hour texts; a host short of swap is reported. Built and tested, nothing released. +**Updated 2026-10-22 (morning, your yeses).** Released: controller 0.338.0 (global floor), agent 0.162.0 (on the 3 test boxes), hub 0.164.0, installer 1.30.0 and the website download button. The new host-swap check warns on boxes bigger than 8 GB; that is too strict (decide D28). ## What works - A box installs from nothing with the public installer, links to the hub, and moves to the floor by itself (map A1, A3, A4). @@ -15,7 +15,6 @@ - The hub mails alarms and recoveries, and keeps one whole-box copy per week on ep0; CC uses its own limited token, not your password (map F1, F11, G15). ## What is broken -- **P1:** the 8 GB box can freeze for minutes under big uploads until the agent with the swap fix is released (R-1192; the night soak says the fix works — morning list item 2). - **P1:** about 12 homelab logins still use a password that was public, and the public Gitea repo is not decided (R-925, yours). - Two root-level weaknesses wait on your decisions D3 and D4 (R-985, R-982). - Tester 2 is off since 2026-10-04: old emergency password, no off-site check, no bootstrap (R-1139, R-1104, R-862). @@ -31,13 +30,14 @@ Newest first. CC's pick is in the „Pick" column. Each row also has its full te | # | Row | Question | Pick (why) | The other option costs | If you do nothing | Blocked | |---|---|---|---|---|---|---| -| D27 | R-1207 | A host with no swap gets nothing from the swap fix, and the agent never adds swap. Add host swap automatically (BYO too), or refuse an 8 GB host without swap at install? | **Report only for now** (our installer gives 7.75 GB; the alarm and the install-page sentence now tell you) — decide after the first BYO box | Add it: the agent changes a disk its owner set up; refuse: a BYO household cannot start | a no-swap host can still freeze; you get the alarm | — | +| D28 | R-1216 | The host-swap check warns when host swap is below the guests' whole swap. A 16 GB box with the installer's 8 GB swap trips it, but the soak used 2.7 GB. Loosen it to „below what the installer gives"? | **Loosen it (A)** (no mail for a healthy box; 938 MB still warns) | Keep (B): you get a mail per big box, and the install page tells such a household to call us | demo-hp and demo-felhom stay flagged; one mail each, already sent | — | +| D27 | R-1207 | A host with no swap gets nothing from the swap fix, and the agent never adds swap. Add host swap automatically (BYO too), or refuse an 8 GB host without swap at install? | **Report only for now** (our installer gives 7.75 GB, and Tester 2's laptop used our installer; the alarm and the install-page sentence now tell you) — decide after the first BYO box | Add it: the agent changes a disk its owner set up; refuse: a BYO household cannot start | a no-swap host can still freeze; you get the alarm | — | | D21 | R-49 | Immich's off-site copy: leave out only the AI model files now (B), or also the raw database folder and Immich's own backups (A)? | **B now** (−62 %, no new risk); A's other parts after their proof | A: −92 %, but it needs a restore path we have never run | every Immich box sends about 12 times its real data off-site each night | — | | D9 | R-1062 | Split the N100's USB drive in two, for multi-drive tests? | **No — keep one drive** (the lived-in box keeps its nightly whole-box backup) | Split: the box loses its local whole-box backup, or you buy a second drive first | it stays one drive; multi-drive tests stay on Tester 1 | — | | D8 | R-206 | Install DooPlex's Docker settings from git (Docker restarts once), with a weekly build-cache prune? | **Yes, in a quiet window** (a rebuilt DooPlex then keeps the settings) | No: the live settings stay hand-made, and a rebuild loses them | git and the host can drift apart | — | | D7 | R-990, R-989 | Rule on the forum ideas and the selfh.st ideas now, or park them? | **Park them** (P4; nothing waits on them) | Rule now: about one hour of reading | nothing changes; the research gets old | — | | D6 | R-992 | The scratch box cannot read the private drill catalog: give it a read-only login, or make that copy public? | **A read-only login** (the drill catalog stays private) | Public copy: anyone can read the drill catalog | every new-app test needs staging by hand | new-app tests | -| D5 | R-991 | Approve the minimum machine: x86-64, 4 cores, 8 GB RAM, 256 GB SSD (recommended: 16 GB, 512 GB)? | **Approve** (measured on the N100 with 61 apps) — **but wait for R-1192**: an 8 GB box froze on its first afternoon, 2026-10-20 | Change it: one edit | no hardware page; a buyer with a Raspberry Pi can still download the installer | the hardware page | +| D5 | R-991 | Approve the minimum machine: x86-64, 4 cores, 8 GB RAM, 256 GB SSD (recommended: 16 GB, 512 GB)? | **Approve** (measured on the N100 with 61 apps) — the 8 GB freeze of 2026-10-20 is fixed by agent 0.162.0 (11 h soak on a fresh 8 GB box, no freeze) | Change it: one edit | no hardware page; a buyer with a Raspberry Pi can still download the installer | the hardware page | | D4 | R-982 | Stop root SSH with a password from the household network (key only)? | **Yes — key only** (the password stays for the console) | Keep it: anyone on the household network can try the password | the host keeps accepting root password logins from the LAN | — | | D3 | R-985 | Our „zero-knowledge" wording is stronger than the product: change the wording, or remove the operator's root reach to the key? | **Change the wording now**; look again after the first sale | Remove the reach: a design change to break-glass | the website promises more than the product does | the website text | @@ -52,12 +52,11 @@ Newest first. CC's pick is in the „Pick" column. Each row also has its full te 6. BIOS: on the N100, read „After Power Loss"; on the HP, set „Bypass F1 Prompt on Configuration Changes" to Enable. Since 2026-10-14. 7. Pin the first Facebook post (R-917), and look at the new cover in the Facebook phone app (R-919). Since 2026-10-12. -**Morning list, 2026-10-22.** CC decided one thing (you may reverse it): a box tells the hub the notification list its page shows, even if never saved (R-1199; the rehearsal household got 1 alarm of 9). -1. Release controller 0.338.0 (restore put-back incl. power cut, first-hour words, swap sentence)? On the scratch box a damaged backup and a killed controller both kept the newest data, app running (R-1177, R-1195, R-1178, R-1180). -2. Release and vouch agent 0.162.0 (swap = RAM, host-swap check, no false door alarm — R-1192, R-1194)? Soak, 11 h on a fresh 8 GB box: no freeze, every check answered, every night job ran; memory pressure passed the 20 % line for 3 min in the 03:30 backup (R-1214). With no host swap the freeze comes back; our installer gives 7.75 GB. I'd release. -3. Deploy hub 0.164.0 (host-swap alarm, bind-page words)? And delete the test host „Tester4-9aca27" (machine gone; my token cannot delete). -4. How was Tester 2's laptop installed — our installer, or its own Proxmox? (Without host swap the fix does not help.) -5. A publish: the website download button (patch ready), and with the next ISO the boot text and the cleared screen (R-1210). Secrets: keep or remove the `REHEARSAL_2026_10_20_*`, `FIXES_2026_10_21_*`, `NIGHT_2026_10_21_*` names in sec. +**Today, 2026-10-22.** +1. Vouch agent 0.162.0 (Configs → Day-0 artifacts; sha256 `5fd7a23b…`, bundle `ac772967…`). If not: new boxes install 0.161.0, without the swap fix. +2. Discard the two test appliances 47 and 48 on the Hosts page (the installer proof). If not: they stay as „unclaimed". +3. Decide D28 above. If not: big boxes keep the warning. +4. When Tester 2 is back on: say so, and I send it agent 0.162.0 (the swap fix). **The rest** - Pull the failed disk Z6A07P2G out of DooPlex (R-934). If not: its alarms return on 11 November. Since 2026-10-12. - Rotate the reused homelab logins and decide the Gitea repo's visibility (R-925, P1). Since 2026-10-09. diff --git a/documentation/backlog/CLOSED-ITEMS.md b/documentation/backlog/CLOSED-ITEMS.md index cf95511c..300a1deb 100644 --- a/documentation/backlog/CLOSED-ITEMS.md +++ b/documentation/backlog/CLOSED-ITEMS.md @@ -26,6 +26,18 @@ --- +## 2026-10-22 morning — the releases (full text of the rows: `git show 115f15c8:documentation/backlog/OPEN-ITEMS.md`) + +| Row | What | Closed | Evidence | +|---|---|---|---| +| **R-1210** | **Three first-hour words from the rehearsal wait for a publish:** (P3) | CLOSED 2026-10-22 — W2 published (website `6b391a63`: „Letöltés (1,6 GB)" / „Download (1.6 GB)"); W1 + W7 shipped in ISO **1.30.0**, published after its gate and two proof installs (W1 seen on the boot screen; W7 by test — the bound banner needs a bind); both download pages point at 1.30.0. Full row text: `git show 115f15c8:documentation/backlog/OPEN-ITEMS.md`. | `documentation/tests/iso-release-1.30.0-2026-10-22/` | +| **R-1192** | **On the minimum machine (8 GB), the household's first afternoon froze the box for about an hour: the dashboard and every app stopped answering, and only pulling the plug brought it back.** (P1) | CLOSED 2026-10-22 — agent **v0.162.0** released (operator yes) and delivered to demo-hp, Tester 1, demo-felhom: each logged `guest-swap: raised` and `pct config` reads swap = memory (25898/25898, 12288/12288, 4096/4096). Night soak on a fresh 8 GB box: 11 h, no freeze. The vouch is the operator's. Follow-ups: R-1207 (no host swap), R-1214 (tier2 pressure), R-1216 (the host-swap check too strict). | `audits/morning-2026-10-22/release/04-agent-delivery.txt`, `audits/night-2026-10-21/P1-soak/` | +| **R-1177** | **A local restore that fails destroys the household's live data and keeps no copy of it: the app is left broken.** (P2) | CLOSED 2026-10-22 — shipped in controller **v0.338.0** (released on the operator's yes; on Tester 1, demo-hp and demo-felhom through the floor, then the global floor 0.338.0). Proven the night before on 9202: a damaged backup kept the newest row and the app ran. | `audits/night-2026-10-21/P3-*`, `audits/morning-2026-10-22/release/` | +| **R-1178** | **The second drive's „Teljes visszaállítás" can change files, then refuse the database half, leave the app STOPPED, and tell the household „the app and its data are untouched".** (P2) | CLOSED 2026-10-22 — shipped in controller **v0.338.0** (`UnitRestoreOptions.CheckOnly`: a refusal moves nothing); test-proven. | controller CHANGELOG v0.338.0 | +| **R-1180** | **The nightly second-drive mirror (`rsync --delete`) can run DURING a restore from that same mirror and delete files not yet copied back.** (P2) | CLOSED 2026-10-22 — shipped in controller **v0.338.0** (the night's mirror skips an app while its restore runs); test-proven. | controller CHANGELOG v0.338.0 | +| **R-1195** | **A power cut in the middle of a full off-site restore can leave the app running on the BACKUP's data while the page says only „the restore was interrupted, start it again" — the household's newer data is gone and nothing says so.** (P2) | CLOSED 2026-10-22 — shipped in controller **v0.338.0**; proven on 9202 the night before (a controller killed mid-restore → put back at the next start, the record says so in Hungarian). | `audits/night-2026-10-21/P3-*` | +| **R-1199** | **The household's notification page shows disk-warning, drive-disconnected and backup-failed mails switched ON, but on the rehearsal day only the OPERATOR got them — the household's mailbox received one alarm (a failed off-site run) out of nine.** (P2) | CLOSED 2026-10-22 — the hub mailed the household by a list saved 2026-10-18, before the box existed; the box never pushed its own because it pushes only a saved choice. Fixed in controller `ba22f9b` (a box with no saved choice pushes the default list its page shows, no address), shipped in **v0.338.0**. *Decided by CC unattended 2026-10-21 — operator may reverse* (the box's page is the source, `08`). `TestR1199_*` red-proved. | `REPORT-night-2026-10-21.md` §6, `audits/night-2026-10-21/P5-checks/` | + ## 2026-10-21 night — the CI time limit of the decoy suite (full text of the row: `git show f576d7f7:documentation/backlog/OPEN-ITEMS.md`) | Row | What | Closed | Evidence | diff --git a/documentation/backlog/OPEN-ITEMS.md b/documentation/backlog/OPEN-ITEMS.md index 3b886bec..7f8cd523 100644 --- a/documentation/backlog/OPEN-ITEMS.md +++ b/documentation/backlog/OPEN-ITEMS.md @@ -112,7 +112,7 @@ match what the reader sees is how an instrument stops being believed (R-421). It **nothing was proven on the day this line was drawn** and a stopping line that moves a status is a stopping line that lies. -## Install & onboarding — 7 rows (P3 5, P4 2) +## Install & onboarding — 6 rows (P3 4, P4 2) | ID | Category | Sev | What | State | Blocked on | Next action | Owner | |---|---|---|---|---|---|---|---| @@ -120,7 +120,6 @@ stopping line that lies. | **R-250** | Install & onboarding | P3 | **A customer create can fail fail-closed because the host-key scan ladder is shorter than the DNS/AAAA settle time.** Found 2026-08-07 creating the fifth walk's venue. `POST /configs/new` with off-site enabled provisions the Storage Box sub-account and then scans its SSH host key to pin it — **fail-closed by design** (`offsite.go:111-121`, *"don't serve a descriptor the controller can't verify"*), with `defaultScanBackoff` = 2+4+8+16+30 ≈ **60 s**, sized by its own comment to *"the observed DNS propagation lag"*. **Measured, both halves:** the first create exhausted the ladder — five `no such host`, then `dial tcp [2a01:4f8:bacc:2:200::d30]:23: connect: network is unreachable` (the name had just begun resolving, **AAAA-first, into a pod with no IPv6 route**) — and the hub logged `[ERROR] offsite provision for walk5`. An **identical second POST succeeded** ~70 s later on its own final rung (`shared already provisioned … (subaccount 285351)`). **Total settle ≈ 100 s against a 60 s budget.** The endpoint was never the problem: verified afterwards from both the node and the hub pod, by name, `SSH-2.0-OpenSSH_9.6p1`. **Two distinct things are wrong and should not be merged:** (1) the budget is sized against DNS *existence*, but what actually bit is the **AAAA-before-A** window, a different and longer phenomenon — lengthen the ladder and/or prefer the A record for the scan dial; (2) **the operator is told nothing actionable** — the create fails with a generic error, the remedy is "press it again", and nothing says so. The retry is genuinely safe (idempotent on the label; confirmed afterwards — `one_time_secrets` 1, one sub-account, no double-provision) **but that safety is invisible to the person deciding whether pressing again will double-charge them.** **Severity LOW-MEDIUM:** self-clearing, no data at risk — but it is the first thing a new customer's provisioning does and it fails looking like an outage. | **VERIFY** — **2026-10-12: hub 0.147.0 live** (S29, decision 224): the host-key scan dials IPv4 first, waits ~2 min (was ~1), and when it still runs out says the store was created and it is safe to press Save again (`TestScannerDialsIPv4First`, `TestScanOutOfRetriesSaysSafeToPressAgain`, red-proved). Known limit: the hub Ingress reads for 60 s, so a very slow first try can show a gateway timeout while provisioning finishes in the background (pressing again is safe). **READY** — operator ruling 2026-10-12 (S29, `09` §3 decision 224): yes — the scan prefers IPv4, waits longer, and the error says „safe to press again". **READY** — owner Viktor | — | The next real off-site setup (a new customer): read the hub log for the scan; success or the new message → close | CC | | **R-516** | Install & onboarding | P3 | **[P3-LOW] English a customer meets on a fresh box and its apps' first screens — enumerated by the big night.** MEASURED 2026-09-14 (BIGNIGHT, VM 333, ISO 1.27.1, controller 0.242.0). Felhom-owned: (1) the dashboard menu item **„Debug"**; (2) the dashboard CPU tile **„Load: 0.29 / 0.39 / 0.37"**; (3) the launcher tile **„Filebrowser"** opens a login in English with no Felhom text (R-513); (4) the storage page mixes formal „Adjon hozzá / Csatlakoztasson" with the product's „te". App first screens a household meets before any Felhom text helps: (5) **Uptime Kuma 2.4 opens on „Which database would you like to use?"** (SQLite / Embedded MariaDB, „Next") — the app card's „Első lépések" does not mention it; (6) PrivateBin, Gokapi, AdventureLog and FileBrowser UIs are English (the apps' own). Already rows: the Proxmox installer screens (R-495, answered by the guide), `wiki.DOMAIN` (R-498). **Fix shape:** rename „Debug"/„Load" (controller); add the Uptime Kuma database step to its card, or pre-seed `db-config.json` for SQLite in the template (catalog). **Added by F4 (20:04:54Z):** (7) the storage page prints the disconnect time as a raw ISO UTC string „Leválasztva: 2026-09-14T19:58:02Z"; (8) the „Meghajtó leválasztva" banner appears twice on every page; (9) „4 telepített alkalmazás nem fut — nézze meg a rendszermonitort" uses the formal form. **Added by F7 (20:50–21:00Z, system disk at 95 %):** (10) a banner on every page in English, „**SSD disk usage high: 90%**"; (11) the dashboard tile reads „Rendszer (/) 61.8 GB / 68.7 GB (**90%**)" while `df` reports **95 %** (reserved blocks ignored), and „(/)" labels the data volume `/mnt/sys_drive`; the deploy page says nothing about free disk. **Added by the i18n spike (2026-09-17, controller v0.247.0):** (12) **six formal („ön") forms in the converted dashboard copy** — „Olvassa be telefonnal" (launcher QR hint), „Biztosan kikapcsolja a megosztást?" (launcher), „Ha újratelepíti … importálnia kell" (the layout's remove-app modal), „Kérjük, vegye fel a kapcsolatot" (backups empty state). They were NOT fixed — a localisation release may not change Hungarian bytes — and are now COUNTED by `controller/scripts/i18n_missing_gate.py` (`HU_FORMAL_CEILING` = 6, a ratchet: a new one convicts, fixing one lowers it). The inventory (`audits/I18N-INVENTORY-2026-09-17.md`) is the list this row closes against in localisation slice 6 (R-561). **Extended 2026-09-17 by slice 1 (controller v0.248.0–v0.250.0):** the converted copy now counts **16** formal forms (`HU_FORMAL_CEILING` 6 → 10 → 12 → 16, each raise stated, Hungarian unchanged by rule) — and the count is an UNDER-count: the gate's stem list sees 4 on the release C pages (storage, drive wizards, debug), while a wider list („írja be”, „adja meg”, „adjon hozzá”, „válassza ki”, „biztosan eltávolítja”, „engedélyezze”, „hozzon létre”, „kattintson”) finds at least **22** keys there alone (login „Adja meg a jelszavát”, the NAS guide, the storage confirms). Widen the stems when this row is worked; the ceiling rises with them. **NARROWED 2026-09-20 by localisation slice 6's walk, item by item** (`audits/i18n-slice6-2026-09-20/R-516-item-by-item.md`): item 2 FIXED (slice 1), items 3 and 6 APP-OWNED (and for an English household item 6 is an advantage), item 11 is a wrong NUMBER rather than a language and needs its own row, item 1 is correct English for an English reader and still open for a Hungarian one. **Items 4, 7, 8, 9 and 10 are NOT DECIDABLE FROM AN ENGLISH WALK** - they are about Hungarian copy quality, a disconnected drive and a full disk, none of which this walk had. **What this row is now waiting for is a HUNGARIAN walk on a box with a second drive**, not another English one; saying it closed would be the kind of closure that makes a register stop meaning anything. **-- 2026-10-08:** the recovery screen's own answers are Go literals in Hungarian only — 14 `renderRecovery` messages in `controller/internal/web/recovery_handlers.go` (seen: the safe default „A művelet nem fejeződött be…" rendered on an English page in a red-proof run). Today's new R-304 sentence is a bundle key in both languages; the 14 old ones are not. | **NARROWED 2026-09-20 - rank P3-LOW; owner: CC; needs a Hungarian walk** **2026-10-05 (burn-down night): items 1 and 4 FIXED on controller `main`** (`d7efa7b`): the menu says „Hibakeresés” (English „Debug”); the storage pages use the te-form (formal-form ceiling 17 → 14; 116 parity fixtures changed by exactly those bytes). Item 2 was already fixed. **Left:** items 5–6 (apps' own screens) and the rest. **2026-10-06: items 1 and 4 DELIVERED** (controller v0.298.0). **2026-10-06 (burn-down night, later): items 7–10 and 12 FIXED on controller `main`** (`e4774e6`, `2e5ef7e`): the disconnect time in local time; one banner per unplugged drive; „nézd meg”; the disk/memory/CPU/temperature banners in the household's language (`health.*` keys; the wire text to the hub unchanged and pinned); the last eleven counted formal forms are te-form (ceiling 14 → 0; 119 parity fixtures changed by exactly those bytes). **Left:** items 5–6 (apps' own screens); about 20 formal forms the gate does not count yet („írja be”, „adja meg”, „hozzon létre”, …) on the debug, storage, network-storage and security pages. Item 11 moved to its own row **R-889**. **2026-10-06 02:40: the bundle has NO formal form left** (controller `4c3c203`, unreleased): 49 sentences in the te-form; the gate's stem list widened (it counted 61 on the previous bundle, 0 now) with decoys and one listed third-person exception. **Left (narrowed):** Felhom-owned formal forms in Go and template literals the gate cannot read yet — the network-storage attach errors, escrow and share handlers, the single-copy notice, a settings refusal, the SMART mail, a fill-watch „Kérjük”, and the setup wizard pages; each moves into the bundle in the te-form. Items 5–6 are the apps' own screens (not ours). **2026-10-06: items 7–10, 12 and the bundle's 49 formal forms DELIVERED** in controller v0.299.0. **2026-10-06 night: the Go-literal leftover moved** (controller main `3d6ba28`, unreleased): 22 Go-literal messages — escrow handler (6), share password page (2), export upload (1), network-storage uid/remove/attach failures (13) — are bundle keys (`api.escrow.*`, `api.share.*`, `api.export.*`, `api.netstorage.*`) in the te-form with English (14 were formal); a detached attach failure renders in the reader's language; the NAS refusal says „Válassz". `TestR516_GoLiteralFormalFormsAreGone` (source scan + positive control), `TestR516_NetAddFailureFollowsTheReader`; red-proofs `audits/night-burndown-2026-10-06/ctrl/R-516-red*.txt`. **Left:** the setup wizard and recovery-info.txt (R-554); the SMART and fill-watch texts (the hub event's message — wire text, needs the household-copy producer shape); items 5–6 (apps' own screens). | — | — | CC | | **R-991** | Install & onboarding | P3 | **Nothing a buyer can read says which machines Felhom installs on, and a quarter of the forum beginners own only machines it cannot install on.** FOUND 2026-10-12 (forum research, `audits/forum-research-2026-10-12/FELHOM.md` §2). Searched `documentation/architecture/`, `website/` (`gyik`, `technologiak`, `letoltes`) and `scripts/felhom-host-install.sh`: no CPU-architecture, RAM, disk or network floor is written anywhere. The download page says only that the installer is built on Proxmox VE 9.2 — x86-64 only (inferred from Proxmox, not stated on the page). Of the 33 forum beginners who name what they own, 8 own only a Synology/QNAP/other NAS box, a router with a USB disk or a Raspberry Pi. The selfh.st survey reading reached the same gap independently (R-989, its recommendation 1). **Needs (operator):** the floor itself (RAM and disk minimum; whether thin clients and old laptops with 4–8 GB are accepted) — then one short section on the download page and in the FAQ. Not changed here: the research task forbade website edits. | **WAITING-ON-OPERATOR** — **2026-10-20: R-993 merged here** (one decision, D5): the proposal to approve is `audits/sizing-2026-10-13/SIZING.md` §5 — minimum x86-64, 4 cores (N100 class), 8 GB, 256 GB SSD; recommended 16 GB, 512 GB SSD; out: ARM / Raspberry Pi, Synology-QNAP, routers, cloud VPS. R-993 also measured that the installer has no floor on the HOST (`autosize_guest_caps` limits only the guest), so whatever minimum is approved, nothing enforces it at install today (full text: `git show 5c487313:documentation/backlog/OPEN-ITEMS.md`). filed 2026-10-12 | the operator naming the floor | Operator: approve or change `SIZING.md` §5 (STATUS D5); then CC writes the section on `letoltes.html` and `gyik.html` (both languages) and files the install-time host floor as its own row if it is wanted. If nothing is done: a buyer with a Pi or a Synology downloads an ISO that cannot run | operator | -| **R-1210** | Install & onboarding | P3 | **Three first-hour words from the rehearsal wait for a publish:** W1 the boot text „…válassza ki a lemezt…" (formal) → „…válaszd ki…" and W7 the linked banner clears the screen and its scroll-back (the stray „V" glyph was already fixed in source by R-725) — ISO source committed `2fa5b8f3`, ships with the next ISO; W2 a real „Letöltés (1,6 GB)" button on felhom.eu/letoltes (and „Download (1.6 GB)" on /en/download) — a website push publishes, so the change is a prepared patch (`audits/night-2026-10-21/P4-words/W2-download-button.patch`), not applied. | WAITING-ON-OPERATOR | the operator's yes to publish (website) and the next ISO build | Apply the W2 patch and push (site gates first); W1/W7 with the next ISO | operator | | **R-494** | Install & onboarding | P4 | **NARROWED 2026-09-14 by operator ruling → [P3-LOW] the hub COULD create the tunnel at customer creation, for a domain already on Cloudflare. Not blocking: every customer has their own domain and the operator creates the tunnel per day-0 A.1 (`architecture/01-topology-and-trust.md`).** *Original finding, kept:* **[P1-HIGH] A new customer's dashboard has NO reachable address unless the operator hand-makes a Cloudflare tunnel — the link in the setup-code mail is dead.** MEASURED 2026-09-14 on a fresh install from the public ISO (drill intervention **I1**): the claim mail points at `https://felhom.drill0242.felhom.eu`; that name has **no A and no AAAA** record (`dig @1.1.1.1`, control `felhom.enkisfelhom.hu` resolves); the hub has **no tunnel- or DNS-creation code** (`hub/internal/cloudflare/` holds only geo-rule removal; `cf_tunnel_token` is a pasted, optional form field, `configs.go:1478`) — day-0 runbook A.1 makes it a manual Cloudflare-dashboard step that nothing on the customer-create page asks for; the box's own split-horizon resolver on the appliance LAN IP answered `google.com` but not the dashboard name at 13:27:39Z; the agent applied the record at **13:27:44Z** (`lanresolver: applied split-horizon record … ip=192.168.0.158`, 3 m 46 s after the controller started), so the box CAN answer the name — **but only to a device that uses the box as its DNS server, and no document, screen or mail tells a household to do that**; the router and the installer-offered DNS answer nothing. The page was reachable only at the guest's LAN address with the name forced (`curl --resolve …:443:192.168.0.158`). **A volunteer could not have done that.** **What it needs:** an operator ruling — the hub creates the tunnel and DNS at customer creation, or the product gives a household a LAN address that works with no DNS change. | **READY — rank P3-LOW; owner: CC** **Re-ranked 2026-10-03: P3→P4: operator-side automation; the operator creates the tunnel by hand per the day-0 runbook.** | — | — | CC | | **R-504** | Install & onboarding | P4 | **[P3-LOW] `iso.felhom.eu` cannot show an index page on its own — its root returns 404, and the download page lives on the website instead.** MEASURED 2026-09-14: `https://iso.felhom.eu/` and `/index.html` → 404; only named objects answer. The host is an R2 bucket behind a custom domain; whether R2 would serve an uploaded `index.html` at `/` was **not measured** (uploading anything to the public bucket is a publication). The ISO v1.27.0 task puts the Hungarian download page at `felhom.eu/letoltes` (published with the ISO, after the operator's yes). **Remaining:** a redirect from `iso.felhom.eu/` to that page needs a Cloudflare rule the session has no credential for. | **WAITING-ON-OPERATOR — rank P3-LOW; owner: operator (Cloudflare rule)** **Re-ranked 2026-10-03: P3→P4: households are sent to the website's download page; the bare address is cosmetic.** | — | — | operator | @@ -154,17 +153,13 @@ stopping line that lies. | **R-683** | App updates | P3 | **[P3-LOW] Watch: after a power cut during an update's health check, the hold named an HOUR-OLD second-drive copy, not the one the update's own backup should have just made.** 2026-09-24 chaos round 3 (nextcloud, `backup_max_age: 1m`): no `backing-up` phase was seen and the hold named Tier 2 at 13:04 for an update pressed at 14:04; the pre-cut controller log was lost with the container (the runner now saves it at arm time — R-320). Round 11, the same action without a power cut, named a fresh 14:34 copy and logged the Tier-2 copy. The sentence was TRUE (it named the copy it offered); the question is why the update did not back up first. Not reproduced; watch the next power-cut drill. `audits/night-2026-09-24/E/round-03*.json`, `E/round-11-controller-pre.log` | **OPEN — P3; owner: CC (watch)** | — | — | CC | | **R-785** | App updates | P3 | **[P3-LOW] SparkyFitness is pinned 11 releases and a major behind upstream (v0.17.3; upstream v1.7.3, v1.6.0 dated 2026-07-24).** READ 2026-10-01 (`audits/visitors-2026-10-01/C/bench/C1-previous-tag.txt`). **Needs:** an update walk 0.17 → 1.x through the ladder (bench + box), after R-784 is decided. | **OPEN — rank P3-LOW; owner: CC (after R-784)** | — | — | CC | -## Backup & restore — 44 rows (P1 2, P2 10, P3 19, P4 13) +## Backup & restore — 38 rows (P2 5, P3 20, P4 13) | ID | Category | Sev | What | State | Blocked on | Next action | Owner | |---|---|---|---|---|---|---|---| | **R-232** | Backup & restore | P2 | **DooPlex's backup makes every copy inside the same box — and nothing tells anyone when it fails.** Surveyed read-only 2026-08-06 (`audits/RECON-dooplex-backup-2026-08-06.md`). **What works:** five sets, 14/14 successful runs in 14 days; a file was restored from the `data` repo and matched the live original **byte for byte**; every set except two is cross-disk; k3s is integrity-checked on every run. **What the matrix exposes, ranked:** (a) **`notify_failure` is a no-op** — `NOTIFY_ON_FAILURE=true` but `NOTIFY_WEBHOOK_URL` is commented out, so a failed backup notifies **nobody**; the project already has a working Resend path that CI uses. Cheapest item, and it makes every other failure visible. (b) **Nothing leaves the box** — no rclone, no remote repo, no off-site target anywhere; Longhorn's target is `nfs://192.168.0.180:` pointing at DooPlex itself, and the only outbound-looking cron pulls *inbound* from Hetzner for a different project. The machine that runs the hub managing the customers' off-site chain has no off-site copy of its own. (c) **The backup tree is a single writable path** and the restic repos are not append-only — one bad script or ransomware destroys every copy at once. (d) **Two same-disk sets**: `.claude-memory` and the PostgreSQL dumps, whose source directory sits *inside* the backup tree. (e) **Longhorn `retain=1`** — one generation per volume, so a corruption noticed a day late has no earlier copy. (f) **`/opt/backup/docs/BACKUP-RESTORE.md` does not exist** though the systemd unit advertises it. (g) **`secrets/restic-repo` has never held a snapshot** — `backup-secrets.sh` contains no `restic` call; the secrets are GPG files on `sda1` only. (h) **No restore has ever been run** beyond today's single-file probe — the matrix's "ever demonstrated?" column is otherwise entirely empty. **Not a finding:** the restic passphrase. The on-box copy is on `sdb1`, a different disk from the backups, and the **operator holds an offline copy out of band** — so a disk loss is recoverable. The narrow residual is that it is operator-held rather than system-held, unlike the customer case's hub-vaulted escrow, so it should be confirmed current and findable by someone else. **Nothing was changed by the recon.** | **NARROWED 2026-10-08 — owner Viktor.** (a) DONE with the operator's yes in chat: `notify_failure` now mails admin@felhom.eu through Resend; proven by one test mail that reached the inbox (`audits/day-2026-10-08/r232/`; no backup was started). (b) partly: the hub database leaves DooPlex nightly to ep0 (R-173); everything else stays on the box. (c)–(h) unchanged. **2026-10-09 (operator yes in chat): (b) and (h) DONE for Gitea and the secrets.** Nightly 00:20 `felhom-dooplex-offsite` pushes Gitea (614 MB of repositories, the `gitea` database dump taken first, `app.ini`) and the nightly GPG secrets export, encrypted with a NEW key, to ep0 `operator` (`host/dooplex-gitea`) on the hub-DB write-only token — no change on ep0; first push 57 s; restore test weekly (manifest, `git fsck` every repo, `pg_restore --list`), run once: 27 805 files, 10 repos OK; `DooplexGiteaOffsiteStale`/`DooplexGiteaRestoreTestStale` in force (`absent()` included, promtool + 2 red-proofs); every backup unit now mails on failure (`OnFailure=`, dry run reached the inbox). **First real Gitea restore:** into a throwaway on the bench, 10/10 repos, product `main` = live, a file byte for byte, a login (`runbooks/gitea-restore.md`). The hub came back too (R-173, closed). **The registry is left out on purpose:** its images rebuild from the code. **Correction to the recon §7:** the API mirror holds ONE repo (`homelab-manifests`), not all — Gitea had a single copy, on DooPlex. `audits/dooplex-survival-2026-10-09/` **LEFT:** (c) append-only for the on-box tree, (d)–(g) as written; the paper copy of the new key (operator). **READY** for the rest | — | — | operator | | **R-895** | Backup & restore | P2 | **The hub's clean-up-window check trusts the snapshot counts the box sends, so a broken-into box (or past-dated fakes added through the add-only key) can shrink the real off-site history without an alarm.** READ 2026-10-06 night in source (R-822's design): the before/after comparison uses counts the box itself reports (`hub/internal/offsitekeys/service.go:284`, `:343`); new fakes keep the count level. Decision 68 already accepts a box-trusted count. | **NARROWED 2026-10-18 — slice 2 built, not deployed** (hub v0.158.0): the 07:10 audit compares the `snapshots/` listing with yesterday's by name — files gone that no clean-up window explains → `offsite_snapshots_vanished` (error), files no reported box run explains → `offsite_snapshots_unexplained` (warning); operator-only, hub-origin (not in `allowedEventTypes`). First listing = baseline; a move-aside or RESET drops it; vanishing judged on a pinned tier only; files younger than 1 h judged the next day. Red-proofed twice (`snapshot_watch_test.go`). **Not built:** the window's before/after on the hub's own count (design §3.1) and refusing a window while unexplained files exist (§3.2). Unmeasured: the provider shell's `ls -l` time zone (± 3 h slack until then). **Deployed 2026-10-18 12:23 (hub v0.158.0).** The first listing (tomorrow 07:10) is a baseline; the first verdict is 2026-10-20 07:10. **Known limit (independent review 2026-10-18, F2):** `_unexplained` is explained by the box's OWN reported `offsite.last_run`, so whoever holds a box's key can silence it; `_vanished` is judged on the hub's own listing and is not affected. **2026-10-20 03:5x UTC: due date moved 10-20 → 10-21** — the first verdict lands at 07:10 hub time (05:10 UTC), after the night session that reached it ended; that brief did not include this read. Nothing is lost: the hub keeps its listing; read the 2026-10-20 07:10 lines on 10-21 (or later on 10-20). **FIRST VERDICT READ 2026-10-21 (rehearsal session, read-only):** the 07:10 CEST run judged three tiers against yesterday — demo-felhom 5, demo-hp 14, tester-1 4 new snapshot files, „each inside a reported box run"; nothing vanished, nothing unexplained; Tester4 stored its first baseline (44 files); Tester-2's own listing failed (no `snapshots/` dir — the box has never pushed). No `offsite_snapshots_vanished` / `_unexplained` mail in the operator mailbox (second channel). Evidence `audits/due-checks-2026-10-21/R-895-hub-0710.txt`. The positive alarm path is still proven only by the unit red-proofs. | the operator's yes to deploy hub v0.158.0 | Deploy; read the first 07:10 lines (newest upload vs the box's last run = the time-zone calibration), shrink the slack; then decide §3.1/§3.2 | CC | | **R-923** | Backup & restore | P2 | **The password manager (Vaultwarden) runs on DooPlex and holds the keys that open DooPlex's own off-site copies — a loss of DooPlex loses the keys with the copies.** Operator finding, 2026-10-09 11:19: "the password manager also runs on DooPlex (Vaultwarden), so I probably need to back up its DB somewhere too." Measured: `vaultwarden-system/vaultwarden` (1.37.3), PVC `vaultwarden-data` 7.4 MB (`db.sqlite3` + WAL, `rsa_key.pem`, no attachments); its only backups were Longhorn on DooPlex. **A key in a password manager that runs on DooPlex is not off DooPlex** — R-173's "both keys are off DooPlex" (2026-10-05) and the hub-DB runbook Step 0 were wrong in that sense. Also seen: Vaultwarden warns its `ADMIN_TOKEN` is plain text (an Argon2 hash is its guidance). | **NARROWED 2026-10-09 (operator yes in chat):** Vaultwarden's own `backup` copy + `rsa_key.pem` ride the nightly encrypted DooPlex→ep0 job (`scripts/dooplex-offsite/`), checked on every push and every Sunday (integrity, users, items — rows only). That copy opens only with the DooPlex off-site key, and the vault only with the master password — so the circle is broken only once both are on paper outside DooPlex: `runbooks/break-glass-sheet.md`, `runbooks/total-loss-of-dooplex.md`. **LEFT:** the operator prints the sheet and stores it away from home; the `ADMIN_TOKEN` hash (a DooPlex change, operator's word). | operator: print the sheet | Operator: print + store the sheet; then close | operator | -| **R-1177** | Backup & restore | P2 | **A local restore that fails destroys the household's live data and keeps no copy of it: the app is left broken.** PROVEN LIVE on scratch 9202 (`audits/dataloss-hunt-2026-10-20/C3-R1-local-restore-9202/`): Rallly + Postgres; control restore OK; then a live row C, the unit's DB volume tar damaged (half), the household's restore → the live volume removed, `tar: short read`, the DB replay correctly skipped, the app started → Postgres crash-loops (`initdb: directory … exists but is not empty`); row C gone; NO undo or safety copy anywhere; the household reads „Visszaállítás sikertelen: starting rallly after restore from unit: starting stack rallly: exit code 1 stderr: …" (raw English Docker output). Mechanism `internal/backup/restore_unit.go:428-489`, `restore.go:215-246`. The OFF-SITE path got „put back exactly as it was" in v0.336.0 (D20 = A, R-893); the LOCAL path — 07 §3's main customer restore — did not. Two reviewers found it independently (R1, D4). **FIXED on main the night of 2026-10-21 (D22 = yes, operator 20:05)** — controller `d582feb`: the local unit restore (the app's own, the second drive's, a kept load) measures, copies and puts back exactly on any failure, reusing `offbox_restore_undo.go`; **proven live on 9202 with 0.338.0-rc.1** (`audits/night-2026-10-21/P3-restore/`): the same damaged-unit case → the live volume poured back, the newest row kept (A,C), Rallly running, „…Nem változott semmi…"; red-proved (`TestR1177_*`, 4 seen failing on the old code). | WAITING-ON-OPERATOR — fixed on main, proven on 9202; ships with the controller release | the controller release (morning list 1) | Release; then close | operator | -| **R-1178** | Backup & restore | P2 | **The second drive's „Teljes visszaállítás" can change files, then refuse the database half, leave the app STOPPED, and tell the household „the app and its data are untouched".** `tier2_whole.go:301-340` stops the app and merges the files first, then calls the unit restore, whose refusals (cut-off dump, mixed versions, allow-list, data key — `restore_unit.go:366-423`) all return before its own stop/start. PROVEN against production code (`audits/dataloss-hunt-2026-10-20/C3-R5-whole-restore/`): 1 file restored + 1 replaced (the live one kept beside), calls `[stop]`, no start, message „…A visszaállítás biztonsági okból nem indult el — az alkalmazás és az adatai érintetlenek." Data-loss hunt 2026-10-20 (C1 reviewer 1). **FIXED on main 2026-10-21 night** — controller `d582feb`: the unit's refusals are asked (`UnitRestoreOptions.CheckOnly`) before the file half, so a refusal moves nothing and never stops the app; a later refusal starts the app and names the changed files (`err.backup.whole_restore_unit_refused_files_changed`). `TestR1178_AUnitRefusalComesBeforeAnyFileMoves` red-proved (the R5 outcome: 1 restored + 1 replaced). | WAITING-ON-OPERATOR — fixed on main (test only); ships with the controller release | the controller release (morning list 1) | Release; then close | operator | -| **R-1180** | Backup & restore | P2 | **The nightly second-drive mirror (`rsync --delete`) can run DURING a restore from that same mirror and delete files not yet copied back.** `RunAllTier2` (`tier2.go:479-520`) takes no backup flag and does not ask about a running restore; the whole restore holds only the backup flag (`tier2_whole.go:301`), the night leg only `LegLock` (`cmd/controller/main.go:1348-1352`). A long restore of a photo library at 03:30, or 15 min after a missed night, overlaps. PROVEN against production code with the real `rsync -a --delete` mirror (`audits/dataloss-hunt-2026-10-20/C3-T1-mirror-during-restore/`): with the backup flag held by a restore, `RunAllTier2` still mirrors, and the mirror goes from [a,b,c,d] to [a,b] — the two files the restore was bringing back are gone from the only copy. Data-loss hunt 2026-10-20 (C1 reviewer 4, T1). **FIXED on main 2026-10-21 night** — controller `d582feb`: `RunAllTier2` skips an app (and the shares) while a restore of it runs, says so, and mirrors it the next night. `TestR1180_TheNightMirrorNeverRunsDuringARestoreOfThatApp` with the production rsync mirror, red-proved ([a.jpg b.jpg] without the skip). | WAITING-ON-OPERATOR — fixed on main (test only); ships with the controller release | the controller release (morning list 1) | Release; then close | operator | -| **R-1195** | Backup & restore | P2 | **A power cut in the middle of a full off-site restore can leave the app running on the BACKUP's data while the page says only „the restore was interrupted, start it again" — the household's newer data is gone and nothing says so.** PROVEN LIVE in the rehearsal 2026-10-20 (`audits/rehearsal-2026-10-20/B6-failures/s2-power-cut-mid-restore/`): BookStack, a page added after the backup; „Teljes visszaállítás"; power cut at 14 s (the app stopped at 8 s, the database starting for the replay) → after power-on the crash recovery restarted the app (`appstop_marker.go`), recorded „A visszaállítás megszakadt (a doboz újraindult) — indítsd el újra." and pushed `restore_interrupted`; BookStack ran on the backup's 5 pages, the newer page gone; no hold; the undo copy written before the change (`offbox_restore_undo.go`) was not used. A cut at 6 s (before data moved) behaved correctly. This is R-1188 (a) proven; R-1188 keeps its other items. **FIXED on main 2026-10-21 night (D22)** — controller `d582feb`: once the copy is whole the restore records it in the app-stop marker; at start the crash recovery pours it back before the restart, and the record reads „A visszaállítás félbeszakadt (áramszünet). Az alkalmazás adatai a visszaállítás előtti állapotban vannak." **Proven live on 9202 (rc.1):** the controller killed (kill -9) right after the volume step → on start the copy poured back, markers A,C,D (D newer than the unit), the app running. The off-site path by `TestR1195_AKilledOffsiteRestoreIsPutBackOnStart` (red-proved). | WAITING-ON-OPERATOR — fixed on main, proven on 9202 (local path live, off-site by test); ships with the controller release | the controller release (morning list 1) | Release; then close | operator | | **R-49** | Backup & restore | P3 | **[P2] The offsite capture set is ~90% cache and duplication — 1.1 GB of a 1.2 GB immich "photo backup".** Measured 2026-07-19: `immich_ml_cache.tar` **823 660 032 B (~60%)** — re-downloadable ML model weights; `immich_postgres_data.tar` **308 251 136 B (~23%)** — a raw tar of the postgres data dir that DUPLICATES the logical `.sql` dump captured beside it; `upload/backups/` **18 MB** — immich's own nightly dump, a backup inside the backup, growing daily; plus the stranded pre-v3 `dccc13fe…` tree (~36 MB) no DB has ever referenced. Actual irreplaceable content: **72 MB of originals**. **MIGRATED FROM `ROADMAP.md` 2026-08-22 (R-369) — originally filed 2026-07-19, size S–M, roadmap state `idea`.** Moved verbatim; nothing added or reinterpreted. The roadmap keeps its copy as history, marked moved. | **OPEN — migrated from ROADMAP 2026-08-22, rank unchanged** **Re-ranked 2026-10-03: P2→P3: wasted space and transfer, no data risk; needs a capture-set ruling, not a sale blocker.** **READY 2026-10-20 — measured and planned, nothing changed; the decision is the operator's (STATUS D21).** Re-measured on 9202 (Immich v3.2.4): off-site ~1.33 GB = model cache 824 MB (62 %), raw database folder 283 MB (21 %), Immich's own backups 115 MB (9 %), logical dump 54 MB, originals 49 MB, thumbnails 2 MB — 102 MB must survive. A: leave out all three re-fetchable parts (−92 %; needs a never-run restore from the dump alone on the vectorchord image). B: only the model cache (−62 %; needs one restore with an empty cache). Pick: B now, A's other parts after their proof (`audits/night2-2026-10-20/P4/immich-offsite-plan.md`). | — | **Evidence: `audits/DIAG-immich-restore-round2-2026-07-19.md` §4 (full byte breakdown).** This is the customer's offsite quota and transfer cost, and it lands on the Hetzner sub-account they are billed for. **Recorded, deliberately not changed** — a capture-set exclusion is a data-loss-shaped decision and gets its own ruling, not a drive-by edit. Candidates in priority order: (a) `immich_ml_cache` — pure cache, strongest case; (b) the `postgres_data` volume tar where a logical dump of the same DB is already captured (the dump is what the restore path actually replays); (c) `upload/backups/`. Likely generalises past immich into a template-classification rule about cache volumes and self-backup directories, so it should be specified against the catalog, not one app | CC | | **R-314** | Backup & restore | P3 | **`StopAbandon` has no web route — a customer who telephones is served by a command line.** `--abandon-stop` exists on the controller binary (`cmd/controller/main.go:86`) and refuses rather than silently no-opping, which is right. But there is no handler: the only in-product way to cancel a countdown is the customer finding their recovery code (Scenario G cancels it at the moment the code proves they still have it). **An operator who is telephoned instead has to reach a shell on the customer's machine.** Used this session on the operator's ruling, container stopped first so the running controller could not overwrite `settings.json` from memory — a sequencing subtlety that is itself an argument for a route **-- 2026-10-08 design:** `audits/day-2026-10-08/design-R-314-279-177.md` — the box's own 14-day countdown has no operator door (the hub's 7-day phase does, decision 74); one door for R-314 + R-279: a fixed list of operator actions carried in the report reply. Question D1 on STATUS's decision sheet. **-- 2026-10-08 14:16 operator ruling D1 (`09` §3 decision 185):** yes — option A, a fixed list of operator actions carried in the box's report reply. | **VERIFY — 2026-10-09: DELIVERED (hub 0.144.0 + controller 0.304.0); `run_job fill-watch` proven live on the Tester 1 box (hub row „done — ran to its end"; control: the box log „checked 3 filesystem(s)"; an unknown action is refused 400). `abandon_stop` / `abandon_extend` NOT yet proven — no box has a deletion countdown; prove them on the first one.** **VERIFY — built on main 2026-10-08 (D1, decision 185), ships with tomorrow's controller + hub releases; closes after the live proof on 9202** (`abandon_stop` / `abandon_extend` through the hub's buttons). **READY (S) — NEW 2026-08-12, RANK 3** **2026-10-05 (burn-down night): NEEDS A DESIGN.** There is no operator door into a RUNNING controller (its HTTP surface is the household's session; the CLI runs in a separate process and cannot safely trigger a job in the running one). Same design as R-177 and R-279. | R-241, R-307 | An operator-authenticated POST that calls the same `StopAbandon`, so the telephone path and the code path converge | CC | | **R-401** | Backup & restore | P3 | **Revisit the off-site integrity depth when a real store is LARGE — the default rests on ONE measurement, on ONE 134 MB store.** Controller v0.228.0 (R-399) made `--read-data-subset=100%` the default for every box. The whole justification is a single data point: `demo-hp`, 2026-08-30, 140 829 678 B / 2 651 blobs / 67 snapshots, structure 35.0 s vs 100% **39.2 s** — four seconds. Re-proven live 2026-08-31 at 38.7 s. **It does not extrapolate, and the reason is structural: the structure check's cost tracks the INDEX, a read-data run's tracks the DATA.** A 50 GB store is ~370x the data and this curve says nothing about it. **Nothing was invented from that one point** — no rotation schedule, no size threshold, no bandwidth budget — because four production designs in this project were specced against unvalidated mechanisms and all four were wrong. **`readDataSubsetRe` already accepts `n/m`**, so a rotating schedule (`1/7` on a different seventh each week) needs no parser work when the time comes; the missing input is a measurement on a large store, not code. **THE TRIGGER IS AN EVENT, NOT A DATE:** the slow-check WARN from v0.228.0 firing on any box (`integritySlowNoticeThreshold`, 5 min) — that line names the duration, the depth and this row. **WHAT HAPPENS IF NOBODY ACTS:** every box re-reads its entire store every week, however large it grows, and the first person to notice is a customer whose upload is saturated. **Whoever acts must also revisit `integrityCheckTimeout` (30 min)**, which is now the number a large store meets first. | **OPEN — WATCHING** | — | When the WARN fires: measure the curve on that store, then choose between a rotation (`n/m`), a size-conditional default, or leaving it. Do NOT choose from this row's numbers — they are the small-store case. | CC | @@ -217,7 +212,7 @@ stopping line that lies. | **R-1094** | Storage & devices | P4 | **The whole-disk format refusal tells the household to format the free part — which is refused while the other part is in use.** SEEN 2026-10-16 (controller 0.318.0): 409 „Ezen a lemezen egy használatban lévő meghajtó van, ezért a teljes lemez nem formázható. Csak a szabad részét formázhatod." — since agent 0.158.1 a part next to a mounted part can only be USED (the root wrapper trusts no „Felhom's own" claim). Evidence: `audits/storage-identity-buildB-2026-10-15/live/14-samedisk-refusal-offer.txt`. | READY | — | Reword `err.web.meghajto_hasznalatban_formazas` (hu + en): „… nem formázható. A szabad részét használatba veheted." Next controller release; the copy gates run. | CC | | **R-1213** | Storage & devices | P4 | **Operator detail still on two household pages:** the registered drive card's `ext4 · /dev/sdb1 · Model` line (`templates/storage.html`; W14 hid only the agent drive cards), and the heading „Távoli mentés (3. mentés) — titkosított, offsite" with the English „offsite". Found by the night helper 2026-10-21 (W11/W14 follow-up). | OPEN | — | Move the line behind „Részletek"; „…titkosított, házon kívüli" | CC | -## Security & access — 20 rows (P1 2, P2 2, P3 10, P4 6) +## Security & access — 19 rows (P1 1, P2 2, P3 10, P4 6) | ID | Category | Sev | What | State | Blocked on | Next action | Owner | |---|---|---|---|---|---|---|---| @@ -239,20 +234,20 @@ stopping line that lies. | **R-1040** | Security & access | P4 | **Until the household makes Sonarr's or Radarr's first admin, any container on the box can read the app's API key.** Measured on the bench 2026-10-14 with the R-1030 seed in place: `AuthenticationRequired=Enabled`, `AuthenticationMethod=None` — `/initialize.json` from another container answers 200 with `apiKey`. Outsiders are blocked by the box's setup gate in that window; a compromised other app is not. | **OPEN** — filed 2026-10-14 | — | Seed the API key at install (`SONARR__AUTH__APIKEY`, measured to work) so the box knows it, and close the window by telling the household in the first steps; or seed a Forms user | CC | | **R-1050** | Security & access | P4 | **Raise HSTS to one year on or after 2026-11-15, if no https trouble was reported.** `09` §3 decision 249 (D2 = A, operator 2026-10-15): HSTS stays `max-age=86400` now; after a month with no https trouble it becomes one year (`31536000`); never preload, never `includeSubDomains`. The value is `HSTSMaxAgeSeconds` in `felhom-controller/controller/internal/infra/infra.go`, pinned by `TestRenderForwardedHeaders_HTTPSOnly`. „Trouble” = any report of a name that will not open, or a box answering http after the floor. | **WATCHING** — filed 2026-10-15 | the date | On or after 2026-11-15: read the register and the operator's mail for https trouble since 2026-10-15; none → a controller release with one year (test updated), bake → vouch → floor | CC | | **R-1054** | Security & access | P3 | **The hub's operator/global API key is still one bearer that can do everything on `/api/v1`, including reading every box's break-glass root password (`GET /admin/hosts/{id}/recovery-credential`).** Hub v0.152.0 gave the web surface scoped tokens (`05` §17) but tokens are refused on `/api/v1` by design. Who uses the global key today is not listed in one place. Fix: list its consumers; move each operator use to a scoped token on the web side (or a token class on the API), and keep the global key only where a box path needs it — or retire it. | OPEN — filed 2026-10-15 by the token build | — | List the global key's consumers (pod env, scripts, runbooks) | CC | -| **R-1194** | Security & access | P3 | **On a fresh box the operator's break-glass SSH door was broken from the first minute: `oob_degraded` „felhom-sshd config invalid (sshd -t fails)".** Rehearsal 2026-10-20, Tester4-816e21, mail at 12:03 UTC (one minute after the host record was created): details `active:false, config_invalid:true, felhom_sshd_port:0, operator_key_configured:false, operator_key_reported:true, reachable:false`. Possibly the shape of a customer with no operator key set (Tester4 is a test customer) — then the alarm is a false one on every such box; or a real config defect. Not diagnosed (no shell). Checked the same day: the only `oob_degraded` in the operator mailbox in 30 days, and no recovery mail followed; the report says port 0. Two candidate mechanisms in the agent (`internal/felhomsshd/health.go:63-66`): `sshd -t -f ` run by the NON-root agent fails on unreadable host keys, or a config rendered before the desired state arrived (port 0). **CAUSE FOUND AND FIXED 2026-10-21 night** (`audits/night-2026-10-21/P5-checks/`): reproduced on a fresh box from the public ISO — `oob_degraded` mailed 20:34 CEST while felhom-sshd was applied 0.4 s after the check and is healthy (port 8822 listening, `sshd -t` passes as the agent's user through its sudo grant — so the non-root theory is FALSE; without sudo it fails on the host key, which the agent never does). The first host report runs before the felhom-sshd loop's first pass and reads a config never rendered. Fix: agent `0da792e` — no OOB stanza until the first pass has run (the hub does not evaluate a missing one; a failed pass counts). `TestR1194_NoOOBStanzaBeforeTheFirstPass` red-proved. | WAITING-ON-OPERATOR — fixed on main, unreleased; ships with the agent release (D26) | the agent release (morning list 2) | Release; the next fresh install must raise no oob_degraded; then close | operator | +| **R-1194** | Security & access | P3 | **On a fresh box the operator's break-glass SSH door was broken from the first minute: `oob_degraded` „felhom-sshd config invalid (sshd -t fails)".** Rehearsal 2026-10-20, Tester4-816e21, mail at 12:03 UTC (one minute after the host record was created): details `active:false, config_invalid:true, felhom_sshd_port:0, operator_key_configured:false, operator_key_reported:true, reachable:false`. Possibly the shape of a customer with no operator key set (Tester4 is a test customer) — then the alarm is a false one on every such box; or a real config defect. Not diagnosed (no shell). Checked the same day: the only `oob_degraded` in the operator mailbox in 30 days, and no recovery mail followed; the report says port 0. Two candidate mechanisms in the agent (`internal/felhomsshd/health.go:63-66`): `sshd -t -f ` run by the NON-root agent fails on unreadable host keys, or a config rendered before the desired state arrived (port 0). **CAUSE FOUND AND FIXED 2026-10-21 night** (`audits/night-2026-10-21/P5-checks/`): reproduced on a fresh box from the public ISO — `oob_degraded` mailed 20:34 CEST while felhom-sshd was applied 0.4 s after the check and is healthy (port 8822 listening, `sshd -t` passes as the agent's user through its sudo grant — so the non-root theory is FALSE; without sudo it fails on the host key, which the agent never does). The first host report runs before the felhom-sshd loop's first pass and reads a config never rendered. Fix: agent `0da792e` — no OOB stanza until the first pass has run (the hub does not evaluate a missing one; a failed pass counts). `TestR1194_NoOOBStanzaBeforeTheFirstPass` red-proved. | WATCHING — released in agent v0.162.0 (2026-10-22, operator yes; on the 3 test boxes); the false alarm comes only on a FRESH box's first report | the next fresh install with agent ≥ 0.162.0 | At the next fresh install read the hub's events for `oob_degraded` in the first hour (none expected); then close | CC | -## Box system & updates — 14 rows (P1 1, P2 2, P3 7, P4 4) +## Box system & updates — 14 rows (P2 2, P3 8, P4 4) | ID | Category | Sev | What | State | Blocked on | Next action | Owner | |---|---|---|---|---|---|---|---| -| **R-1192** | Box system & updates | P1 | **On the minimum machine (8 GB), the household's first afternoon froze the box for about an hour: the dashboard and every app stopped answering, and only pulling the plug brought it back.** Rehearsal 2026-10-20 on a fresh box (controller 0.336.0, agent 0.161.0): the install page let the household book 8 apps to 3638 of 3712 MB (98 %) — the guest has 4096 MB in all — and told it on every page „Az alkalmazások csúcsterhelése meghaladhatja a rendelkezésre álló memóriát. **Normál használat mellett ez nem okoz problémát.**" Then the first uploads (53 PDFs to Paperless, photos to Immich, a file tree to Nextcloud — sequential per app) → from ~13:05 UTC `/api/health` gave no answer in 15 s; the VM read ~4 GB/min from its disk (158 → 476 GB) with the network still; the box's own history shows load 139–152 and no samples for 36 min; it came back at 14:00 for minutes and froze again; the plug pulled at 14:11 → dashboard in 2 min 22 s, stable after. Lost on the way: 8 Paperless documents failed (5 ordinary invoices among them), the Immich upload cut at photo 150, Nextcloud at 251 of 3 393 files. Cause NOT diagnosed (no shell in the box; memory read ~2.3 GB while load was 150 — not plain „memory full"); the one hint: the hub's `app_oom` at 13:34 — immich-machine-learning killed by its memory limit. Reproduced a SECOND time at 15:27:55 with only one Immich upload + one chunked Nextcloud upload running (~35 min, then froze again; plug pulled 16:13); per-app memory now logged every 30 s (`B4-use/memwatch.txt`). Evidence `audits/rehearsal-2026-10-20/journal.md` (12:56–14:23), `B4-use/box-metrics-after-plug.txt`, `B4-use/vm-counters-before-plug.txt`, `B4-use/after-plug-watch.txt`. | WAITING-ON-OPERATOR **DIAGNOSED 2026-10-21 with numbers, fix committed (agent `286a7e3`), proven by applying the same setting by hand** (`audits/fixes-2026-10-21/P4-freeze/`). Reproduced on demo-hp: a nested 8 GB VM, Tester4 from the public ISO, the same 8 apps, the same uploads (generator seed 20261020) → the dashboard dead 13:28:18–13:34:48 UTC. **Mechanism:** the guest's swap is capped at Proxmox's LXC default of 512 MB (the agent never set `swap`); Immich's analysis loaded its models (+1.15 GB, `immich-machine-learning` 70 → 1 224 MB) and the server grew (+0.4 GB) on top of 8 apps' 1.75 GB, so the 4096 MB guest filled (anon 3 585 MB, swap 511/512 MB) and could evict only file pages: ~360 MB left for ~25 containers' code → 150 000–2 700 000 refaults and up to 12 GB of reads per 10 s, memory „full" pressure 96 %, IO 97 %, load 162, 0 OOM kills; the host had 2.2 GB RAM and 7.4 GB swap free. **Experiment:** `pct set 9201 --swap 4096` live at 13:34:06 → „full" pressure 96 % → 1.7 % in 2 min, dashboard back 42 s later, uploads running on. **Proof (2 h, 13:43–15:43, swap = RAM by hand):** the same uploads repeated as fresh work (Paperless 110 cycles × 53 PDFs, Immich 111 new users × 306 photos, two Nextcloud trees): 720 samples, max „full" pressure 12 %, load 33, 0 limit hits, every dashboard probe answered (slowest 1.26 s). Controller 0.337.0: the false „Normál használat mellett ez nem okoz problémát." replaced. Nextcloud's small-file WebDAV upload ran ~17 files/min under this load — slow, not lost. **NIGHT SOAK 2026-10-21→22 (fresh box from the public ISO, the agent fix as a by-hand fixture, `audits/night-2026-10-21/P1-soak/`):** 2 h of the rehearsal uploads, then the night chain untouched — 3 389 probes, none failed, largest interval between answers 16 s, slowest 4.1 s; 0 OOM kills; every night job ran (dump, second drive, off-site 8 apps, sweep, proof, integrity). Memory „full" pressure went above 20 % twice: one 10-s sample at the Immich model load (31/35 %) and ~3 min in the 03:30 second-drive job (39/45 %) — R-1214. 1 photo of ~26 000 not stored (a 10-min hang at low pressure) — R-1215. The freeze did not come back. | the operator's agent release + vouch | Release agent with the swap fix (swap = RAM at bring-up, at RAM resize, once at start); after the update read one box's `pct config` (swap = memory) and its `guest-swap: raised` log line; then close | operator | | **R-984** | Box system & updates | P4 | **Host and agent hardening, low risk each: the backup-target route has no role check; the unsigned guest spec has no size bounds; signed ops have no maximum validity; the guarded mkfs does not refuse LVs, zvols or RAID devices; the local API is reachable from the LAN by a static route; a sudoers inspect pattern is wider than needed; install passes secrets on the command line; guest settings files are world-readable; the host offers rpcbind and DNS on the LAN.** Fix each in its own small change. Security review 2026-10-12 (`audits/security-review-2026-10-12/`); detail held off-git for the operator (`/mnt/5_hdd/felhom.eu/evidence/security-review-2026-10-12-PRIVATE/`). | OPEN | — | Batch into hardening work | CC | | **R-982** | Box system & updates | P3 | **The Proxmox host accepts root password login over SSH from the LAN (measured on demo-hp), so anyone on the household network can try the root password.** Design-shaped: the break-glass password exists for the console. Fix: key-only SSH for root; the password stays for the console. Evidence: `audits/security-review-2026-10-12/evidence/demo-hp-host-reads.txt`. | OPEN — design-proposal | — | Decide; then set it in the installer and the config bundle | CC | | **R-979** | Box system & updates | P3 | **Controller updates are trusted by registry tag alone (no digest, no signature), and the Update button offers any newer tag, even an unvouched one; the built-in traefik, cloudflared and FileBrowser images are also pinned by tag only.** Whoever can push to the registry decides what runs. Fix: pin by digest from the hub's vouched list; offer only vouched versions. Security review 2026-10-12 (`audits/security-review-2026-10-12/`); detail held off-git for the operator (`/mnt/5_hdd/felhom.eu/evidence/security-review-2026-10-12-PRIVATE/`). | OPEN — design-proposal | — | Design note, then build | CC | | **R-974** | Box system & updates | P3 | **A compromised host agent can likely become root on the host through the root wrapper that applies PBS settings: the wrapper accepts a folder path inside the agent's own writable tree and then acts on it as root.** Static (the symlink behaviour was reasoned, not run). Same class as R-861. Fix: a fixed root-owned folder, and refuse symlinks before any root action. Security review 2026-10-12 (`audits/security-review-2026-10-12/`); detail held off-git for the operator (`/mnt/5_hdd/felhom.eu/evidence/security-review-2026-10-12-PRIVATE/`). | OPEN | — | Fix the wrapper with a test on a throwaway box | CC | | **R-972** | Box system & updates | P2 | **The shipped controller and hub programs are built with Go 1.24.13 and golang.org/x/crypto v0.31.0, and the agent with Go 1.26.0, so dozens of fixed Go security bugs (including html/template escaping fixes) are still in what runs on boxes and the hub.** Go 1.24 has had no security fixes since Go 1.26 was released (Go supports the two newest major releases: https://go.dev/doc/devel/release#policy); the scanners name fixes in Go 1.26.9 and 1.27.2. Also: the controller image's Debian 12 base has 12 fixable critical packages, and the Samba image has 48 fixable high ones. Fix: build all three on a supported, patched Go; update x/crypto; rebuild the base images. Scanner output: `audits/security-review-2026-10-12/scanners/`. | **NARROWED** 2026-10-16 (burndown 2): **controller v0.322.0 released** on Go 1.27.2 + x/crypto v0.58.0, runtime debian:12.13-slim + `apt-get upgrade` (Debian 13 deliberately not: restic 0.18, R-1105) — scanner: critical 16 → 4, fixable criticals and highs in the OS 0; govulncheck 62 → 1 (module-level, `openpgp` not linked). **Hub v0.156.0 deployed** 2026-10-16 19:26 on the operator's yes (Go 1.27.2, alpine 3.24.2: 0 critical, 0 high); Synced/Healthy, reports from all three boxes after the start, the floor reads 0.322.0. **Agent: Go 1.27.2 committed (`37b99d7`), tested, NOT released** — the next vouched agent release carries it. Open: the Samba image (48 fixable high, not rebuilt); docker-compose plugin's own Go (4 high, upstream). Evidence `audits/burndown2-2026-10-16/P4/` **2026-10-16 (evening): the Samba part is DONE in controller v0.323.0** — felhom-samba 1.2.0 on Alpine 3.24.2 (0 critical / 0 high, was 48 fixable high), proven on demo-hp with the same household password (smbclient, nmbd, mDNS, WS-Discovery); on the three test boxes now, on every box with the global floor (R-1105's night check). The controller's Debian 13 OS part: 1 critical / 70 high, none fixable. Left: docker-compose plugin's own Go (4 high, upstream); the agent release; restic's binary is R-1107. **2026-10-17 (evening): agent v0.159.1 (Go 1.27.2) RELEASED and running on demo-hp, Tester 1 and demo-felhom** (signed jobs on the operator's yes); waiting for the operator's vouch — then only the upstream compose plugin is left (close then, recorded). | the next vouched agent release | Close when the global floor carries v0.323.0 and the next vouched agent release carries Go 1.27.2 (compose plugin: upstream, recorded) | CC | -| **R-1207** | Box system & updates | P2 | **A host with no (or too little) swap gets nothing from the guest swap fix (R-1192), and the agent never adds host swap.** The fix lets a guest swap as much as its RAM; that swap lives on the HOST. Measured 2026-10-21 night: our installer gives an 8 GB / 256 GB machine 7.75 GB of host swap (LVM `pve/swap`), so the installer's boxes are covered; a BYO host (or one with swap turned off) may have none. Now reported and said (agent `0da792e`: `host_swap_mb` / `guest_swap_mb`, one WARN; hub 0.164.0 `host_swap_short` to the operator; the install page sentence) — but nothing adds swap. The no-swap test on the soak VM (`audits/night-2026-10-21/P2-noswap/`) says what happens without it. | WAITING-ON-OPERATOR **NO-SWAP TEST 2026-10-22 04:08–04:38 UTC (`audits/night-2026-10-21/P2-noswap/`):** the soak box, `swapoff -a` on the host, the same burst → the freeze CAME BACK within 20 s: `/api/health` dead for 289 s, then 172 s and 68 s (24 of 125 probes failed), memory „full" 36 % host / 47 % guest, the VM reading ~40 GB per 25 s from disk; Immich lost 207 of 306 photos and its stream broke; the box recovered only when the Immich stream stopped (04:23). After `swapon -a`: 0 failed probes, „full" ≤ 1.3 %. The agent logged its one WARN at the swapoff (host 938 MB < guests 4096 MB). | decision: should the agent (or the installer for BYO) create host swap when it is short, or should an 8 GB BYO host without swap be refused at install? | Operator decides; CC builds the pick | operator | +| **R-1207** | Box system & updates | P2 | **A host with no (or too little) swap gets nothing from the guest swap fix (R-1192), and the agent never adds host swap.** The fix lets a guest swap as much as its RAM; that swap lives on the HOST. Measured 2026-10-21 night: our installer gives an 8 GB / 256 GB machine 7.75 GB of host swap (LVM `pve/swap`), so the installer's boxes are covered; a BYO host (or one with swap turned off) may have none. Now reported and said (agent `0da792e`: `host_swap_mb` / `guest_swap_mb`, one WARN; hub 0.164.0 `host_swap_short` to the operator; the install page sentence) — but nothing adds swap. The no-swap test on the soak VM (`audits/night-2026-10-21/P2-noswap/`) says what happens without it. | WAITING-ON-OPERATOR **NO-SWAP TEST 2026-10-22 04:08–04:38 UTC (`audits/night-2026-10-21/P2-noswap/`):** the soak box, `swapoff -a` on the host, the same burst → the freeze CAME BACK within 20 s: `/api/health` dead for 289 s, then 172 s and 68 s (24 of 125 probes failed), memory „full" 36 % host / 47 % guest, the VM reading ~40 GB per 25 s from disk; Immich lost 207 of 306 photos and its stream broke; the box recovered only when the Immich stream stopped (04:23). After `swapon -a`: 0 failed probes, „full" ≤ 1.3 %. The agent logged its one WARN at the swapoff (host 938 MB < guests 4096 MB). **Operator answer 2026-10-22: Tester 2's laptop was installed with OUR installer** — so it has host swap (the installer gives ≈ RAM up to 8 GB) and the swap fix helps it once its agent is ≥ 0.162.0. The decision for BYO hosts stays open. | decision: should the agent (or the installer for BYO) create host swap when it is short, or should an 8 GB BYO host without swap be refused at install? | Operator decides; CC builds the pick | operator | | **R-1214** | Box system & updates | P3 | **On the 8 GB box with the swap fix, the night's second-drive backup still pushes memory „full" pressure above 20 % for about 3 minutes; the box keeps answering.** Night soak 2026-10-21→22 (`audits/night-2026-10-21/P1-soak/03-rec.jsonl`, 10-s samples; fresh box from the public ISO, agent with swap = RAM, 8 apps, the rehearsal uploads for 2 h): at 01:30–01:34 UTC (the 03:30 tier2 job) host 39 % / guest 45 % over 10 s, over 60 s at most 20 % / 25 %; IO „full" 66 %; guest swap 1.35 → 2.1 GB; `/api/health` answered every probe (slowest 4.1 s, largest interval 16 s); 0 OOM kills. Once more in the upload window (Immich loading its models, 31 % / 35 % for one sample). The brief's soak pass line was „full" < 20 %, so the soak missed that one line; the freeze itself (96 % for an hour, R-1192) did not come back. Not diagnosed: which part of the tier2 job (the copy's page cache, the volume dumps) causes it. | OPEN | — | Measure the tier2 job alone on the 8 GB box (per-step pressure); decide whether 20 % over 10 s is the right line, or limit the copy (ionice / cgroup IO weight) | CC | +| **R-1216** | Box system & updates | P3 | **The host-swap check is too strict for a guest larger than the installer's 8 GB host swap: on demo-hp and demo-felhom the agent warned and the hub mailed the operator `host_swap_short` within minutes of agent 0.162.0, and the controller's install page will tell such a household „nincs elég cserehely… Szólj a Felhomnak” when memory is tight.** Measured 2026-10-22 (`audits/morning-2026-10-22/release/04-agent-delivery.txt`, hub events 07:57:07 UTC): demo-hp host swap 8191 MB vs guests' swap 25898 MB; demo-felhom 8191 vs 12288; Tester 1 (8 GB machine) 7871 vs 4096 — fine. The check compares the host's swap with the guests' WHOLE swap allowance (swap = RAM since R-1192); Proxmox's installer gives host swap = RAM capped at 8 GB, so every machine above ~10 GB RAM with a big guest trips it. The soak's burst used at most 2.7 GB of host swap (8 GB machine, 4 GB guest). Three places compare the same two numbers: agent (WARN), hub (`host_swap_short`, operator-only), controller (install-page sentence). | OPEN | the operator's pick: (A) „short" = host swap below min(guests' swap, 8 GB) − 10 %, i.e. below what the installer itself gives — agent, hub and controller patch releases; or (B) keep the strict check and accept the operator mail for big boxes, the page sentence only when memory is tight | Operator picks A or B; CC builds A in the three repos with a test each (a 16 GB host with 8 GB swap and a 12 GB guest is NOT short; 938 MB is) | CC | | **R-862** | Box system & updates | P3 | **Tester 2 cannot take the config bundle until one by-hand bootstrap is done: its `felhom-os-apply` (agent 0.142.0) predates the bundle mode, and no signed job can write a root file on it.** FOUND 2026-10-04 (R-840 build, Part C): the route reaches every box installed from installer 1.31.0 on, and the demo boxes (bootstrapped by CC); Tester 2 has every root file of agent 0.142.0 (installer 1.30.0) and lacks only the R-858 wrapper fix, which matters only for a Docker step it gets solely from a signed job. CC has no route to Tester 2 (its door admits only the operator's WireGuard peer; `felhom-op` cannot become root). The steps: `runbooks/config-bundle.md` "Tester 2". Then CC signs the bundle and reads it back. | **WAITING-ON-OPERATOR** — the operator said (2026-10-04 ~19:05) he will try through his tunnel **2026-10-07 07:58 (`09` §3 decision 170): the operator believes Tester 2 never set up the off-site backup (no escrow); the laptop may stay off for days; the tester plans to add an HDD.** **2026-10-07 (Part H, read only):** in Tester 2's last 10 notifications (2026-10-05 09:16 → 2026-10-07 06:58) the household got 0 mails, the operator 10 (host_down ×9, expected_dbdump_missed ×1); control: the household channel shows on the other three customers. So the household is not mailed daily while the box is off; no row (`audits/day-2026-10-07/H/`). | the operator's WireGuard tunnel | the operator runs the three bootstrap commands; CC sends the bundle | operator | | **R-78** | Box system & updates | P3 | **`local_api` authority ruling — auto-reconcile vs detect-only** **MIGRATED FROM `ROADMAP.md` 2026-08-22 (R-369) — originally filed 2026-07-25, size M, roadmap state `idea (deferred OUT of R-77 on purpose)`.** Moved verbatim; nothing added or reinterpreted. The roadmap keeps its copy as history, marked moved. **An OWED OPERATOR DECISION, not a defect — moved because an owed ruling hidden among feature ideas is the shape this session exists to remove.** | **OPEN — migrated from ROADMAP 2026-08-22, rank unchanged** | — | R-77 ships detection because the fix is genuinely undecided, and **both directions can lose customer-visible function**. **Direction 1 (today):** `controller.yaml` wins and drift is silent → the 2026-07-25 island migration blinded the whole fleet's control plane for 17.5 h (drive gate, guest-reboot recovery, quiesce/backup all degrade). R-77 makes that loud but does not stop it recurring. **Direction 2 (`bootstrap.json` wins, auto-reconcile on boot):** a guest whose `controller.yaml` is CORRECT and whose `bootstrap.json` is stale — a half-completed re-provision, a hand-repaired guest, a setup-wizard box — gets a **working channel clobbered on the next restart**, fleet-wide and silently, during a routine deploy. That is not obviously better than the bug. Needs a spike: which writer is authoritative per field (endpoint vs fingerprint vs token — `mergeLocalAPI` replaces the whole block, so they cannot be reconciled independently today), whether the agent side should stamp a generation/mtime so 'newer wins' is even expressible, and whether reconcile should require an operator ack. Until then the drift alert plus a manual edit is the supported path. | CC | | **R-468** | Box system & updates | P3 | **[P3-LOW] THE GOLDEN WAIVER — goldens on a cadence, not per release (operator ruling 2026-09-13).** 25 goldens in 26 days in August, almost one per release, because `golden_currency_gate.py` trips on every release by design and the only honest ways past it were a bake or a declared `--no-verify` (thirteen by 2026-09-01, R-404/R-417). **The ruling: bake WEEKLY, and always before any drill or fresh install.** Every release still raises the FLOOR, so both demo boxes keep getting each release in ~20 s; only the golden — which protects a fresh install and nothing else — moves to a cadence. **The mechanism (built 2026-09-13):** `documentation/tests/golden-waiver. **⚠ CORRECTED THE SAME DAY (R-472): between bakes the floor does NOT carry a release — the hub holds any floor above the vouched golden (publish-train rule 1), so releases between bakes reach the demo boxes only by hand-deploy.**yml`, four lines (`issued`, `expires`, `reason`, `register_row: R-468`), read by the gate. While valid, a golden BEHIND the record makes the gate print a loud ADVISORY and exit 0; when it expires the gate is red again until someone bakes or renews. **The 14-day cap is enforced by the gate, not the runbook** — a longer, undated, unparseable, reason-less or row-less waiver is INCONCLUSIVE (exit 2), never 0 and never silently ignored. **It never covers a golden that is UNRECORDED (R-385)** — that is not a cadence choice. **A dated waiver cannot be forgotten; it just expires** — the difference from R-242's original rule, which recurred the day after it was written. Tests: `scripts/test_golden_currency_gate.py` cases 5–15 (E/F/G/H, a 15-day, absent, unparseable, bad-row and empty-reason waiver each 2; the R-421 decoy — a file saying only `expires` — 2). **This is a PRE-CUSTOMER arrangement: the first external install retires it** (delete the file in that commit). Cadence written into `RUNBOOK-manual-build.md` §4.2 and the `felhom.eu` end-of-session checklist. **Does NOT touch R-242's open half (nothing gates the VOUCH).** **2026-10-15 (`09` §3 decision 250, operator):** the cadence is now the RULE, not a waiver — a controller release needs no golden (the floor carries it), the golden is baked every Sunday night when the floor is above it (`runbooks/nightly-rotation.md`), and `golden_currency_gate.py` convicts only a golden MORE THAN 7 DAYS old while a release is ahead (CASE 18–21, red-proved). The waiver file stays as a dated exception for a missed Sunday. | **WATCHING** — the weekly bake is a night-routine step; the first external install still retires the waiver arrangement | — | — | CC | @@ -261,13 +256,12 @@ stopping line that lies. | **R-1061** | Box system & updates | P4 | **A per-customer floor reached Tester 1 only at its next 15-minute report, not in seconds.** Set 2026-10-15 12:55:51 UTC for tester-1, demo-hp and demo-felhom together (hub 0.153.0, CC's token): demo-hp and demo-felhom ran 0.314.0 within 13 s (the hub's wake); Tester 1 moved at 13:09:35, its regular report (`audits/gate-restore-2026-10-15/release/03-boxes-move.txt`). It had restarted at 12:54:29 onto rc.1 and logged „hub wait channel active". Why the wake did not reach it is not read (the wake line is DEBUG). No harm: the floor arrived. | **OPEN** — filed 2026-10-15 | — | Read Tester 1's DEBUG ring at the next floor change; compare with the hub's bump log | CC | -## Monitoring & notifications — 14 rows (P2 2, P3 9, P4 3) +## Monitoring & notifications — 14 rows (P2 1, P3 10, P4 3) | ID | Category | Sev | What | State | Blocked on | Next action | Owner | |---|---|---|---|---|---|---|---| | **R-1020** | Monitoring & notifications | P4 | **`app_repaired_after_crash` reports a duration of 0 s, and the controller log says „in 0s".** `RunAfterUncleanBoot` sets `res.Duration` in a deferred func after the result is already returned (no named result), so the caller sees 0; the `app.yaml` record is right (10,172 ms on demo-hp 2026-10-14, `audits/immich-repair-2026-10-14/D/`). Small, but the controller release for this session is spent (v0.311.0). | **OPEN** — filed 2026-10-14 | — | CC: a named result (or set the duration before return), with a test on the returned value; ride the next controller release | CC | | **R-528** | Monitoring & notifications | P2 | **[P2-MEDIUM] Docker does not report an OOM kill inside a Felhom LXC guest: `OOMKilled` stays false and no `oom` event fires, so the v0.243.0 OOM line is not proven live.** MEASURED 2026-09-15 on scratch 9202 (Docker 29.8.0): Paperless capped at 128M restarted 11 times with `OOMKilled=false` and zero `docker events --filter event=oom`; a memory hog inside the running container was killed (rc 137) with the same silence (`E2-oom-signal-measure-9202.txt`). BIGNIGHT VM 333 did read `oomkilled=true`, so the shape differs by case. **Fix shape:** the agent reads the guest container cgroups' `memory.events oom_kill` counters (host-side, reliable), or the controller alarms on a restart-count trend **RE-MEASURED 2026-09-16 on the DRILL box (fresh install, nested VM 334, Docker in an LXC guest, controller 0.243.0), so the finding is not a property of one machine:** the Paperless webserver was capped at 128 M with `docker update --memory`; it restarted 9-10 times, and all three signals stayed silent - `OOMKilled=false` on every inspect, `docker events --filter event=oom` EMPTY for the whole window, the container's cgroup not visible from inside the guest, and `dmesg` unreadable there. Identical to scratch 9202. So the v0.243.0 OOM line cannot fire on ANY Felhom box as shipped, on either host. Evidence: `audits/evidence-drill-0243-2026-09-16/phase2-m1-oom.txt`. | **WATCHING** — **2026-10-12: the built part is released** (agent v0.150.0 carries the Docker-approval memory-kill check; the boxes run 0.154.0; hub 0.140.0+ requires a passing `oom_check` before a Docker set is approved). Per decision 157 nothing else is built; the row watches for a box whose Docker reports a false OOM flag. Dated look: 2026-11-12. **READY — rank P2-MEDIUM; owner: CC** **2026-09-17 (chaos night): an OOM WAS detected on a fresh box, and named precisely.** On `tester-1-022354` (controller 0.245.0, guest 9201, 6 GB RAM) immich’s Postgres was killed by the memory limit during its reverse-geocoding import, and the controller pushed `app_oom` (warning, operator-only): „Alkalmazás memóriája elfogyott: immich (immich-postgres) — egy folyamatát a memóriakorlát leállította” — naming the app AND the exact container. The visible consequence was `write CONNECTION_CLOSED immich-postgres:5432` and twelve restarts of immich-server. So on THIS box the OOM scan works and was the fastest route to the diagnosis; recorded here rather than filed as a new row. Evidence: `audits/evidence-chaos-night-2026-09-17/round-2.txt`. **2026-10-05 (burn-down night): a one-page design proposal (no code) is in `audits/night-burndown-2026-10-05/design-R-528.md`** — for the operator. **2026-10-06: STOPPED BEFORE ANY CODE — the measurement contradicted the design** (decision 155 said A then C). On scratch 9202, Docker 29.8.2, the `OOMKilled` flag was TRUE in all four shapes tried: a child process killed while the container kept running (`oom_kill` 0 → 3, flag true) and three main-process kills (exit 137, flag true); an `oom` event each time. The false flags of 2026-09-15 were on Docker 29.8.0. Cost read for the record: one exec read of 21 containers on demo-hp = 1.6 s. `audits/design-build-2026-10-06/`C/. **2026-10-06 18:24: operator ruling, option A (decision 157):** nothing is built; the row stays open as a WATCH for a box whose Docker reports a false flag. **Added:** a Docker engine set may not be approved until it reports a memory kill correctly on the boxes that ran it (built in this row's next session). **2026-10-06 (night): the Docker-approval memory-kill check is BUILT** — hub v0.140.0 (LIVE: the approval waits for a passing `oom_check` on every ring-0 box; a failed, errored or missing one blocks) and the agent's wrapper (`felhom-agent` `acccb66`, unreleased — ships as v0.150.0 after the 2026-10-07 read-back). Proven by hand on demo-hp's guest: `OOMKilled=true`, exit 137, the `oom` event — seen only with an events window ending after the run (the wrapper waits 2 s). `audits/readback-2026-10-07/`F/. | — | 2026-11-12: read the hub for any failed `oom_check` or an `app_oom` with no restart reason since 2026-10-12; none → close | CC | -| **R-1199** | Monitoring & notifications | P2 | **The household's notification page shows disk-warning, drive-disconnected and backup-failed mails switched ON, but on the rehearsal day only the OPERATOR got them — the household's mailbox received one alarm (a failed off-site run) out of nine.** Rehearsal 2026-10-20, read from the Gmail catch-all (the second channel): to `tester4@` only the setup code and „A biztonsági mentés sikertelen!" (17:01); to `admin@` also `disk_warning` 89 % (18:36 — the box logged „notifying the customer"), `storage_disconnected` ×2, `storage_reconnected` ×2, `backup_run_failures` (3 of 8 apps), `app_oom`, `host/node_stale`. The box's page (`/settings/notifications`) has `event_disk_warning`, `event_storage_disconnected`, `event_backup_failed`, `event_crossdrive_failed` … ticked; the hub sends household mail only by ITS OWN stored prefs (`hub/internal/notify/dispatcher.go` `processCustomer`: `isEventEnabled(prefs.EnabledEvents, …)`) — whether the two lists disagree is not read (the token cannot read the customer record). Evidence `audits/rehearsal-2026-10-20/B6-failures/notifications-defaults.txt`, `journal.md`. | VERIFY | an operator read of Tester4's hub notification prefs and notification log | Compare the hub's `notification_prefs` / `notification_log` for Tester4 with the box's page; if they differ, make one the source of truth | CC | | **R-1193** | Monitoring & notifications | P3 | **When the box froze (R-1192), the operator heard only „no report for 45 m" — 28 minutes in — and the household heard nothing at all.** Measured 2026-10-20 against the operator mailbox (the second channel): the freeze began ~13:05 UTC; the hub page read ONLINE / OK at 13:22 (correct inside the 45-minute threshold, R-549); `host_stale` at 13:33, `app_oom` at 13:34 (immich-machine-learning killed by its memory limit), `host_crash_restart` at 14:26 and 16:29 (the two plug pulls), `node_stale` 15:59 / `node_recovered` 16:03. No mail or banner tells the household that its box is not answering, and no operator mail says „the box answers ping but not its dashboard". CORRECTED the same day: the first version of this row said the hub showed OK „throughout" and „nobody was told" — that read only the hub page, not the mailbox. Evidence `audits/rehearsal-2026-10-20/journal.md`. | OPEN | — | Design note (2026-10-21, after R-1192's diagnosis): the freeze's signature is cheap to see from the HOST side — the guest cgroup's memory PSI „full" above ~50 % for a minute, or its `memory.events max` climbing, while the host still reports; the agent could raise `guest_memory_thrash` (operator mail in its own words, not „no report for 45 m") and the household banner „A dobozod most nagyon lassú…". With the swap fix (R-1192) the measured thrash ends within a minute, so this alarm should be built only if a freeze is seen again after the agent release; until then it stays a design. Decide whether a dashboard that does not answer for N minutes while the host still reports should alarm sooner and in its own words (guest-side liveness), and whether the household is told | CC | | **R-1202** | Monitoring & notifications | P3 | **A box whose clock is behind blames the hub and stops an app without telling anyone.** Rehearsal 2026-10-20 B6 #8: RTC set 2 years back (the OS raised it to 2026-04-13): the dashboard shows only „Hub nem elérhető" while the log says „x509: certificate … not yet valid: current time 2026-04-13…"; Paperless crash-looped and the box stopped it with a restore hold; the `app_stopped_unhealthy` event failed (hub unreachable), so neither the household nor the operator heard. After the real time came back the app stayed stopped until a Start (clear sentence, 1 min). | **OPEN** | — | say „the box's clock is wrong (it says )" when TLS fails with not-yet-valid/expired against a hub that answers; keep the stop event queued until the hub is reachable | CC | | **R-340** | Monitoring & notifications | P3 | **The new reachability check does not touch the surface that actually failed.** R-339 reports when the hub cannot READ ep0 — but the read it performs is the `usage` op, which is `proxmox-backup-manager` plus `df` over SSH, and therefore rides the **local API daemon**. The 2026-08-18 incident explicitly CLEARED that daemon: `proxmox-backup.service` was healthy throughout, and it was the **HTTPS proxy on 8007** that was wedged with a full accept queue. **So R-339's check would have returned green for all 9 h 37 m of that outage.** It closes the case where ep0 is unreachable *as a host*; it does not close the case that actually happened. This is not a defect in R-339 — it is the honest boundary of what it watches, recorded so a future reader does not mistake a green box gauge for a working off-site tier | **READY (M) — NEW 2026-08-18** | a tenantsync endpoint-script version bump (the op is added on ep0, so it needs the same version-gated rollout `ErrUsageUnsupported` already models) | Add a **health op** to `scripts/felhom-tenantsync.sh` that probes `https://127.0.0.1:8007/` on ep0 and reports the proxy's fd count and listen-queue depth, then surface it as a third signal. **Overlaps the connections spike (R-336's remaining half): both want the same observations from ep0, so whichever runs SECOND must reuse the first's evidence rather than re-measuring a protected machine twice** **REUSE, per this row's own instruction — the connections spike ran FIRST (2026-08-20) and already produced most of what the health op wants; do not re-measure a protected machine a third time.** Available in `audits/evidence-ep0-established-connections-2026-08-20/`: the proxy **fd count** and its type breakdown (`lsof` + `/proc//fd`), the **listen-queue depth** (`ss -lnt` — `Recv-Q 0`, `Send-Q 1024`), the **ESTAB/CLOSE-WAIT split**, the **per-peer** connection histogram, a **31-minute persistence diff** of full 4-tuples, and a **46.18 h** slope with Poisson bounds. What the health op would still add beyond these: a loopback `GET https://127.0.0.1:8007/` probe — the observation that distinguished "process problem" from "network problem" on 2026-08-18 and the one thing this spike did NOT take, because it is the surface R-339 cannot see. **And this spike sharpens what the op should report:** a rising **ESTAB** count is the live signal (CLOSE-WAIT was **0**, not merely flat), and per **R-344** the fd ceiling that matters may be the **agent's**, not only ep0's. | CC | diff --git a/documentation/backlog/STATUS-HISTORY.md b/documentation/backlog/STATUS-HISTORY.md index 5567269f..5240de3a 100644 --- a/documentation/backlog/STATUS-HISTORY.md +++ b/documentation/backlog/STATUS-HISTORY.md @@ -7,6 +7,8 @@ Moved here byte for byte on 2026-10-14 (night session), newest first, so that `S ## Moved from STATUS on 2026-10-22 +**Updated 2026-10-22 (morning, after the night run).** A failed or cut restore now puts the data back and starts the app (proven on the scratch box); clearer first-hour texts; a host short of swap is reported. Built and tested, nothing released. + **Updated 2026-10-21 (evening).** A rebuilt box now gets the household's off-site backups back (hub 0.163.0, proven live: 3 031 files byte-identical), and shared folders, imported apps and away drives keep their copies and locks (controller 0.337.0, the floor). The 8 GB freeze is explained — the guest's swap was capped at 512 MB — and the agent fix is ready but not released. Report: `REPORT-fixes-2026-10-21.md`. ## Moved from STATUS on 2026-10-21 diff --git a/documentation/runbooks/iso-release-gate.md b/documentation/runbooks/iso-release-gate.md index d8604aa9..12e12bec 100644 --- a/documentation/runbooks/iso-release-gate.md +++ b/documentation/runbooks/iso-release-gate.md @@ -327,4 +327,4 @@ release report. A criterion with no recorded observation is a criterion that was **The ONE home for a release's record is `documentation/tests/iso-release--/`** (R-588, 2026-10-05) — one directory per published ISO, so „was the gate run for this image?" is answered by looking, not by a full-text search for a checksum. A record made elsewhere (inside an audit) gets a directory here -whose `README.md` points at it. Today: 1.27.0, 1.27.1, 1.28.0 (pointer), 1.29.0. +whose `README.md` points at it. Today: 1.27.0, 1.27.1, 1.28.0 (pointer), 1.29.0, 1.30.0. diff --git a/documentation/tests/iso-release-1.30.0-2026-10-22/README.md b/documentation/tests/iso-release-1.30.0-2026-10-22/README.md new file mode 100644 index 00000000..e498befe --- /dev/null +++ b/documentation/tests/iso-release-1.30.0-2026-10-22/README.md @@ -0,0 +1,67 @@ +# ISO release 1.30.0 — PUBLISHED 2026-10-22 (W1 boot text, W7 the bound banner clears the screen) + +| | | +|---|---| +| file | `felhom-installer-1.30.0-pve9.2-1.iso` | +| sha256 | `590d7b9b3ccbc7644536a1971a44deb2d1bf7136f69eae2b4dc42961e74d5cc1` | +| size | 1 705 324 544 bytes | +| base | Proxmox VE 9.2-1 (`4e88fe41…c2c6c`) | +| source | felhom.eu `115f15c8` (clean and pushed; the build's own clean-tree gate) — W1/W7 from `2fa5b8f3`, the version bump `6d5a7f1b` | +| published | `https://iso.felhom.eu/felhom-installer-1.30.0-pve9.2-1.iso` (+ `.sha256`, `.manifest.txt`) | +| rollback | `felhom-installer-1.29.0-pve9.2-1.iso` (sha `dceacae5…`) stays online (HTTP 200 after the publish); rolling back is one edit on the two download pages | +| decided by | the operator's yes, 2026-10-22 morning („Publish items — Yes, all") | + +**What changed (felhom.eu R-1210, the rehearsal's first-hour words):** +- **W1** — the graphical entry's boot line is in the te-form: „A Felhom telepítése indul — válaszd ki a lemezt a + telepítőben..." (was „válassza ki"). Seen on the screen: `w1-boot-text.png`. +- **W7** — when the box is linked, the bound banner first clears the screen AND its scroll-back + (`\033[3J\033[H\033[2J`), so the spent pairing code is not left readable. Pinned by + `scripts/iso/test/test_bound_banner_clears.py` (with a decoy); **not seen live** — the bound banner shows only after a + bind, and the proof installs were not bound (no customer was made for them). + +## The criteria, each with its observed value (run on the exact file that was uploaded) + +`static-gate.txt` holds the raw output of every static check below. + +| | verdict | observed | +|---|---|---| +| G1 no `answer.toml` | **PASS** | root-level `answer.toml` / `auto-installer-mode.toml` → 0 | +| G2 no root password | **PASS** | `root-password`, `$6$`, `$y$`, `$2[aby]$` across every added path + the extracted package → 0; the build said `root-pw: NONE`, no `.rootpw.txt` in the publish source | +| G3 no SSH key | **PASS** | `root-ssh-keys`, `ssh-rsa`, `ssh-ed25519`, `ssh-dss` → 0 | +| G4 no customer identity | **PASS** | two hits, both variables: `Bearer $token` (line 534) and a `*FELHOM_RETRIEVAL_PASSPHRASE=*` pattern test (line 553) | +| G5 enumeration | **PASS** | added vs stock: `/boot/grub/felhomtheme/` (2 files) and `/proxmox/packages/felhom-bootstrap_1.30.0_all.deb`; removed: `/boot/grub/pvetheme/` — the same set as 1.29.0. PEM headers, `token=`/`password=`/`passphrase=`/`api_key=` with ≥ 12-char values → 0 | +| G6 boot menu | **PASS** | 2 menuentries, `timeout=15`, `timeout_style=menu`, `default=0`; `proxdebug`/`Rescue Boot`/`memtest`/`fwsetup` → 0 | +| G7 package | **PASS** | one `felhom-bootstrap 1.30.0`, no `Depends`; `dpkg-query` on both installs: `install ok installed` | +| G8 postinst | **PASS** | `systemctl start/daemon-reload/restart` → 1 and `set -e` → 1 are both the postinst's own header COMMENTS (lines 10–11, „NO `set -e`", „NO systemctl start") — no command; no curl/wget/apt/nc/ping; last line `exit 0`. Unchanged since 1.29.0 (`eb1ae370`) | +| G9 payload = repo HEAD | **PASS** | `felhom-bootstrap.sh` `8dbb173d…36adfb` and the unit `cf2e4678…a69af3` — extracted = repo, `cmp` IDENTICAL; the installed copy on both boxes has the same sha | +| G10 committed | **PASS** | the build's clean-tree gate (HEAD = origin/main, no untracked file); the manifest names the commit | +| G11 checksum + round trip | **PASS** | downloaded from `iso.felhom.eu`: 1 705 324 544 B, sha256 `590d7b9b…74d5cc1` = the built file = the published `.sha256` (both side files HTTP 200) | +| G12 bucket private | **NOT RE-READ** | nothing in this release touches the bucket; the token is object-scoped and cannot read the bucket's setting | +| G13 directories | **PASS** | `./etc/felhom/`, `./usr/local/sbin/`, `./lib/systemd/system/` in the package | +| G14 a person chooses the disk | **PASS** | `filter.` in the added text → 0; observed on BOTH entries: graphical `Target Harddisk /dev/sda (32.00GiB, QEMU HARDDISK)` with a selector (`gfx-disk.png`), text `Target harddisk: < /dev/sda (QEMU HARDDISK) (32.00 GiB) >` (`tui-disk.png`); both summaries show the disk before erasing | +| G15 console after first boot AND one reboot | **PASS** | both installs, both boots: `grep -c 8006 /etc/issue` → **0**; `Felhom otthoni szerver` → 1; `Felhom home server` → 1; `pvebanner.service` → **masked** (`checks-*.txt`); the text install's screen after the reboot is pixel-identical to the first boot | +| G16 Hungarian first, secrets once | **PASS** | `python3 scripts/iso_bootstrap_gate.py` → 73 harness checks green, its decoy convicted; `jelszavad` 0, `Tulajdonosi jelmondat` 1, `Owner passphrase` 1, negative control `zzqx-not-there` 0 | + +**The runbook's G16 command was stale** and is corrected in the same session: it mounted `scripts/iso` as `/work`, where +`golden/` and `postinst` do not sit, so 10 checks failed on a correct tree (the same 10 failed on the commit before W7). +`scripts/iso_bootstrap_gate.py` stages the inputs and is now the named command. + +## The proof installs — BOTH menu entries, on the built file (sha checked on demo-hp before boot) + +Nested VMs on demo-hp, 4 GiB RAM, 32 GB disk on `nvme-scratch`, the Hungarian keyboard kept, destroyed afterwards. + +| | entry | VM | result | +|---|---|---|---| +| 1 | `Felhom telepítés / Install Felhom` (graphical) | 9341 | installed, first boot + one reboot: package installed, unit `enabled` and fired on both boots, a pairing code in `/etc/felhom/appliance-pairing-code`, all G15 checks | +| 2 | `Felhom telepítés (szöveges mód) / text` | 9342 | the same, all pass | + +The installer gave each 4 GB machine a 3.8 GB host swap (`SwapTotal` 4 005 884 kB) — the installer's swap = RAM rule +the swap fix relies on (felhom.eu R-1192, R-1207). Pairing codes are blanked in the committed screendumps. + +## Teardown + +- **Machine:** VMs 9341 and 9342 destroyed (`qm destroy --purge`, names checked first); no disk directory left on + `nvme-scratch`. The ISO stays in demo-hp's `local:iso` beside 1.27.1–1.29.0, for the next proof. +- **Hub:** the two unclaimed appliance registrations the proof installs made (**ids 47 and 48**, `registered`) are + the OPERATOR's to discard (Hosts page → Discard) — no token can do it (`05` §17.3). +- **Off-site:** nothing (an unbound appliance provisions nothing). diff --git a/documentation/tests/iso-release-1.30.0-2026-10-22/boot-menu.png b/documentation/tests/iso-release-1.30.0-2026-10-22/boot-menu.png new file mode 100644 index 00000000..254ef0a4 Binary files /dev/null and b/documentation/tests/iso-release-1.30.0-2026-10-22/boot-menu.png differ diff --git a/documentation/tests/iso-release-1.30.0-2026-10-22/checks-gfx.txt b/documentation/tests/iso-release-1.30.0-2026-10-22/checks-gfx.txt new file mode 100644 index 00000000..775f2588 --- /dev/null +++ b/documentation/tests/iso-release-1.30.0-2026-10-22/checks-gfx.txt @@ -0,0 +1,17 @@ +host: proofgfx boot: 2026-10-22 10:39:27 +G7 dpkg: felhom-bootstrap 1.30.0 install ok installed +unit enabled: enabled active: activating +unit fired (journal lines this boot): 8; first: Oct 22 10:39:51 proofgfx felhom-bootstrap.sh[1072]: felhom-bootstrap: console: pvebanner.service masked (it would rewrite /etc/issue with th +pairing code file non-empty: yes +G15 8006 in /etc/issue: 0 'Felhom otthoni szerver': 1 'Felhom home server': 1 pvebanner: masked +host swap: 4005884 kB RAM: 4008428 kB +felhom-bootstrap.sh sha256: 8dbb173df22067fdbb5129afed990486fc8bbc96009095f573deee066836adfb +--- after one reboot +host: proofgfx boot: 2026-10-22 10:41:41 +G7 dpkg: felhom-bootstrap 1.30.0 install ok installed +unit enabled: enabled active: activating +unit fired (journal lines this boot): 6; first: Oct 22 10:41:53 proofgfx felhom-bootstrap.sh[1008]: felhom-bootstrap: console: pvebanner.service masked (it would rewrite /etc/issue with th +pairing code file non-empty: yes +G15 8006 in /etc/issue: 0 'Felhom otthoni szerver': 1 'Felhom home server': 1 pvebanner: masked +host swap: 4005884 kB RAM: 4008428 kB +felhom-bootstrap.sh sha256: 8dbb173df22067fdbb5129afed990486fc8bbc96009095f573deee066836adfb diff --git a/documentation/tests/iso-release-1.30.0-2026-10-22/checks-tui.txt b/documentation/tests/iso-release-1.30.0-2026-10-22/checks-tui.txt new file mode 100644 index 00000000..b8821a3a --- /dev/null +++ b/documentation/tests/iso-release-1.30.0-2026-10-22/checks-tui.txt @@ -0,0 +1,17 @@ +host: prooftui boot: 2026-10-22 10:41:41 +G7 dpkg: felhom-bootstrap 1.30.0 install ok installed +unit enabled: enabled active: activating +unit fired (journal lines this boot): 8; first: Oct 22 10:42:00 prooftui felhom-bootstrap.sh[1050]: felhom-bootstrap: console: pvebanner.service masked (it would rewrite /etc/issue with th +pairing code file non-empty: yes +G15 8006 in /etc/issue: 0 'Felhom otthoni szerver': 1 'Felhom home server': 1 pvebanner: masked +host swap: 4005884 kB RAM: 4008424 kB +felhom-bootstrap.sh sha256: 8dbb173df22067fdbb5129afed990486fc8bbc96009095f573deee066836adfb +--- after one reboot +host: prooftui boot: 2026-10-22 10:43:54 +G7 dpkg: felhom-bootstrap 1.30.0 install ok installed +unit enabled: enabled active: activating +unit fired (journal lines this boot): 3; first: Oct 22 10:44:06 prooftui felhom-bootstrap.sh[1018]: felhom-bootstrap: console: pvebanner.service masked (it would rewrite /etc/issue with th +pairing code file non-empty: yes +G15 8006 in /etc/issue: 0 'Felhom otthoni szerver': 1 'Felhom home server': 1 pvebanner: masked +host swap: 4005884 kB RAM: 4008420 kB +felhom-bootstrap.sh sha256: 8dbb173df22067fdbb5129afed990486fc8bbc96009095f573deee066836adfb diff --git a/documentation/tests/iso-release-1.30.0-2026-10-22/felhom-installer-1.30.0-pve9.2-1.iso.manifest.txt b/documentation/tests/iso-release-1.30.0-2026-10-22/felhom-installer-1.30.0-pve9.2-1.iso.manifest.txt new file mode 100644 index 00000000..5dc22da8 --- /dev/null +++ b/documentation/tests/iso-release-1.30.0-2026-10-22/felhom-installer-1.30.0-pve9.2-1.iso.manifest.txt @@ -0,0 +1,26 @@ +Felhom bare-metal ISO build manifest (R-21 slice A+B+C) +built : 2026-10-22T10:24:15+02:00 +iso-version-tag : iso-v1.30.0 (the git tag this image's source carries, when tagged — NOT installer-v*, the host-install script's line) +pve-version : 9.2-1 +source-iso : proxmox-ve_9.2-1.iso +source-iso-sha256 : 4e88fe416df9b527624a175f24c9aa07c714d3332afb1ee3dbf3879573ef2c6c +assistant-version : proxmox-installer-common v9.2.8 +profile : none (a release image bakes no disk selection) +fqdn : (none — interactive install) +mode : release (PUBLIC image — NO answer.toml, NO baked credential, interactive disk selection) +loader : shim (stock MS-signed chain; Secure Boot OK on compliant firmware) +grub-mkimage : unknown +boot-menu : FELHOM release menu — TWO INTERACTIVE entries ('Felhom telepítés' graphical = default, 'Felhom telepítés (szöveges mód)' = Terminal UI), timeout 15s +menu-entries : 2 (graphical default + Terminal UI; timeout 15s) +menu-removed : debug variants, Rescue Boot, memtest86+, UEFI Firmware Settings +automated-entry : NOT PRESENT — no auto-installer-mode.toml, so the stock grub.cfg does + not emit it. Disk selection is INTERACTIVE by construction. +host-install-url : https://felhom.eu/scripts/felhom-host-install.sh (default) +secret-bearing : no (PUBLIC image — carries NO credential of any kind) +root-password : NONE — not baked. The installer prompts the person installing (release gate G2). +answer-file : NONE — no answer.toml, no auto-installer-mode.toml (release gate G1) +felhom-package : felhom-bootstrap_1.30.0_all.deb sha256=fb224e733e312f992492109f9c29e455bba3471ade254c26494e2dee639fb910 +repo-commit : 115f15c89e82b6002235a2c132cf30570a3cedfd (clean tree, = origin/main at build time — the clean-tree gate, R-730) +output : felhom-installer-1.30.0-pve9.2-1.iso +output-sha256 : 590d7b9b3ccbc7644536a1971a44deb2d1bf7136f69eae2b4dc42961e74d5cc1 +output-size-bytes : 1705324544 diff --git a/documentation/tests/iso-release-1.30.0-2026-10-22/felhom-installer-1.30.0-pve9.2-1.iso.sha256 b/documentation/tests/iso-release-1.30.0-2026-10-22/felhom-installer-1.30.0-pve9.2-1.iso.sha256 new file mode 100644 index 00000000..4a9bafee --- /dev/null +++ b/documentation/tests/iso-release-1.30.0-2026-10-22/felhom-installer-1.30.0-pve9.2-1.iso.sha256 @@ -0,0 +1 @@ +590d7b9b3ccbc7644536a1971a44deb2d1bf7136f69eae2b4dc42961e74d5cc1 felhom-installer-1.30.0-pve9.2-1.iso diff --git a/documentation/tests/iso-release-1.30.0-2026-10-22/gfx-afterreboot.png b/documentation/tests/iso-release-1.30.0-2026-10-22/gfx-afterreboot.png new file mode 100644 index 00000000..95bc6bb5 Binary files /dev/null and b/documentation/tests/iso-release-1.30.0-2026-10-22/gfx-afterreboot.png differ diff --git a/documentation/tests/iso-release-1.30.0-2026-10-22/gfx-disk.png b/documentation/tests/iso-release-1.30.0-2026-10-22/gfx-disk.png new file mode 100644 index 00000000..368217ac Binary files /dev/null and b/documentation/tests/iso-release-1.30.0-2026-10-22/gfx-disk.png differ diff --git a/documentation/tests/iso-release-1.30.0-2026-10-22/gfx-firstboot.png b/documentation/tests/iso-release-1.30.0-2026-10-22/gfx-firstboot.png new file mode 100644 index 00000000..f1393e55 Binary files /dev/null and b/documentation/tests/iso-release-1.30.0-2026-10-22/gfx-firstboot.png differ diff --git a/documentation/tests/iso-release-1.30.0-2026-10-22/gfx-summary.png b/documentation/tests/iso-release-1.30.0-2026-10-22/gfx-summary.png new file mode 100644 index 00000000..403eb488 Binary files /dev/null and b/documentation/tests/iso-release-1.30.0-2026-10-22/gfx-summary.png differ diff --git a/documentation/tests/iso-release-1.30.0-2026-10-22/static-gate.txt b/documentation/tests/iso-release-1.30.0-2026-10-22/static-gate.txt new file mode 100644 index 00000000..65e62272 --- /dev/null +++ b/documentation/tests/iso-release-1.30.0-2026-10-22/static-gate.txt @@ -0,0 +1,62 @@ +== G1 answer.toml/auto-installer-mode.toml at root (want 0) +0 +== G5 paths added vs stock: +'/boot/grub/felhomtheme' +'/boot/grub/felhomtheme/background.png' +'/boot/grub/felhomtheme/theme.txt' +'/proxmox/packages/felhom-bootstrap_1.30.0_all.deb' +== G5 paths removed vs stock: +'/boot/grub/pvetheme' +'/boot/grub/pvetheme/logo.png' +'/boot/grub/pvetheme/theme.txt' +deb: /x/proxmox/packages/felhom-bootstrap_1.30.0_all.deb +== G2 root-password / crypt hash (want 0) +0 +== G3 ssh keys (want 0) +0 +== G4 identity with a value (lines, want only empty decls / variables) +/debx/usr/local/sbin/felhom-bootstrap.sh:534: -H "Authorization: Bearer $token" "$HUB_URL/api/v1/appliance/poll" 2>/dev/null) +/debx/usr/local/sbin/felhom-bootstrap.sh:553: if [[ -z "$envtext" || "$envtext" != *FELHOM_RETRIEVAL_PASSPHRASE=* ]]; then +== G5 secret patterns (PEM, token=, password=, passphrase=, api_key=) +(end) +== G6 menuentries / settings / banned +2 +set timeout_style=menu +set timeout=15 +set default=0 +menuentry 'Felhom telepítés / Install Felhom' --class felhom --class os { +menuentry 'Felhom telepítés (szöveges mód) / text' --class felhom --class os { +0 +== W1 boot text (te-form 'valaszd' want>=1, formal 'valassza' want 0) — ASCII fragments with controls +1 +0 +1 +== G7 package +1 + Package: felhom-bootstrap + Version: 1.30.0 +== G8 postinst +1 +0 +1 +exit 0 +== G9 payload = repo HEAD +8dbb173df22067fdbb5129afed990486fc8bbc96009095f573deee066836adfb /debx/usr/local/sbin/felhom-bootstrap.sh +8dbb173df22067fdbb5129afed990486fc8bbc96009095f573deee066836adfb /repo/scripts/iso/felhom-bootstrap.sh +cf2e4678e9ef5ab8439f7fc8522e4a61b031222243eea8916ea0efa6dca69af3 /debx/lib/systemd/system/felhom-bootstrap.service +cf2e4678e9ef5ab8439f7fc8522e4a61b031222243eea8916ea0efa6dca69af3 /repo/scripts/iso/felhom-bootstrap.service +script IDENTICAL +unit IDENTICAL +== W7 clear in the shipped bound banner (ASCII fragment) +98: # W7 (rehearsal 2026-10-20): clear the screen AND its scroll-back first — the spent pairing code stayed readable +100: { printf '\033[3J\033[H\033[2J' +296: # judged on the lease's OWN addressing/routing, so clear vmbr0 first; the restore path (and +312: pkill -x dhclient 2>/dev/null # F-P4: clear the failed/killed client before the next candidate +== G13 dirs +./etc/felhom/ +./lib/systemd/system/ +./usr/local/sbin/ +== G14 filter. in added text files (want 0) +0 +== G16 secret names in the shipped script +jelszavad=0 Tulajdonosi jelmondat=1 Owner passphrase=1 NEGATIVE-control zzqx-not-there=0 diff --git a/documentation/tests/iso-release-1.30.0-2026-10-22/tui-afterreboot.png b/documentation/tests/iso-release-1.30.0-2026-10-22/tui-afterreboot.png new file mode 100644 index 00000000..95eae46f Binary files /dev/null and b/documentation/tests/iso-release-1.30.0-2026-10-22/tui-afterreboot.png differ diff --git a/documentation/tests/iso-release-1.30.0-2026-10-22/tui-disk.png b/documentation/tests/iso-release-1.30.0-2026-10-22/tui-disk.png new file mode 100644 index 00000000..521c7ac2 Binary files /dev/null and b/documentation/tests/iso-release-1.30.0-2026-10-22/tui-disk.png differ diff --git a/documentation/tests/iso-release-1.30.0-2026-10-22/tui-firstboot.png b/documentation/tests/iso-release-1.30.0-2026-10-22/tui-firstboot.png new file mode 100644 index 00000000..499531cf Binary files /dev/null and b/documentation/tests/iso-release-1.30.0-2026-10-22/tui-firstboot.png differ diff --git a/documentation/tests/iso-release-1.30.0-2026-10-22/tui-summary.png b/documentation/tests/iso-release-1.30.0-2026-10-22/tui-summary.png new file mode 100644 index 00000000..c9e8c2d2 Binary files /dev/null and b/documentation/tests/iso-release-1.30.0-2026-10-22/tui-summary.png differ diff --git a/documentation/tests/iso-release-1.30.0-2026-10-22/w1-boot-text.png b/documentation/tests/iso-release-1.30.0-2026-10-22/w1-boot-text.png new file mode 100644 index 00000000..c2fbec95 Binary files /dev/null and b/documentation/tests/iso-release-1.30.0-2026-10-22/w1-boot-text.png differ diff --git a/website/CHANGELOG.md b/website/CHANGELOG.md index 9baf42ca..e3fb6756 100644 --- a/website/CHANGELOG.md +++ b/website/CHANGELOG.md @@ -1,4 +1,11 @@ -## 2026-10-22 — a real download button on the download pages (W2, operator yes) +## 2026-10-22 — the download pages point at installer 1.30.0 (W1, W7; operator yes) + +- `letoltes.html` and `en/download.html`: version, both links, the side-file link, the two check commands and the SHA-256 + now name `felhom-installer-1.30.0-pve9.2-1.iso` (`590d7b9b…74d5cc1`, the same 1 705 324 544 bytes). Published and + verified by round trip first; the gate record is `documentation/tests/iso-release-1.30.0-2026-10-22/`. 1.29.0 stays + online for a one-edit rollback. + +## 2026-10-22 — a real download button on the download pages (W2, operator yes) - `letoltes.html` „Letöltés (1,6 GB)" and `en/download.html` „Download (1.6 GB)": a `.btn` link to the ISO above the file name, so the household sees one obvious button (the rehearsal's first-hour word W2, felhom.eu R-1210). The diff --git a/website/en/download.html b/website/en/download.html index 5396c73e..5cadb7b5 100644 --- a/website/en/download.html +++ b/website/en/download.html @@ -100,17 +100,17 @@

Download

-

Felhom installer 1.29.0 (based on Proxmox VE 9.2)

+

Felhom installer 1.30.0 (based on Proxmox VE 9.2)

-

Download (1.6 GB)

-

felhom-installer-1.29.0-pve9.2-1.iso – 1.6 GB (1,705,324,544 bytes)

+

Download (1.6 GB)

+

felhom-installer-1.30.0-pve9.2-1.iso – 1.6 GB (1,705,324,544 bytes)

Checksum (SHA-256):

-

dceacae5da247d76cad065bf6c0d3bbefac8d8a5f8e571db2fd8449a97e94829

+

590d7b9b3ccbc7644536a1971a44deb2d1bf7136f69eae2b4dc42961e74d5cc1

-

The same checksum as a file: felhom-installer-1.29.0-pve9.2-1.iso.sha256

-

To check it on Linux or macOS: sha256sum felhom-installer-1.29.0-pve9.2-1.iso. On Windows, in PowerShell: Get-FileHash felhom-installer-1.29.0-pve9.2-1.iso. The string it prints must match the one above. If it does not match, do not use the file – download it again.

+

The same checksum as a file: felhom-installer-1.30.0-pve9.2-1.iso.sha256

+

To check it on Linux or macOS: sha256sum felhom-installer-1.30.0-pve9.2-1.iso. On Windows, in PowerShell: Get-FileHash felhom-installer-1.30.0-pve9.2-1.iso. The string it prints must match the one above. If it does not match, do not use the file – download it again.

The downloaded file has to be written to a USB stick of at least 4 GB (with Balena Etcher or Rufus, for example). The guide covers that too.

diff --git a/website/letoltes.html b/website/letoltes.html index ad38c1c8..f31078ea 100644 --- a/website/letoltes.html +++ b/website/letoltes.html @@ -100,17 +100,17 @@

Letöltés

-

Felhom telepítő 1.29.0 (Proxmox VE 9.2 alapon)

+

Felhom telepítő 1.30.0 (Proxmox VE 9.2 alapon)

-

Letöltés (1,6 GB)

-

felhom-installer-1.29.0-pve9.2-1.iso – 1,6 GB (1 705 324 544 bájt)

+

Letöltés (1,6 GB)

+

felhom-installer-1.30.0-pve9.2-1.iso – 1,6 GB (1 705 324 544 bájt)

Ellenőrző összeg (SHA-256):

-

dceacae5da247d76cad065bf6c0d3bbefac8d8a5f8e571db2fd8449a97e94829

+

590d7b9b3ccbc7644536a1971a44deb2d1bf7136f69eae2b4dc42961e74d5cc1

-

Ugyanez letölthető fájlként is: felhom-installer-1.29.0-pve9.2-1.iso.sha256

-

Ellenőrzés Linuxon vagy Macen: sha256sum felhom-installer-1.29.0-pve9.2-1.iso. Windowson PowerShellben: Get-FileHash felhom-installer-1.29.0-pve9.2-1.iso. A kiírt számsornak meg kell egyeznie a fentivel. Ha nem egyezik, ne használd a fájlt, és töltsd le újra.

+

Ugyanez letölthető fájlként is: felhom-installer-1.30.0-pve9.2-1.iso.sha256

+

Ellenőrzés Linuxon vagy Macen: sha256sum felhom-installer-1.30.0-pve9.2-1.iso. Windowson PowerShellben: Get-FileHash felhom-installer-1.30.0-pve9.2-1.iso. A kiírt számsornak meg kell egyeznie a fentivel. Ha nem egyezik, ne használd a fájlt, és töltsd le újra.

A letöltött fájlt egy legalább 4 GB-os USB kulcsra kell írni (például a Balena Etcher vagy a Rufus programmal). Az útmutató ezt is leírja.