Global singleton observing every account's online/offline edge:
- Pure per-UIN debounce state machine (debounce.ts): an offline surviving
debounceSeconds fires "offline"; recovery fires the paired "online"; a
self-heal within the window fires nothing; a cold online fires nothing.
- NotificationManager (manager.ts): renders each opted-in + enabled channel's
body template and POSTs it (single attempt + timeout, JSON), recording the
outcome in a bounded in-memory history (lost on restart). Side effects
(config/channelIds/post/clock) are injected for testability.
- BridgeManager: single-callback setters → additive listeners so OneBotManager
and NotificationManager observe independently; close edge now carries the
bridge (read nickname before dispose); fire-all with per-listener try/catch.
- Wired into the composition root, bound after OneBotManager.
Tests: debounce machine (pure, all misfire sequences) + manager (selectChannels,
dispatch, history cap, fake-timer self-heal/pairing). 23 green, typecheck clean.
Adversarial review: 0 blockers / 0 should-fix (2 NITs applied).