Hub: identity now comes from the gs_session cookie riding the websocket
handshake (auth._uid_from_cookies -> username per connection; spoof-proof).
On the read-only public hub the commune requires sign-in. Rooms are hosted:
create names the room; invitations go to present, signed-in users by
username; accept/decline; leave any time (host leaving disbands); the host
allocates sections, members claim free ones (hub arbitrates conflicts); and
voice-state is relayed ONLY from the section's holder — enforced server-side.
Roominfo broadcasts keep every member's view of the room identical.
Client: invitation inbox with join/decline in the commune panel, host desk
(invite + allocate rows), identity from the signed-in account, right-click
voice items show holders ("held by X"), presence tag survives reconnects.
Verified full protocol on the live test hub: host -> invite delivered ->
accept -> roominfo both sides -> host allocates bass to peer -> peer's state
applied on host's instrument (1.44x, menu shows holder).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>