c23da52795
When the user mutes mid-broadcast, `NestMoqLiteBroadcaster`'s send loop just `continue`s past the mute check, leaving the current group's QUIC uni stream open with no FIN. The watcher's `Container.Consumer.#runGroup` parks on `await group.consumer.readFrame()` waiting for either another frame or a stream FIN — and gets neither. kixelated/hang's UI surfaces this as a "stalled" indicator on the speaker tile while we're muted, which is wrong: we're muted, not stalled. FIN the open uni stream once on the unmuted→muted edge via a `wasMuted` latch that the muted→unmuted edge clears. Doesn't change the timestamp counter — it still advances on muted frames so an unmute's first timestamp reflects the muted duration as a real wall- clock gap (not a collapse to zero). `runCatching` around endGroup because a transport-side close racing with the FIN is non-fatal — the broadcaster's terminal-failure path picks up real breakage on the next live frame. Also resets `framesInCurrentGroup` to 0 so the post-unmute send path opens a fresh group cleanly via the standard `currentGroup ?: openNextGroupLocked()` branch in `PublisherStateImpl.send`. https://claude.ai/code/session_014JfZJHSTvyYYWJbC9VbB47