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

19 KiB
Raw Blame History

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).