Files
felhom.eu/documentation/audits/review-round-2-2026-10-24/EDITS.md
T

196 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Document edits — review round 2 (2026-10-24)
Every edit below corrects a FACT the main session read at the cited `file:line` before editing (the reviewer's item id
in brackets; the candidate files are in `reviewers/`). Each edited place carries „corrected 2026-10-24" in the text.
Rules, fences, „never" lines and promises were NOT edited — those are rows for the operator.
## 05-hub-architecture.md (DOC-C1)
- [S5] „the live hub is v0.11.0" → written against v0.11.0; the deployed version is read from `manifests/hub.yaml` (`:135` = 0.169.0).
- [S4] „hub 0.162.0 — not yet deployed" ×2, §15.4b „0.166.0 NOT deployed" → deployed (hub CHANGELOG headers v0.164–v0.169).
- [C3] §11 „ADD … the slim DR record onto hosts" → struck through, retired (R-105, §9).
- [S3] `autoMintSelfBindLink` four events → plus the fifth path (R-719 / R-1203) — `hub/internal/web/selfbind.go:384-400`.
- [S12] „39 event types" → 44 (`mail.event.*` keys counted in `hub/internal/i18n/locales/hu.json`).
- [S1/C1] §16.3 nightly 02:00, catch-up 24 h, push 02:30 → four slots, catch-up 6 h, push :30 after each, refuse > 7 h — `hub/internal/dbsnap/dbsnap.go:31,36`; `hub/cmd/hub/main.go:964-968`; `scripts/hub-db-backup/felhom-hub-db-backup.timer:7-10`.
- [S2] §16.5 `scheduleDaily` list → the four slots; prune at its configured time — `hub/cmd/hub/main.go:648,859,968,972`.
## 08-alarm-ladder.md (DOC-C1)
- [S11] info dropped before both legs → except the paired recoveries — `hub/internal/notify/dispatcher.go:137-167`.
- [S7] operator leg „only … a 1-hour cooldown" → per-type cooldown (5 min / 6 h / 1 h), R-723 first-hour suppression — `dispatcher.go:597-640`.
- [S9 — a dated note, the ruling line kept] backup_integrity_failed „default OFF" → superseded by operator Q1 2026-10-12: a default since controller v0.309.0 — `felhom-controller/controller/internal/settings/settings.go:713-721`.
- [S8] the per-APP grain table → five more per-app types — `dispatcher.go:470-480`.
- [S13] „a disabled box is still skipped" → also a box switched off on purpose (R-998) — `hub/internal/monitor/deadline.go:433-442`.
- [S10] §8.1 „NOT BUILT" → slice 1 built in v0.309.0 — `felhom-controller/controller/internal/settings/notif_groups.go:1-16`.
- [S6] §9 „NOT released" ×2 → released 2026-10-24 (controller CHANGELOG v0.342.0 header; `manifests/hub.yaml:135`).
- [U6/U7, listed as facts — each already has a ruling] the operator-only box alarms wg_tunnel_stale, host_swap_short, bind_old_host_linked, golden_not_vouched, recovery_older_package — `dispatcher.go:777,782,862,866,870`; `hub/internal/api/host_swap.go:25-37`.
- §6.5 header „hub main, unreleased" → released in hub v0.144.0 (hub CHANGELOG `:629` inside the v0.144.0 section).
## _hub-review.md (DOC-C1 S14)
- A HISTORICAL banner (stale threshold 45 m by config — `manifests/hub.yaml:88`; cooldown per type; push retired). The body is kept as the record.
## felhom-system-poster.facts.md + .html (DOC-C1 C2) — text only (the poster rule §6: facts file and matching html text)
- Timeline „02:30 hub database → ep0" → „… (and again at 08:30; every 6 h since D34)"; html „02:30 hub DB → ep0, 6-hourly".
## 03-host-agent.md (DOC-B)
- [S1] cloudflared three states → four (`absent`, v0.161.0) — `felhom-agent/internal/hub/cloudflared.go:12-23`.
- [S2] D4 „ready patch, NOT shipped" → shipped in v0.163.0 (`git tag --contains 1109092`) + installer-v1.36.0 (`manifests/webpage.yaml:347`).
- [S3/S4] `a0c88e5`, `ae69ad4` „unreleased" → in v0.163.0 (`git tag --contains`).
- [S5] old key `wg/private.key.prev` → first old key only; later `.prev.<unix>`, newest three; `wg/last-rekey` — `rekey.go:39,105-139`.
- [S6] host_busy „Unreleased 56aabc7" → v0.161.0; plus the line-test holder — `internal/linetest/linetest.go:62`.
- [S7] R-1010 „Unreleased 56aabc7" → v0.161.0.
- [S8] local API „default :8443" → `listen_addr` required, no default — `internal/config/config.go:317-319`.
- [S9] guest swap „once a minute after start" → once, one minute after start — `cmd/felhom-agent/main.go:940-955`.
- NOT edited (RULE → row): S10 break-glass „via the Cloudflare Tunnel behind Access".
## 06-offsite-connectivity.md (DOC-B) — dated notes; the design-of-record text kept
- [S11] „no slice is implemented yet" → note: S1–S4 shipped.
- [S12] sudoers `install … *.mount` → note: `felhom-priv-apply wg` — `felhom-agent/configs/felhom-agent.sudoers:223-229`.
- [S14] IdentityBundle `{TunnelToken, PBSToken}` → four fields — `felhom-agent/internal/escrow/identity.go:30-40`.
- [S15] the only automatic re-registration → plus D30 — `rekey.go`.
- [S16] „No new alarm channel" → `wg_tunnel_stale/ok` — `hub/internal/api/host_tunnel.go`.
- [S17] key rotation „design when fleet size warrants" → note: the D30 rotation exists.
- [S18] cloudflared „seam" → note: a guest container the agent only reads; withdrawing the plan is the operator's (row).
- NOT edited (RULE → row): S19 „no inbound listener … box→PBS only".
## 12-agent-tooling.md (DOC-B)
- [S20] „five byte-identical copies" → measured not identical; aligned (below).
- [S21] rules load „when a matching path is touched" → `unconditional: true` / no `paths:` load always — `felhom.eu/.claude/rules/live-probes.md:2`.
- [S22] skills „live at once … the list is the folder" → a NEW skill needs `install_skills.py` again (`felhom-web-design` has no link; not installed — no DooPlex change in this run).
## Instruction files (unprompted-work §5: a stale fact corrected / a proved fact added — named here)
- `felhom-agent/.claude/rules/unprompted-work.md`, `app-catalog-felhom.eu/.claude/rules/unprompted-work.md`, workspace root
`.claude/rules/unprompted-work.md` (unversioned): the missing item-6 paragraph „A version number is pushed once …"
added (before: 95 lines, md5 3b071ad2; after: byte-identical to the felhom.eu and controller copies, md5 b1891bd4).
Why: the file's own header says „change all five or none" and two copies had drifted; the paragraph states a fact
(`felhom-controller/controller/build.sh:115-125` refuses an existing tag and an unreachable registry).
- `felhom.eu/.claude/rules/live-probes.md:41`: before „no `/opt/felhom/stacks/<name>`"; after „no
`/opt/docker/stacks/<name>/app.yaml` (the folder itself stays — it holds the catalog's template files)". Why: the path
is `/opt/docker/stacks` (`felhom-controller/controller/internal/config/config.go:393`) and the folder stays after a
clean removal (the catalog's `box_walk.remove` checks `app.yaml` since 2026-10-24).
## 01-topology-and-trust.md (DOC-A)
- [S7] `docs/proxmox-platform.md` → `documentation/proxmox-platform.md` (the file exists; `docs/` does not).
- [S6] „every /api/ route needs a dashboard session" → but the read-only `/api/health` — `felhom-controller/controller/cmd/controller/main.go:4236`.
- [S1] claim mail link `templates.go:27` → `FormatClaimEmail` (`hub/internal/notify/templates.go:250-252`).
- [S2] the retrieval code „single-use … TTL" → a dated note: not burned, no TTL; D19/R-1159 rule — `hub/internal/api/passphrase_scope.go:19-30`.
- [S3] Cloudflare token reach check „hub main, unreleased" → released in hub v0.144.0.
- [S4] dead pointer `07:296-299` → a dated note.
- [S5] snapshot-before-deploy → [DESIGN — not built]: the agent serves `/snapshot`, `/rollback`; no controller caller (grep of `internal/agentapi`).
- NOT edited (RULE/promise → rows): C3 „the hub never connects into a box / no inbound control endpoint / no standing operator backdoor" vs poke + felhom-sshd; C4 „the operator cannot open the off-site backup" vs R-985.
## 04-control-plane-authorization.md (DOC-A)
- [S8] `docs/tests/…`, `docs/architecture/…` → `documentation/…`.
- [S10] time window → the 2-minute skew on `issued_at` — `felhom-agent/internal/authz/verifier.go:19-22,148-155`.
- [U2 → DESIGN — undocumented note + row] no cap on the window's length; opsign default 30 min — `felhom-agent/cmd/felhom-opsign/main.go:57`.
- [S9] §6.1 „controller + hub main, unreleased" → released in controller v0.304.0 + hub v0.144.0 (both CHANGELOGs).
## 13-threat-model.md (DOC-A) — facts corrected; every verdict cell LEFT AS IT WAS and marked „re-check" (a verdict is a judgement)
- [S11] „38 local-API routes" → 41 on main (`felhom-agent/internal/localapi/server.go`).
- [S12] hub routes → 54 API entries; `/bind/<token>` added to the no-credential list.
- [S13] homepage socket (R-981) → gone; the allow-list empty — catalog `templates/homepage/docker-compose.yml:21`; `privpolicy/allowlist.json:4`.
- [S14] R-983 / R-976 → fixed (controller v0.324.0, `internal/web/auth.go:352-366`).
- [S15] R-973 / R-978 → narrowed in agent v0.160.0 (`git tag --contains f17e197 / 8561dc8`).
- [S16] tokens unsealed (R-975) → sealed since hub 0.168.0 (deployed).
- [S17] root password SSH (R-982) → the drop-in shipped in agent v0.163.0.
- [S18] R-970 „does not hold" → the routes are removed, pinned by `r970_no_hub_key_door_test.go`.
- [S19] R-971 „design gap" → `privpolicy.Admit` before every write (controller v0.328.0).
- [S20] „hub 0.168.0 deploy pending", „R-1244 not released" → deployed / released 2026-10-24.
## 07-backup-architecture.md (DOC-D1)
- [S2/C3] Tier-1 „secret-stripped app.yaml" → carries the portable secrets (D5) — `felhom-controller/controller/internal/backup/recovery_unit.go:24-27`.
- [S7] `main.go:604-607` → `backupwindow.LegTimes` at `cmd/controller/main.go:1258-1264`.
- [S9] demo-hp „keep-last=1" → a dated note: keep-daily=N since R-1149 — `felhom-agent/internal/config/config.go:553-559`.
- [S1] D22 „controller main, unreleased" → released v0.338.0.
- [S11] §6.6 table → a row: the off-site restore also refuses a mismatched/mixed snapshot first — `internal/backup/offbox_reconstitute.go:826-833`.
- [S8] line citations moved (`GetAppDrivePath`, F5); `mp1` → a dated note (gone).
- [S3/C1] row 15 R-104 „open DEFECT" ×2 → FIXED 2026-10-05, v0.297.0 — `internal/backup/offbox.go:156-162`; CLOSED-ITEMS.md:895.
- [S6] row 10 R-893 / R-973 „unreleased" → released; „the next slice on R-893" → note: D20 (v0.336.0), D22 (v0.338.0).
- [S5] „Hub v0.158.0 … deploy waits" → deployed 2026-10-18 12:16 (hub CHANGELOG:288).
- [S10] „a restore is refused while any second-drive copy runs" → a dated note: the kept-data load checks only RestoreStatus/IsRunning (`internal/api/kept_install.go:89-92`) — a row.
- [U1/U2/U6 + hub U2/U3 + U7 → §8.2c, DESIGN — undocumented notes, one row for the operator]: the 60-min copy limit and stray handling; Eltávolítás refused during backups; start-after-put-back failure; the hub's off-site delivery checker (`offsite_delivery_stuck`, `maybeHeal`, the R-1230 skip — `hub/internal/monitor/offsite_delivery.go:103-110`); the release copy (D33) not in the matrix.
- NOT edited here: C4 (a stale code comment in `felhom-agent/internal/localapi/backup_cap.go:15`) — a row; C2 (G15 „nightly") — corrected in the capability map below.
## 09-update-architecture.md (DOC-C2) — dated notes; no §3 ruling text edited
- [S1/S2/S3] §1 (the 2026-09 measurement) → one dated note: `UpdateStack` gone, `StartGuardedUpdate`; moved line numbers.
- [S16] `stacks.update_window` „no Go code reads it" (inside ruling 11) → a dated note: removed.
- [S17] `unattended.go:433–435` → `:449-451`.
- [S4] §5.3 writers → note: `advancePinTo`; `pinBack`, the undo's `restoreDefinition`.
- [S7/C1] slice 6 „OPEN — R-450" ×2 → BUILT, R-450 closed 2026-10-05.
- [S12] R-646 residual → closed by `BackfillAppliedMeta` — `internal/stacks/undo.go:646-652`.
- [S18] `config.go L280-281` → L278-279.
- [S9] part 1 „DB up alone … empty-then-load" → note: the shipped folder copy — `undo.go:26-36`.
- [S10] „a step has no .felhom.yml of its own" → closed — `ladder.go:127-132`.
- [S11] „the box half … is not built" → built — `digest.go:15-24`.
- [S19] reason `current` → `already_current` — `update.go:432`.
- [S14] digest comparison „R-446 §3b Q6" → built for every ref with a ladder entry.
- [S13] §8.6 / „stepping is slice 6" → notes: any tier, the undo, the ladder.
- [S15] engine-major „until Slice 4" → note: MariaDB lifted, PostgreSQL by two-venue proof.
- [S5] recordInstalledImages callers → note: the real callers.
- [S8] §6.1 phase table → the bind-data tier order; a `converting` row (v0.273.0, `pgconvert.go`).
- [U1–U6, S6 → §6.4.x, DESIGN — undocumented notes]: build.sh's dirty/HEAD/non-git refusals (`controller/build.sh:144-166`); the once-retry; stopped_by_household; the manual leg's deadline; already_current/engine_no_test; the unreadable-template render row and R-971 admission.
- NOT edited (RULINGS — rows for the operator): C4 decision 13's „CompareImageRefs moves to the catalog gate" (not built); C5 decision 14's „never jumps" vs a person's press on an app older than the ladder; C7 decision 250 item 5's „by its AGE" vs the gate's proxy.
## 00-capability-map.md
- 20 PROVEN-LIVE rows marked „re-check (2026-10-24)" in their Scope cell, each with the commit that changed its mechanism after its evidence (status words unchanged): a7, a8, a10, a11, a17, b1, b2, b7, b11, c3, c4, c5, c6, d6, d10, d11, e17, g7, g15, g18. Each commit's files read with `git show --stat`.
- [DOC-D1 C2] G15 „a nightly consistent copy" → every 6 hours since D34.
## 16-storage-physical-identity.md (DOC-D2)
- [S2] the single-copy notice „a Go constant, not i18n" → the i18n keys — `felhom-controller/controller/internal/backup/backup.go:1485-1494`.
- [S3] `/disks/candidates` „whole disks only" → with nested partition candidates — `felhom-agent/internal/storage/candidates.go:84-90`.
- [S4] `felhom-host-install.sh:2261-2275` → `step_grows` at `:2475`.
- [S1] the R-1093 „not as written" → a note: fixed in agent v0.160.0 (`git tag --contains f7b7308`).
- [U4–U7 → DESIGN — undocumented notes]: detect-virt once; unreadable = same disk (R-668); the internal place's lifecycle refusals; its size rule.
## 15-media-library.md (DOC-D2)
- [S5/S6/C2] the §10 measurement table → one dated note before it: binds rewritten, restart on the household's press, the drive kept registered, and `b01bb4b`'s stopped-app rule.
- [S7] Transmission's watch/download folders → note: `excluded` since catalog `c50adfc` (`templates/transmission/.felhom.yml:46-51`).
- [U1/U3 → DESIGN — undocumented note]: the „Később" timer is in memory (`media_events.go` `handleMediaRestart`); the Sonarr/Radarr key read from `config.xml` (`mediawire.go:336-345`).
- [U2 — FIXED in code, not a note]: a media restart started a household-stopped app → controller `b01bb4b`.
## _recovery-inventory-2026-07-28.md (DOC-D2 S8–S13) — a WHAT HAS MOVED SINCE banner; the inventory body kept as its date's record
- one `mp0`, no `mp1` (`felhom-agent/configs/build-golden.sh:31-38,99`); portable secrets in the unit; `RestoreTier2Unit` (`tier2_restore.go:197`); volume tars replayed (R-354); ep0 keep-weekly 2 at 03:30 (`scripts/felhom-tenantsync.sh:187-197`); local keep-daily=3; restic pinned 0.19.1 (`Dockerfile:43-52`).
- runbooks/RUNBOOK-manual-guest-restore.md [DOC-D2 C3]: a dated note after the example config — one `mp0` at /var/lib/felhom, no `mp1` (golden v2.1.0+); the procedure unchanged.
## 14-host-power-off.md (DOC-E)
- [S2] „two exact sudoers vectors, FELHOM_POWEROFF" → `pct shutdown` in FELHOM_GUESTHOOK + `systemctl poweroff` in FELHOM_POWEROFF — `felhom-agent/configs/felhom-agent.sudoers:81-90`.
- [S1] heavy-gate holders → plus the line test (agent v0.164.0).
- [S3] the website FAQ line „a later task" → published — `website/gyik.html:128,603`.
- [S4] a paragraph that split the §3 table → moved below the table (rendering only).
- [U1–U3 → DESIGN — undocumented notes]: a re-enroll during the hold is „gone" (`hub/internal/api/reenroll.go:67-68`); the two info events; the three confirmation words.
## 11-os-updates.md (DOC-E)
- [S8] status „§8 step 2 BUILT" → steps 2–6 built by §8's own list (the ratification left to the operator).
- [S5] cloudflared `2026.6.0` → `2026.9.3` today — `felhom-controller/controller/internal/infra/infra.go:26`.
- [S6] apt sudoers/caller line numbers → `sudoers:68,228`, `lanresolver.go:133`, `wgtunnel/manager.go:659`.
- [S7] §5.4.1 „DRAFT … nothing installed" → note: built; sudoers holds only `--plan` (`sudoers:337`).
- [S9] BUNDLE_FILES 22 → 32 (counted in `felhom-agent/configs/felhom-os-apply`).
- [S10] HOST_SLOW_RE list → plus `linux-*`, `firmware-*`, `proxmox-secure-boot-support` (read from `felhom-os-apply`).
- [DOC-E U5 / DOC-C1 U5] §5.7 → the System page's „Upload line" cell (`hub/internal/web/system.go` `lineStaleAfter`).
## 10-localisation.md (DOC-E)
- [S12] „Part B is the remaining piece" → built (v0.256.0) — `felhom-controller/controller/internal/config/config.go:149-154`.
- [S13] formal-form ceiling 16 → 0 — `felhom-controller/controller/scripts/i18n_missing_gate.py:41`.
- [S11/C1] the setup wizard „still reachable … R-554" → deleted (`internal/setup` absent; `bootstrap.WaitForConfig`).
- [S15] `metadata.go L316` → L475.
- [S14] „53 real catalog files" (fixtures, still 53) / „fifth row" → sixth / „all 53 apps" → the freeze file's 65.
## 02-controller-module-map.md (DOC-E) — dated notes; the v0.33 plan tables kept
- [S16/C3] two in-flight markers → four (`update-journal.json`, `.felhom-install-pending`).
- [S17] three StartGate holders → four (1b `IsUpdating`, `cmd/controller/main.go:2459-2477`).
- [S18] `GetAlerts` → `GetBannerAlerts(page, lang)` (R-906) — `internal/web/alerts.go:353`.
- [S19] „no longer calls the Cloudflare API" → note: `cloudflare/` still wired with `cf_api_token` (`main.go:1992-2000`).
- [S20] `state.go`/`updater.go` DELETE → note: both live, `AgentSwapper` (`internal/selfupdate/updater.go:38-47`).
- [S21] `sync.go:319`, `config.go:351` → `:436`, `:399`.
- [S22] `locked_after_deploy` „read by no code" → note: read into `LockedFields`, enforced only by an uncalled function.
- [C2] §2 `UpdateStack` → note: deleted in v0.237.0.
- [U4] §1 → a note naming the 22 packages with no row (an `ls` of `controller/internal/`).
## felhom-controller/REUSE.md (DOC-D1 C5/U8, DOC-C2 C3)
- `CrashPutBack … (D22 / R-1195, unreleased)` → `v0.338.0`.
- `recordInstalledImages` callers `StartStack/RestartStack/UpdateStack/runComposeDeploy` → the real callers; `UpdateStack` deleted in v0.237.0.
- A new row: `Tier2CopyBlocksRestore` / `ClearLeftoverTier2Copies` / `MarkTier2CopyForTest` + the `tier2Docker` seam (`internal/backup/tier2_copy_lifecycle.go:85,255,319,341`).
## Late additions (the disposition check before the README)
- 03 §6 [DOC-B U1–U5, U8; DOC-A U4 → DESIGN — undocumented note]: 41 routes (24 unlisted), the controller-started line test, the island bridge, the line-test state and switch, the WG block's OOB fields, the D30 count in memory.
- 13 §5 [DOC-A U1 → DESIGN — undocumented note]: the file manager's one sign-in trust (`filebrowser_sso.go:15-22`).
- 08 §9 item 6 [SEC-1 X1]: the limits list names „any viewer explains any upload" (R-1262).