park() detached the live session only after session.dispose() resolved,
so during the dispose window the registry still exposed ref.session at
idle status. Concurrent ensureLive()/hub-send handed out or injected into
the dying session, reporting success while the message was dropped once
detach committed.
- Replace the #parking Set guard with a #parks map of in-flight park state
that is cancelable until the session is detached.
- park() now yields a cancel window, then detaches + flips status to
parked BEFORE dispose(), and coalesces concurrent park calls.
- ensureLive() cancels a pre-detach park (keeps the live session) or waits
for detach+dispose then performs one coalesced revive; never returns a
disposing session.
- release()/dispose() drain any in-flight park; the idle re-arm skips while
a park owns the transition.
- IrcBus.send() gates parkable recipients through ensureLive and derives
the revived receipt from session identity, so receipts/unread counts
reflect actual delivery.
Fixes#5633