Files
Rendezvous/docs/architecture/0006-compatible-session-browser.md
KyuubiYoru a9a2b3db35
quality-gate / quality (push) Successful in 57s
feat: add bounded compatible session browser (#8)
Closes #8
2026-07-16 06:06:29 +02:00

2.8 KiB
Raw Permalink Blame History

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 1100, 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.