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

---

# REPORT — Hub GUI correctness + pull-based config delivery (hub v0.26.0)

**Date:** 2026-06-30 · **Repo:** `felhom.eu` (`hub/`) · **Companion:** felhom-controller v0.94.0

Implements the "retire the 5 inbound controls + pull-based config-refresh" task. Resolves audit
`documentation/audits/AUDIT-hub-gui-2026-06-30.md` F-S1/F-S4 + the dead-template findings.

## Baselines
- hub `felhom.eu` was `e51e03b` (v0.25.0) → code `a3ac6c9`, manifest `d88b43a` (**v0.26.0**, live on k3s).
- (companion) felhom-controller v0.93.0 → v0.94.0.

## What changed (hub)
- **Pull-based config delivery.** New `customer_configs.config_version` (stored counter, NOT a YAML
  hash — `configgen` emits a fresh `session_secret`+timestamp each call). `SaveCustomerConfig` bumps it
  on every save (new=1, updates increment). The report ACK (`handleReport`) advertises `config_version`
  beside the floor/latest; omitted for report-only customers.
- **Retired the 5 inbound (hub→box) controls** (`01-topology-and-trust.md:11` never-inbound):
  Trigger Update, Push Config, Pull Config, Show Diff (+`compareYAMLValues`/`flattenYAML`/`maskSensitive`
  helpers + dead `ConfigSyncStatus`/`ConfigDiffCount`) — handlers + routes + buttons + JS deleted.
  Geo-disable KEEPS its hub→Cloudflare `RemoveGeoRules`; its inbound `notifyControllerGeoDisable` deleted.
- **GUI staleness + dead templates.** Setup Commands now show `sudo ./felhom-host-install.sh
  --customer-id <id>` (no-echo passphrase) instead of `docker-setup.sh`; Option 2 relabelled
  "Manual config fetch (debug only)". Deleted orphaned `customer.html` + `config_detail.html`.

## Files
`internal/store/store.go` (column + bump + 3 SELECTs + struct), `internal/api/handler.go` (ACK),
`internal/web/server.go` (routes + handleTriggerUpdate removed), `internal/web/configs.go`
(handlers/helpers removed, geo trimmed), `internal/web/templates/customer_unified.html` (setup cmd,
buttons/JS removed), deleted `customer.html`+`config_detail.html`, `manifests/hub.yaml` (tag).
Tests: `internal/store/config_version_test.go`, `internal/api/config_version_ack_test.go`.

## Tests & green gate
- `go build ./... && go vet ./... && go test ./...` — **all green**.
- **Red-proof (version bump):** with the `config_version + 1` bump defeated, both
  `TestSaveCustomerConfig_BumpsConfigVersion` and `TestReportACK_ConfigVersion` FAIL
  (`config_version after edit = 1, want 2`) — the bump is load-bearing. Restored → green.
- **No-inbound:** `grep client.Do internal/web/` → only Gitea registry/template fetches; **zero**
  ControllerURL targets (ControllerURL remains a display-only link).

## Live validation (demo, hub.felhom.eu + guest 9201)
- Hub v0.26.0 rolled out on k3s (Synced/Healthy, `[INFO] felhom-hub … starting`).
- Live ACK for demo-felhom: `{"config_version":1,"latest_version":"0.94.0","min_controller_version":"0.87.0","status":"ok"}`.
- Bumped demo-felhom `config_version` 1→2 in the hub DB (equivalent to a config save; the SaveCustomerConfig
  bump itself is unit-tested + red-proofed). The controller detected it, re-pulled, and self-restarted
  (see controller REPORT for the box-side trace) — full pull-based delivery, no inbound connection.

## Open follow-ups (from the audit, not in scope here)
Hosts page (F-M1); controller-side geo intent sync (geo-disable is now CF-only, no box notify);
Show-Diff could return later as a read-only hub-vs-reported view.
