Browser co-op kitchen game: FastAPI + native WebSockets, server-authoritative 20 Hz simulation, in-memory anonymous lobbies, data-driven YAML levels, Canvas 2D vanilla ES-module client with locally authored SVG art and no external CDNs. .agents/PLAN.md records the LOCKED decisions; .agents/user_stories/ holds the 12 flow contracts; .agents/phases/todo/ breaks them into 14 sequential, test-gated phases (71 task files), each leaving the app launchable and the suite green. LLM-Generated: true
3.9 KiB
3.9 KiB
Phase 06 — Realtime WebSocket protocol
Story: US-02_join_by_code, US-03_ready_up_and_start, US-05_orders_score_and_result (delivery), US-09_disconnect_and_rejoin (partial)
Context: .agents/PLAN.md §7 (protocol), §4 (data flow, snapshot), A3, A4, A14
Objective
Put the tested room core on the wire: /ws/{code} with a versioned JSON protocol, strict
inbound validation (shape, size, rate, per-state legality), input ingestion with
sequence numbers, and snapshot/event broadcasting at the configured rate — so two browsers
can already play a round. This is the last phase before the game becomes visible.
Dependencies
05_anonymous_lobbies_and_room_lifecycle(complete) — supervisor,Room, lobby payloads, session store04_kitchen_pipeline_and_scoring(complete) — sim state and result payloads to encode
Tasks
01_protocol_models_and_wire_contract.md—server/protocol.py, message models,docs/PROTOCOL.md, protocol version02_ws_endpoint_and_handshake.md—/ws/{code}, origin/token checks, caps, error codes, single-socket-per-token03_input_ingestion_and_validation.md—inputhandling, seq discipline, clamping, per-state whitelist04_snapshot_and_event_encoding.md—server/encoding.py, quantized snapshots, event batching,SNAPSHOT_HZpacing, size budget05_heartbeat_disconnect_and_seat_grace.md— heartbeats, seat grace on drop, ghost parking, rejoin within the window06_websocket_integration_suite.md— two-socket full round, malformed flood, rate limit, size cap, latency injection flag
Testing & Quality
- Unit: every protocol model's accept/reject surface; encoder quantization and size; whitelist per room state; seq stale/rollback rules.
- Integration (real WebSockets via
TestClient/websocketsagainst a live uvicorn on an ephemeral port): handshake, welcome shape,ready→start→countdown→snapstream, two clients both reach the sameroundpayload, unknown message types, oversized frame, message flood, wrong protocol version close code4400, second socket evicts first, abrupt close keeps the seat for the grace window and a reconnect resumes snapshots. - Budget tests: encoded snapshot ≤ 1.5 KB for a 4-player level-1 state; downlink ≤ 60 KB/s per player over a measured 5 s window.
- Coverage: >90% on new/modified code;
server/protocol.py,server/encoding.py≥ 95%. - The phase is "Complete" only when the entire project test suite passes 100%.
Documentation & Consistency
- The final pass reviews
README.mdandAGENTS.mdin full against the project as it stands after this phase — fixing every inconsistency found, including pre-existing ones not caused by this phase. docs/PROTOCOL.mdis the deliverable contract: message tables, close codes, error codes, size/rate limits, versioning policy, and a sequence diagram of a full round. Every field in code must appear in the doc (a test compares model field sets to the doc tables).
Completion Criteria
- a Python
websocketsclient can: create room over HTTP → connect/ws/{code}→hello→ready→ hoststart→ receivecountdownthen ≥ 20snapframes → drive a scripted input toround - two clients in one room receive identical
roundpayloads - protocol version mismatch closes with code
4400and a clean client message - oversized (>
max_message_bytes) and flood (>max_inputs_per_s) cases are refused with the documented error/close codes and no memory growth - snapshot ≤ 1.5 KB and downlink ≤ 60 KB/s measured by tests
docs/PROTOCOL.mdmatches the implemented models (test-enforced) and includes the round sequence diagram- full test suite 100% passing, coverage >90%
- README.md and AGENTS.md are accurate and consistent with the whole project (verified in the final pass)
- no behavior change in completed phases