feat(observer): add observer mode and disconnect recovery

This commit is contained in:
2026-09-05 21:19:52 +03:00
parent d042c3ce90
commit ffdaa299bc
23 changed files with 988 additions and 43 deletions
+62 -13
View File
@@ -657,7 +657,7 @@ Complete the authoritative gameplay mechanics and terminal match outcomes.
## Milestone 008 — Player browser experience
**Status:** `IN_PROGRESS`
**Status:** `COMPLETE`
### Objective
@@ -705,8 +705,7 @@ into the browser.
### Evidence
Implementation is complete, but the milestone remains `IN_PROGRESS` until the
required physical-device and current-stable-browser checks can be run.
Implementation and required verification are complete.
- `bash scripts/run_host_tests.sh` completed successfully. The five focused
browser tests reported keyboard/swipe direction equivalence, intention-only
@@ -750,16 +749,26 @@ required physical-device and current-stable-browser checks can be run.
`606b98e11cbc479bf11bffa9a38d62ddfebce0689f0e3ebf148521190a032fd5`;
`cmp` returned zero, proving byte-for-byte delivery without interrupting the
host's internet connection.
- Live browser validation is blocked. The browser-control runtime returned `No
browser is available`, and its browser inventory was empty. Therefore the
required visual and interaction passes at `412 x 916`, representative tablet
and desktop viewports, and current stable Chrome, Safari, Firefox, and Edge
cannot yet be recorded. Milestone 008 must not be marked `COMPLETE` until
those browser checks pass. Milestone 009 remains `NOT_STARTED`.
- Automated live browser validation was unavailable because the browser-control
runtime returned `No browser is available` and its browser inventory was
empty. The project owner subsequently supplied the required manual browser
evidence recorded below.
- On 2026-09-04, a fresh browser-control inventory check again returned an
empty list. Milestone 008 was therefore changed from `IN_PROGRESS` to
`BLOCKED`; no Milestone 009 implementation work was started.
- On 2026-09-04, the project owner completed the required manual player-UI
checks in Chrome 152, Firefox 155, Safari 26.6, and Edge 152.0.4191.53. The
checks covered the `412 x 916` phone layout without page scrolling,
representative tablet and desktop layouts, keyboard and swipe movement,
the accessible drop-key control, and refresh/session restoration. Together
with the automated browser-contract, projection-security, localization,
offline-asset, payload-size, build, and physical-device evidence above, this
satisfies every Milestone 008 acceptance criterion. Milestone 008 is
`COMPLETE`; Milestone 009 remains `NOT_STARTED`.
## Milestone 009 — Observer mode and disconnect recovery
**Status:** `NOT_STARTED`
**Status:** `IN_PROGRESS`
### Objective
@@ -794,9 +803,49 @@ and reconnect behavior.
### Evidence
Completion evidence is not yet available because this milestone has not
started. Required evidence includes role-authorization tests, four-observer
browser evidence, and timed reconnect/timeout scenarios.
Implementation is complete, but the milestone remains `IN_PROGRESS` until the
required physical-device and observer-browser checks can be recorded.
- On 2026-09-05, `bash scripts/run_host_tests.sh` completed successfully. The
new deterministic recovery suite proved immediate authoritative pause,
rejection of commands without state or effect progression while paused,
restoration before the monotonic 60,000 ms deadline, timeout draw at the
deadline, late-reconnect rejection, and preservation of the remaining 200 ms
finish window across a pause. Observer-role command enqueue returned
`read_only`, and observer connection changes left lobby phase unchanged.
- The same host run reported `game default observer serialization: PASS (688
chunks, maximum 494 bytes)`. The projection contains all 8,192 cells, both
player records and connection states, and remains below the 512-byte message
bound. Seven browser-contract tests passed, covering authoritative chunk
assembly, observer role rendering, absence of observer mutation controls,
bounded fit/zoom/pan behavior, and the Russian sub-`1024 x 768` notice. Web
asset reproducibility passed with SHA-256
`e8d097c7aa1a56cf84748078176b50cc8e2718082edfda35625b6d4436a1fd67`
and 19,133 of 1,572,864 allowed compressed bytes.
- Separate AddressSanitizer and UndefinedBehaviorSanitizer runs of the changed
game-core and disconnect-recovery suites passed without findings; leak
detection was disabled because the sandbox executes under `ptrace`.
`node --check web/player.js`, compilation of
`scripts/ws_protocol_client.py`, and `git diff --check` also passed.
- `/home/sasa/.platformio/penv/bin/pio run -e esp32-c6-devkitm-1` completed
with `[SUCCESS]`, reporting 124,148 of 327,680 RAM bytes and 1,023,742 of
2,097,152 application bytes. The independent partition check reported
`firmware.bin uses 1024368/2097152 bytes in partition factory`. The
corresponding `buildfs` command completed with `[SUCCESS]` and reported
`littlefs.bin uses 2031616/2031616 bytes in partition littlefs`, with all five
compressed assets present.
- Physical verification remains outstanding. The prepared dependency-free
command `python3 scripts/ws_protocol_client.py 192.168.1.50 --verify-m009`
covers simultaneous full-state delivery to four observers, observer mutation
rejection, observer-disconnect continuity, same-state player restoration,
and the real 60-second timeout draw. At the end of this pass,
`/dev/ttyACM0` was absent and `192.168.1.50` was unreachable, so the final
`0.9.0` images could not be uploaded and this scenario could not be run.
- Automated live observer validation also remains outstanding. The
browser-control runtime returned `No browser is available`, and its browser
inventory was empty. A live check at `1024 x 768` or larger plus a smaller
viewport must still confirm full-map fit, updates, zoom, pan, read-only UI,
player connection state, and the required Russian large-screen notice.
## Milestone 010 — On-device integration and resource hardening