docs: REPORT/README/CONTEXT for v0.94.0 config-refresh (live-validated)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HxLA1mZurFq9kt8hneFeCs
This commit is contained in:
2026-06-30 22:17:53 +02:00
parent 419d3d0b4e
commit 6ce61e862a
3 changed files with 86 additions and 77 deletions
+20
View File
@@ -1159,6 +1159,26 @@ The floor is the **auto-target** (the operator raises it for a controlled fleet
the customer's manual opt-in. Floor source + operator UI are hub-side (felhom-hub v0.15.0). **No agent
change — Phase 2 reuses the Phase 1 `POST /controller/swap`.**
##### Pull-based config-refresh (v0.94.0)
The same **report ACK** also carries a per-customer **`config_version`** (a hub-side stored counter,
bumped on every config save; felhom-hub v0.26.0). This is how an operator config edit reaches a running
box — **the hub never connects into the box** (it replaced the retired inbound "Push Config"). Wired in
`OnPushResponse` beside the floor reconcile (`internal/report/config_refresh.go`, `ConfigRefresher.Reconcile`):
- **Changed** vs. the last-applied version (`settings.applied_config_version`) → `bootstrap.RefreshConfig`
re-pulls `controller.yaml` from the hub and rewrites it, **re-merging the per-guest `local_api`** from
`bootstrap.json` (reuses the first-boot pull machinery; overwrites `controller.yaml` since the hub is its
source of truth; **never touches `settings.json`**) → record the new version → **graceful self-restart**
(`api.GracefulSelfRestart``os.Exit(0)` → Docker `restart: unless-stopped` re-reads the new config).
- **First-ever** ACK (nothing recorded) → record the baseline **without restarting** (the first-boot pull
already has the current config).
- **Unchanged** version → no-op (so no restart storm — after a refresh `applied == ACK`).
- **Failed pull** → keep the current config, do **not** record/restart, retry next report cycle.
- Record-before-restart so the restarted process sees the version applied and doesn't loop. Only the
`felhom-controller` container restarts; customer app stacks are untouched. (A config apply rotates
`web.session_secret`, so dashboard sessions are invalidated — same as the old Push-Config path.)
##### Design Philosophy
- **No automatic rollback** — follows the Watchtower pattern (24k+ GitHub stars, no rollback). Docker's `restart: unless-stopped` policy is the crash safety net. The Hub's dead man's switch detects when the controller goes down.