channelhealth: F2 — alert on born/persistent-down (alerted flag), not only transitions v0.91.0

A channel broken at startup/reseed (e.g. controller boots into pin_mismatch) was dashboard-only,
no operator email ever. New 'alerted' flag drives alerting instead of prev=='': born-down
non-transient alerts cycle 1; transient still N>=2; healthy first-obs silent; recovery re-arms.
Red-proof + companion included.

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:
2026-06-29 21:45:57 +02:00
parent 0f7ba7b665
commit b2ad871720
3 changed files with 109 additions and 24 deletions
+15
View File
@@ -1,5 +1,20 @@
## Changelog
### v0.91.0 — F2: alert on born/persistent-down channel (not only transitions) (2026-06-29)
- **What:** closes F2 from the full-stack testrun — a channel failure present at **startup/reseed**
(e.g. the controller boots right after a leaf regen → first observation is `pin_mismatch`) was
dashboard-only, **no operator email, forever**. Now a born-down non-transient reason alerts on cycle 1.
- **`internal/channelhealth/checker.go`:** added an `alerted` flag (have we emitted for the CURRENT
down-spell?). A confirmed down that comes from up/unseeded OR changes reason re-arms (`alerted=false`)
then emits once; a steady down that already alerted does not re-fire; recovery (up) re-arms. Removed
the `prev==""` silent-seed-for-down branch (a born-down IS a real down-spell). Debounce stays intact:
a **transient** born-down (refused) still needs N≥2 (the cold-boot agent-not-yet-up race), and a
**healthy** first-obs still seeds silently.
- Tests: F2 born-down non-transient **red-proof** (one alert cycle 1) + companion showing the old
seed-silent path would not have alerted; born-down transient still debounced; recovery re-arms the
spell. Version `0.90.0 → 0.91.0`.
### v0.90.0 — Controller→agent channel health-check (periodic probe + classified operator alert) (2026-06-29)
- **What:** the next self-health slice — a ~60s scheduler job that proves the controller↔agent
local-API channel, classifies failures, and alerts the operator + dashboard on a state change.