The monitor could hang indefinitely (last event 2026-06-01) after an idle
server disconnect. Root cause: InfoClient::new disables SDK reconnect, so on
disconnect the reader task emitted a single Message::NoData and exited without
dropping the channel sender; the old code swallowed NoData into the catch-all
arm and looped back to recv(), which then blocked forever.
- hyperliquid.rs: create the client with InfoClient::with_reconnect so the SDK
auto-reconnects (~1s) and resubscribes UserEvents on the same channel. Handle
Message::NoData explicitly for observability instead of swallowing it.
- Drop the 180s recv() timeout: the SDK does not forward Pong frames to the
subscription channel, so a quiet market (no fills) is indistinguishable from a
dead connection and any finite timeout caused spurious reconnects, each
opening a blind window where fills (not backfilled on resubscribe) are missed.
- notion.rs: give the TradeSnap HTTP client a 15s timeout. Events are consumed
serially, so a hung screenshot request would otherwise stall all trade syncing.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>