e00d6c1995
Review follow-up: relayAgentsOn() returned [] on ANY error, so a transient profiles.list timeout pushed a fresh union roster missing a LIVE machine's agents — and the gateway-side _target_liveness reads 'absent from a fresh roster' as definitively offline, refusing enqueues with a false runtime_offline during the ~60s window. Failure now returns null (distinct from a genuinely empty list); syncRelayRosters reuses the last good rows for that connection and prunes the cache when a connection truly leaves profileRoutes. Source-contract test pins null-on-failure + cache fallback.