A relay that accepted, authenticated and subscribed and then closed cleanly made the read loop return without raising, so _websocket_loop reconnected immediately with no backoff and never flipped health to "retrying". The read loop now raises ConnectionError on StopAsyncIteration so the clean close takes the same backoff + degraded path as an idle or send-side disconnect.