9e8c8b4ace02630cee96f45af954ad30f1a274c0
Core reconstructed PeerState in five command branches (join, mute toggle, avatar change, screen-share start/stop), each repeating the full field list. Factor a SelfPresence struct holding the sticky identity fields (name + avatar) with a to_state(is_muted, addr, sharing) builder that folds in the volatile per-announce fields, so the PeerState literal lives in one place. This is the precondition for adding a broadcast game-presence field without editing every call site. No behavior change. +1 unit test (359 lib total path). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>