# REPORT — agent reports served leaf fingerprint (hub re-key detection, Part A), v0.48.0 **Task:** the last self-health leg — the agent reports its served local-API **leaf fingerprint** so the hub can detect an agent re-key fleet-wide (`host_leaf_changed`, hub v0.22.x). This repo = **Part A**. **Baseline:** agent `main` @ `3844df7` (v0.47.0) → **v0.48.0** @ `bf8e3be`, sha `a3dad050…`. ## Change - **`internal/hub/report.go`:** new `HostReport.LeafFingerprint string` (`json:"leaf_fingerprint"`) — the SHA-256 of the leaf the agent currently serves. Empty when the local API is disabled (no leaf) → the hub treats "" as unknown, never an alert. Not a secret (the fp is public; the token is never reported). - **`internal/hub/collect.go` + `cmd/felhom-agent/main.go`:** `Collector.SetLeafFingerprint(fp)` threads the `fp` from `EnsureLeaf` (the SAME value the LOADED/REGENERATED log reports) into every report, next to `Capabilities`. ## Tests (green: `go build/vet/test ./...`) `TestCollect_LeafFingerprint`: the report carries the fp when set, and `""` when unset (local API disabled) — companion proving the threading is what populates it. The golden + contract + field-names tests updated; the cross-repo golden mirrors `leaf_fingerprint` (byte-identical with the hub copy). ## Live validation (felhom-pve) — PASS Deployed 0.48.0 (`leaf LOADED` fp `60b5974d…`, capabilities 45/45). The hub received the report with `leaf_fingerprint: 60b5974d…` (confirmed in the hub DB), then — during the end-to-end re-key test — a regenerated leaf (`82078fab…`) and its restore (`60b5974d…`) both rode the report stream and the hub raised `host_leaf_changed` on the change (see felhom.eu/REPORT.md). Final state: leaf == pin `60b5974d…`, capabilities 45/45, channel recovered. ## NOT changed The pin/transport, the token store, the sudoers/capability surface, the swap, the channel-health logic. Report contract + collector threading only.