Skip to content

feat(ambient): emit recovery_failing health signal for the core alert - #42

Merged
WingedGuardian merged 1 commit into
mainfrom
feat/ambient-recovery-failing
Jul 22, 2026
Merged

feat(ambient): emit recovery_failing health signal for the core alert#42
WingedGuardian merged 1 commit into
mainfrom
feat/ambient-recovery-failing

Conversation

@WingedGuardian

Copy link
Copy Markdown
Owner

What

When device auto-recovery is armed, the ambient bridge now emits a
recovery_failing verdict into ambient_health.json so the Genesis core can alert
when auto-recovery has engaged but still can't restore the capture device.

New health-JSON keys (present only when recovery is armed — absent otherwise, so
installs without recovery are byte-unchanged):

  • recovery_failing (bool) — True once the device has been dark ≥
    recovery_escalation_dark_s (default 4h, comfortably past the reboot window so
    recovery has definitively stopped trying) andrecovery_escalation_min_reboots
    reboot attempts since it was last seen failed to bring it back.
  • failed_reboot_count, device_dark_since (ISO), last_reboot_error.

Details

  • RecoveryState tracks a persisted reboots_since_seen counter + last error,
    reset on reconnect (mark_seen) — so the signal is restart-safe (survives a
    bridge restart mid-wedge; keyed off the persisted last-seen, not the in-process
    connection timer).
  • reboot_device now returns (ok, error). The error is a sanitized
    classification (a fixed phrase or the exception class name) — the device IP and
    the noise PSK are logged locally only and never placed on the health JSON, which
    is surfaced onward to the dashboard.
  • Two new env knobs: AMBIENT_RECOVERY_ESCALATION_DARK_S (14400),
    AMBIENT_RECOVERY_ESCALATION_MIN_REBOOTS (1). State files written before this
    change load with sane defaults (0 / None).

Tests

test_esphome_recovery.py extended: the (ok, error) contract + sanitized-error
assertions (no IP in the returned reason), the recovery_status truth table,
counter reset/persistence across a restart, and back-compat loading. Full file
green; ruff clean.

🤖 Generated with Claude Code

…re alert

When auto-recovery is armed, the health JSON now carries recovery_failing,
failed_reboot_count, device_dark_since (ISO), and last_reboot_error so the
Genesis core can alert when the device has been dark past the escalation
threshold AND the reboot attempts couldn't restore it. Restart-safe: the
since-seen counter + last-seen are persisted (survives a bridge restart
mid-wedge). last_reboot_error is a SANITIZED classification (exception class
name / fixed phrase) — the device IP/PSK is logged locally only, never emitted.
reboot_device now returns (ok, error); adds recovery_escalation_dark_s (4h) and
recovery_escalation_min_reboots (1) knobs. Keys are absent when recovery is
disabled, so installs without recovery are unchanged.

Refs: e6e68d70 (ambient silent-dark escalation)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@WingedGuardian
WingedGuardian merged commit 123aa65 into main Jul 22, 2026
4 checks passed
@WingedGuardian
WingedGuardian deleted the feat/ambient-recovery-failing branch July 22, 2026 20:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant