2.8 KiB
ADR 0006: bounded compatible session browser
- Status: Accepted
- Date: 2026-07-16
- Tracking: #8
Decision
The public list endpoint requires game, environment, and exact gameplay protocol. Region is optional, page size is 1–100, and callers may exclude sessions whose advisory current-player count has reached the advertised maximum. Lists contain public sessions only and only while both lease and authenticated host presence are fresh. Unlisted sessions never appear in a list; they may be retrieved directly by their 128-bit unguessable listing ID only when the caller also supplies the exact game, environment, and protocol scope.
Results use ascending opaque listing ID as a deterministic keyset. A cursor carries
the last ID plus every compatibility/filter field, a five-minute expiry, and an
HMAC-SHA256 signature under a per-process key. Tampering, expiry, or reuse with a
different tenant/protocol/region/full filter returns InvalidRequest. Restart
rotates the key, matching the loss of ephemeral listings.
Pagination is a bounded live view, not a database snapshot. A record that remains eligible and whose ID is greater than the cursor is returned exactly once. Records removed or made stale disappear immediately. A record created after a page whose ID sorts before that page's cursor is outside that traversal; callers refresh from the first page to discover new sessions. This avoids skips or duplicates among stable eligible records without retaining per-browser snapshot state.
The store reads at most page size plus one record. The service serializes against the 256 KiB response ceiling and shortens a page before returning it when metadata makes the requested count too large. A continuation cursor is emitted whenever an extra or byte-trimmed record remains. All cursor, page, metadata, property, scalar, and collection sizes are bounded before untrusted allocation can grow without a ceiling.
Browser DTOs are fresh copies containing only opaque listing ID, exact compatibility, region, visibility/trust presentation, advisory capacity, build/display labels, and policy-validated string metadata. They contain no observed endpoint, lease, capability, ticket, credential fingerprint, derivation salt, principal subject, or store key. Metadata is display text: JSON encoding escapes markup, but game UI must still render values as text and must never execute markup, interpret endpoints, or use metadata for authorization.
Consequences
- Cross-game, cross-environment, incompatible, stale, revoked, expired, unlisted, and optionally full sessions are removed before response construction.
- Direct unlisted lookup is suitable for an out-of-band invite carrying the opaque ID; human join codes remain future work and require their own bounded abuse model.
- Host capacity remains advisory. The host makes the final admission decision.