multiplayer-next.md carried the Phase 8 checklist but not the numbered
tasks with acceptance criteria that work actually gets picked up from.
That format lives in multiplayer-todo.md section 7, which already hosts
Phase 7 as in-progress, so Phase 8 goes there too.
Tasks 8.1-8.20 across four groups: backend service (identity, rating
store, Glicko-2, queue), server orchestration and autoscaling, playlists
and client UI, and keeping Docker/CI green. Section 0's short list gains
an index entry, and the status header now says Phase 8 is a 1.0 launch
blocker and the first phase to add a component outside the Godot
project.
Three entries are measured findings rather than plans, each of which
would break a naive implementation: stdout block-buffering making a
log-grep readiness probe hang forever, the hardcoded 7777/udp port
preventing more than one match per host, and compose.phase6-smoke.yml's
dependence on the exact behaviour allocation work would change.
Also fixes a now-false cross-reference: a Phase 4 note read 'not
Phase 8' meaning 'not a later phase', written when no Phase 8 existed.
CLAUDE.md's 'never add new work to multiplayer-todo.md' rule gains the
new-phase exception it always had in practice - Phase 7 was already
there.
The document had no one place that answered "what is left". Outstanding
items were spread across two phase-gate lines, two phase tables, §11, and
prose buried in the phase notes - and the name-keyed slot-reservation
hijack, which an adversarial review demonstrated with a real three-process
run, was not written down anywhere at all. It existed only in a
conversation.
New §0 indexes everything not done, in four groups: verification a
machine cannot do (the Phase 4 playtest, the Phase 5 3v3 gate), known
defects left unfixed with their severity, the one open architectural
question, and the two unstarted phases. Each row points at the detailed
write-up rather than duplicating it, and the phase gates now point back.
§11 gains the identity defect in full: reservations match on
slot.player_name and nothing else, with no uniqueness constraint on names
anywhere, so a peer joining during the 30s window with a departed
player's name is handed their slot, ship and team. A bespoke token would
be half of task 7.4 thrown away, so it stays deferred - with the
consequence stated plainly rather than implied, and listed as a
precondition of Phase 6's internet-facing gate.
Also refreshes the stale status paragraph and task 5.10 for the replay
log's reject recording, write-failure handling, close(), and dump tool.