# felhom.eu — task reports > **Overwrite** this file with a summary of the most recent task only (uniform with the other repos; not cumulative). The cumulative hub history lives in [hub/CHANGELOG.md](hub/CHANGELOG.md); the scripts history lives in [scripts/CHANGELOG.md](scripts/CHANGELOG.md). --- # TASK-D — unattended resilience: docs, roadmap, capability map, riders (2026-07-21) **No hub code was touched** (§12 of the brief). This repo's share is documentation, the two Part-5 riders, and the honest status of the three claims the task makes. Implementation reports live in the repos that shipped: `felhom-controller/REPORT.md` (R-51, R-52, v0.156.0) and `felhom-agent/REPORT.md` (R-54, v0.92.1). ## 1. ROADMAP - **R-51 → SHIPPED (controller v0.156.0)**, and **the row's diagnosis is corrected in place**. It claimed aggregation classified a dead-primary stack `unhealthy`, making the deliberate `unhealthy` exclusion the suppressor. The source says otherwise: `aggregateState`'s final branch returned `StateRunning` for any running/stopped mix ("report as running (partial)"), so the stack read **running** and `IsDownState` was never consulted about `unhealthy` at all. The constraint the row protects was therefore never in tension with the fix, and `downstate_test.go` ships untouched. - **R-52 → SHIPPED (controller v0.156.0)**, `internal/bootrecon`. Note recorded that **P1 is not a blocker**: the reconciliation is correct whether or not Docker recorded those two containers as user-stopped, and P1's experiment falls out of STOP-1's reboot leg for free. - **R-54 → NEW ROW, SHIPPED (agent v0.92.1).** Origin: `INCIDENT-guest-dhclient-killed-2026-07-20` §5, whose OPEN RISK it closes. The row carries the load-bearing design fact — *liveness of the DHCP client is itself a probe, because the damage is timed and the address survives the cause by 1–2 hours* — the live sudoers finding, and the explicit deferral of the **static-guest** leg to **R-50**, which is where the incident's own option 2 ("give the guest a static address") belongs. ## 2. Capability map New row in section: **"Box survives an unattended app or guest-network failure"** — status **IMPLEMENTED**, deliberately **not** PROVEN-LIVE. One leg genuinely is live and is cited as such: the guest-network watchdog's healthy cycle on felhom-pve (`ok=68 total=68 degraded=0` and `DEBUG guestnet: guest network healthy vmid=9201 mode=dhcp has_route=true dhclient_alive=true`, 12:34:15 CEST). The three legs that would earn PROVEN-LIVE are all destructive and operator-present, and none has run: killing immich's primary, rebooting 9201 to strand and recover boot orphans, and replaying the dhclient kill. The strict enum says a row without that evidence is not PROVEN-LIVE, so it is not. The existing **"Box survives a site/network change"** row (PARTIAL) already pointed at R-51/R-52 as related work; it stays PARTIAL — R-50 is still its durable fix. ## 3. Part-5 riders - **Hub `build.sh` deploy hint → GitOps wording.** The script printed `kubectl set image …` and `kubectl apply -f manifests/hub.yaml` as the deploy instructions — both are reverted by the next ArgoCD sync, which is the worst failure shape: it appears to work, then silently disappears. Now prints the manifest-bump + hard-refresh + deliberate-sync sequence, and names the trap explicitly. **Caveat worth knowing: `/mnt/5_hdd/felhom.eu/build/felhom-hub/build.sh` is NOT in any git repo** — it is a DooPlex-local build-dir script. So this rider is a fix to the operative file only, and it is not versioned anywhere. Worth adopting into the repo as its own change. - **`documentation/PROMPT-TEMPLATE.md` §10 gains the seam-discipline row.** Text generalised from the brief's §9 rule 6, plus what this session added to it: three shipped inert-seam defects in three days (controller v0.154.0, agent v0.91.0, agent v0.92.0's missing sudoers grant), all fully green; and the finding that a `strings.Contains` source assertion is not sufficient, because a commented-out call still contains the string — walk the AST. ## 4. What was verified, and how Endpoint/host-level, no browser (none on DooPlex). Everything claimed live in the two implementation reports was read out of journald or the agent's own capability self-check on felhom-pve. No claim in any of the three reports rests on a test that only proves a seam. ## 5. An ordering question for the operator (STOP-1 vs STOP-3) The brief's Phase A says **do not hand-deploy** the controller — the floor save at **STOP-3** is what deploys 0.156.0, banking another single-fire self-update datapoint. But **STOP-1 exercises the controller legs**, which need 0.156.0 to be live. As written the two are in the wrong order. The resolution that keeps both intentions is: **do the STOP-3 controller floor save first** (floor → `0.156.0`), let the box self-update — that IS the R-23 datapoint — and then run STOP-1 against the new version. The agent half of STOP-3 (manifest → 0.92.1) is independent and can happen at any point. Flagged rather than assumed, because reordering an operator's STOP sequence is not CC's call. ## 6. Follow-ups this session surfaced (none actioned here) 1. `felhom-controller/controller/.gitignore`'s bare `controller` entry also matches the directory `cmd/controller/`, so ripgrep silently skips `main.go` and new files there need `git add -f`. Both directions produce inert-seam mistakes. XS fix: anchor it as `/controller`. 2. The hub `build.sh` above is unversioned. 3. `TestGenerateRecoveryCode_EntropyAndFormat` (agent) flakes on hyphenated wordlist entries (`drop-down` → 11 tokens). Observed 3/8 this session — worse than the documented ~1/5, and it is a one-line fix in the generator or the assertion, not a mystery.