Scaffold project and author 14-phase roadmap

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
This commit is contained in:
2026-10-05 17:05:56 -04:00
commit f84c6ebaef
105 changed files with 5752 additions and 0 deletions
@@ -0,0 +1,55 @@
# 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 store
- `04_kitchen_pipeline_and_scoring` (complete) — sim state and result payloads to encode
## Tasks
1. `01_protocol_models_and_wire_contract.md` — `server/protocol.py`, message models, `docs/PROTOCOL.md`, protocol version
2. `02_ws_endpoint_and_handshake.md` — `/ws/{code}`, origin/token checks, caps, error codes, single-socket-per-token
3. `03_input_ingestion_and_validation.md` — `input` handling, seq discipline, clamping, per-state whitelist
4. `04_snapshot_and_event_encoding.md` — `server/encoding.py`, quantized snapshots, event batching, `SNAPSHOT_HZ` pacing, size budget
5. `05_heartbeat_disconnect_and_seat_grace.md` — heartbeats, seat grace on drop, ghost parking, rejoin within the window
6. `06_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`/`websockets` against a live uvicorn on an
ephemeral port): handshake, welcome shape, `ready`→`start`→`countdown`→`snap` stream,
two clients both reach the same `round` payload, unknown message types, oversized frame,
message flood, wrong protocol version close code `4400`, 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.md` and `AGENTS.md` in 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.md` is 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 `websockets` client can: create room over HTTP → connect `/ws/{code}` → `hello` → `ready` → host `start` → receive `countdown` then ≥ 20 `snap` frames → drive a scripted input to `round`
- [ ] two clients in one room receive identical `round` payloads
- [ ] protocol version mismatch closes with code `4400` and 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.md` matches 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