Part of #74. References @ 17980ad.
Protocol-crate groundwork so hosts and clients can express N viewers and one movable input focus.
- Extend the handshake so a client declares intent (view-only vs input-capable) and the host answers with current focus state. Today input authorization is implied by connecting with input capabilities (
crates/sigil-protocol/src/handshake.rs:21-135, negotiated_input_capabilities in crates/sigil-host/src/server.rs:4996-5027); after this change, capabilities express eligibility and a separate focus state expresses possession.
- New control messages:
FocusRequest, FocusGrant, FocusRevoke, FocusState (broadcast to all viewers on every change, carrying holder identity and reason: granted, released, revoked, holder-disconnected). Versioned, bounded, reserved-byte-strict like the existing message families.
- Add a controller-slot field (u8) to gamepad input messages now; this phase validates it as 0 and rejects others. This is the phase-2 hook the epic calls out; adding it later would re-version the input protocol.
- Presence: a bounded viewer-roster message (count and display identities) so Portal can render who is connected. Decide whether roster identity is the enrollment name or an opaque per-session handle; do not leak peer public keys to other viewers by default.
- Version negotiation: old clients must keep working against new hosts in 1:1 mode; a new client on an old host must degrade to the current implicit-focus behavior.
Non-goals: no transport changes, no host arbitration logic (that lives in the registry and authorization issues). Deliverable is types + encode/decode + property tests in sigil-protocol, unused by the host until the registry issue lands.
Part of #74. References @ 17980ad.
Protocol-crate groundwork so hosts and clients can express N viewers and one movable input focus.
crates/sigil-protocol/src/handshake.rs:21-135,negotiated_input_capabilitiesincrates/sigil-host/src/server.rs:4996-5027); after this change, capabilities express eligibility and a separate focus state expresses possession.FocusRequest,FocusGrant,FocusRevoke,FocusState(broadcast to all viewers on every change, carrying holder identity and reason: granted, released, revoked, holder-disconnected). Versioned, bounded, reserved-byte-strict like the existing message families.Non-goals: no transport changes, no host arbitration logic (that lives in the registry and authorization issues). Deliverable is types + encode/decode + property tests in
sigil-protocol, unused by the host until the registry issue lands.