feat(lobby): implement bounded WebSocket sessions and countdown

This commit is contained in:
2026-09-04 02:13:26 +03:00
parent b10c7f5972
commit 996bda9567
21 changed files with 2040 additions and 64 deletions
+53 -6
View File
@@ -274,12 +274,11 @@ access-point provisioning flow.
invalid two-field configuration request returned HTTP 400. A final board
reboot again loaded and connected to `Mazda7`, proving the rejected request
did not alter the persisted valid configuration.
- All five acceptance criteria therefore have recorded evidence. Milestone 004
remains `NOT_STARTED`.
- All five acceptance criteria therefore have recorded evidence.
## Milestone 004 — HTTP, WebSocket, sessions, and lobby
**Status:** `NOT_STARTED`
**Status:** `COMPLETE`
### Objective
@@ -313,9 +312,57 @@ observers, and an owner-controlled lobby.
### Evidence
Completion evidence is not yet available because this milestone has not
started. Required evidence includes protocol-test output, six-client connection
results, session restoration tests, and lobby authorization tests.
- On 2026-09-04, `./scripts/run_host_tests.sh` reported
`health state tests: PASS`, `wifi configuration tests: PASS`,
`configuration NVS tests: PASS`, `provisioning protocol tests: PASS`,
`lobby and protocol tests: PASS`, and `web asset reproducibility: PASS
(6bdc7d380994cd302019c8634570953881cda035757d577fe2b1f54742a95f33)`.
The deterministic lobby tests cover the two-player and four-observer bounds,
duplicate-name and excess-role rejection, Player 2 start rejection, Player 1
readiness enforcement, restoration to the original slot, and the shared
countdown activation instant. Protocol tests cover valid envelopes plus
malformed, oversized, duplicate-field, unsupported-version, unknown-type,
invalid-payload, and stale-sequence handling without state mutation.
- A clean production build followed by
`/home/sasa/.platformio/penv/bin/pio run -e esp32-c6-devkitm-1 --target
upload --upload-port /dev/ttyACM0` completed with `[SUCCESS]` in 50.31
seconds. PlatformIO reported 47,508 bytes of RAM and 1,005,274 of 2,097,152
application bytes in use; the independent partition check reported
`firmware.bin uses 1005904/2097152 bytes in partition factory`. The upload
identified the physical target as an ESP32-C6FH4 with 4 MB embedded Flash,
wrote the bootloader, partition table, and application, and hash-verified all
three images.
- `/home/sasa/.platformio/penv/bin/pio run -e esp32-c6-devkitm-1 --target
buildfs` completed with `[SUCCESS]` and reported
`littlefs.bin uses 2031616/2031616 bytes in partition littlefs`. The two
deterministic compressed browser assets total 5,970 bytes, below the 1.5 MiB
web-payload limit and within the unchanged 1,984 KiB LittleFS partition.
- The final firmware booted through the bounded station retry policy and served
its fallback network while the configured `Mazda7` access point was
unavailable. A live `GET /health` returned
`{"status":"serving","healthy":true,"version":"0.4.0","errorCode":0}`.
The host retained its independent Ethernet route while its Wi-Fi interface
joined the device access point, so device testing did not interrupt the
development connection.
- On the physical board,
`python3 scripts/ws_protocol_client.py 192.168.4.1 --verify` reported
`malformed and stale message rejection: PASS`,
`six-client capacity: PASS (2 players + 4 observers)`,
`duplicate player name: PASS`, `seventh connection rejection: PASS`,
`Player 2 start authorization: PASS`,
`session refresh restoration: PASS (Player 2 retained slot 2)`,
`authoritative countdown: PASS (activationAtMs=72223)`, and
`oversized message rejection: PASS`. The countdown payload received by both
player connections was byte-for-byte equivalent, and both subsequent active
events carried the same server activation timestamp.
- During a six-client physical run, the gateway logged all six bounded
admissions and `Six-client heap: free=305388 bytes, largest=278528 bytes`;
it rejected a seventh connection and a 513-byte frame. Session tokens were
returned only in private session messages and were absent from shared lobby
snapshots. The observer protocol exposes no mutating command, while start
authorization is resolved from the server-owned session and player slot.
- These results provide concrete host and physical-device evidence for all six
acceptance criteria. Milestone 005 remains `NOT_STARTED`.
## Milestone 005 — Symmetric maze generation and validation