Files
felhom.eu/REPORT.md
T
admin 907e5ce65c docs(TASK-D): R-51/R-52 SHIPPED + new R-54 row; capability-map row; seam-discipline rider
R-51's roadmap diagnosis is corrected at the source: aggregation returned StateRunning
("partial") for a running/stopped mix, so the stack read RUNNING and IsDownState was never
consulted about  at all — the constraint that row protects was never in tension
with the fix.

New R-54 row closes the INCIDENT-guest-dhclient-killed-2026-07-20 §5 OPEN RISK, and records
the design fact that makes it work: liveness of the DHCP client is itself a probe, because
the damage is timed and the address outlives its cause by 1-2 hours. The static-guest leg is
deliberately deferred to R-50.

New capability-map row is IMPLEMENTED, not PROVEN-LIVE: one leg is live (the watchdog's
healthy cycle on felhom-pve), the three that matter are destructive and operator-present and
have not run.

PROMPT-TEMPLATE §10 gains the seam-discipline row, including that a strings.Contains source
assertion is NOT sufficient — a commented-out call still contains the string.
2026-07-21 12:40:00 +02:00

88 lines
5.7 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.
# 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
12 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.