docs: record the closed root blocker and the new probe/rotation contract

docs/MATCHMAKING.md is the stated source of truth for this design, so it
changes first: the probe challenge endpoint and why probing gates
matching rather than merely improving it, and the key-ID rotation
procedure that makes overlapping-key rotation concrete.

multiplayer-next.md §0's root blocker is closed rather than deleted --
what it was, why it blocked everything, and how it was resolved, since
the reasoning is what a future reader needs. Tasks 7.6, 8.15 and 8.31
updated to what actually remains, which in every case is now external
rather than unbuilt.

TODO.md #14 asked for a join-signing design decision; that decision is
recorded with its rationale. CLAUDE.md no longer says a real deployment
cannot complete a match end to end.
This commit is contained in:
Josh Creek
2026-09-05 11:00:50 +01:00
parent f628ccfd35
commit ccf7d0fbfe
4 changed files with 56 additions and 21 deletions
+22 -1
View File
@@ -95,6 +95,15 @@ matcher, allocator and game-server pods cannot read it. The signer accepts
only allocator-recorded assignments, audits every signature, and supports
overlapping-key rotation.
Join authorisations carry a key ID naming the key that signed them, and that
ID is part of the signed bytes so it cannot be repointed at a different key.
Allocated servers hold the set of currently-valid keys and select by ID, which
is what makes rotation overlapping rather than breaking: publish the new key
everywhere, move the allocator's active key ID to it, then drop the retired key
once no live match can still reference it. The key set is delivered as a JSON
map of key ID to base64 key, mounted from the same Secret by both the allocator
Deployment and the Fleet.
## 3. Control-plane architecture
Use one repository and shared domain packages, with independently runnable
@@ -169,7 +178,19 @@ The client submits its recent opaque Steam ping location plus nonce-bound
active-probe responses from each regional endpoint; it does not submit the RTT
used for placement. The backend validates a 30-second freshness window and
nonce, then uses the Steam coordinator SDK and probe timings to compute the
regional matrix. A predicted/observed discrepancy over 25 ms or 30% (whichever
regional matrix.
The nonce comes from `POST /v1/probes/{region}/challenge`, which the client
calls before `POST /v1/probes/{region}`. The challenge is single-use and
durable rather than per-process, because any control-plane replica may serve
the answer to a challenge another replica issued. The recorded RTT is the
interval the backend measures between issuing the challenge and receiving the
answer, which is what keeps client-reported latency out of placement entirely.
Probing is a precondition for matching, not an optimisation: a ticket with no
regional RTT evidence is rejected by the matcher outright, so the client
collects evidence before it creates a ticket. Not every region has to answer --
placement uses whichever did -- but a ticket with none is never queued. A predicted/observed discrepancy over 25 ms or 30% (whichever
is larger) in three matches within 24 hours quarantines the account's samples:
it may queue only in regions whose active probe independently remains under
the ceiling until five clean matches clear the quarantine. The matchmaker: