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

## Agent capability-degraded operator alert — hub leg (HostCapabilityChecker), hub v0.19.0

**Date:** 2026-06-29 · **Baseline:** hub `main` @ `1958204` (v0.18.0) → **v0.19.0** @ `b7b165b`;
manifest synced @ `2312572`. Companion: felhom-agent **v0.44.0**.

### What & why
felhom-agent v0.44.0 now rides a `capabilities` snapshot on its host report (each required `sudo -n`
grant: ok/degraded). This is the hub leg: detect the ok→degraded transition and alert the **operator**
— closing the loop that let the 2026-06-28 non-root-cutover regressions go undetected until breakage.

### Implementation
- **`monitor.HostCapabilityChecker` (NEW):** a deliberate sibling of `HostStalenessChecker` — same
  per-host state map, seed-without-event, emit-only-on-transition. A host is `degraded` iff its latest
  report has any **Critical** capability `status:"degraded"`; non-critical degradations never alert.
  Runs on the existing 60s sweep alongside the staleness checkers.
- **Events:** `agent_capability_degraded` (warning, ok→degraded; names the degraded caps + gated
  features in message + details JSON), `agent_capability_recovered` (info, degraded→ok). Routed via
  the existing `Dispatcher.ProcessEvent` — **operator-only** (not a customer notification toggle, same
  mechanism as `host_stale`) with the standard 1 h operator cooldown.
- **`store.GetHostCapabilities` (NEW):** reads the snapshot from the latest host-report's `report_json`
  per host, keyed on `MAX(id)` (not `received_at` — within-second ties would return multiple rows).
  **No schema migration.** A pre-v0.44.0 agent (no `capabilities`) reads as `ok` → no false alert.
- Cross-repo `host-report.golden.json` mirrors `capabilities: []` (byte-identical with the agent copy).

### Tests (all green: `go build/vet/test ./...`)
`TestHostCapabilityChecker` (seed no-event → ok→degraded ONE event → steady degraded none →
degraded→ok recovered), `…_NonCriticalIgnored`, `…_OldAgentNoCaps`. The golden contract test +
key-set tests pass with the mirrored field.

### Live validation (k3s felhom-system) — deployed + verified
- Built + pushed `felhom-hub:0.19.0` on 180; bumped `manifests/hub.yaml`; ArgoCD hard-refresh → sync →
  rollout. **Synced / Healthy**, running image `…felhom-hub:0.19.0`.
- Startup: `felhom-hub 0.19.0 starting` + `Host capability checker initialized: 1 ok, 0 degraded` —
  the checker is live and reading the demo host's snapshot (agent reports 40/40 ok).

### NOT yet live-validated (deferred)
The full live agent→hub→operator-email degraded transition: the hub alert fires only on a **Critical**
capability degraded, which on the live host would require removing a Critical grant (forbidden — would
re-break drives) or a separate test host, plus a real operator email. **Fully covered by the unit
tests above.** Deferred to a scratch-host exercise.
