hub: HostLeafChecker — proactive agent re-key detection (host_leaf_changed) v0.22.0
Watches each host's reported local-API leaf fp; alerts on change (trust-on-first-report). Sibling of HostCapabilityChecker; store.GetHostLeafFingerprints reads report_json (no migration); hub-generated event (no allowlist change). Change red-proof + first-obs-seed + empty-skip + blocked-drop tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Pg8ANF97SEeKYSN5Jxw3qJ
This commit is contained in:
@@ -1,5 +1,29 @@
|
||||
# Felhom Hub — Changelog
|
||||
|
||||
## v0.22.0 — proactive agent re-key detection: HostLeafChecker (host_leaf_changed) (2026-06-29)
|
||||
|
||||
Companion to felhom-agent v0.48.0 (which now reports its served local-API leaf fp). The hub watches
|
||||
each host's leaf fingerprint and raises an operator alert when it **changes** (an agent re-key) —
|
||||
proactive, fleet-wide, independent of any controller's channel-health check. The last self-health leg.
|
||||
|
||||
- **`monitor.HostLeafChecker` (NEW):** sibling of `HostCapabilityChecker`. Trust-on-first-report — the
|
||||
first fp per host is the baseline; a later change emits **`host_leaf_changed`** (operator, English;
|
||||
details carry old+new fp) and advances the baseline. First-obs seeds silently (a "change" needs a
|
||||
prior value, so no F2 issue). An empty reported fp (pre-v0.48.0 / local-API-disabled) is unknown —
|
||||
never seeds, never alerts, never overwrites a baseline. Customer-blocked hosts dropped; unseen pruned.
|
||||
Runs on the existing 60s sweep. **KNOWN LIMITATION (documented):** trust-on-first-report can't detect
|
||||
a re-key that happened before the hub's first report — but the controller channel-check catches the
|
||||
downstream pin mismatch, so this is defense-in-depth.
|
||||
- **`store.GetHostLeafFingerprints` (NEW):** latest reported fp per host, parsed from `report_json`
|
||||
(mirrors `GetHostCapabilities` — `MAX(id)`, **no schema migration**).
|
||||
- **No allowlist change:** `host_leaf_changed` is hub-GENERATED (via `SaveEvent` + `dispatcher.ProcessEvent`),
|
||||
not controller-pushed, so it bypasses the `/api/v1/event` `allowedEventTypes` gate — same as the
|
||||
host_* events. The generic operator template relays it (no template change).
|
||||
- Tests: change **red-proof** (A→B → one event + baseline advanced; companion: unchanged → none),
|
||||
first-obs seeds silently, change-back re-alerts, empty fp skipped, customer-blocked dropped. Cross-repo
|
||||
golden mirrors `leaf_fingerprint`. Version `0.21.0 → 0.22.0`.
|
||||
|
||||
|
||||
## v0.21.0 — F2: alert on a host already degraded/stale at hub (re)start (2026-06-29)
|
||||
|
||||
Mirror of the controller's F2 fix, for the hub checkers: a host that was already **degraded**
|
||||
|
||||
Reference in New Issue
Block a user