diff --git a/docs/RELEASE_GUIDE.md b/docs/RELEASE_GUIDE.md new file mode 100644 index 0000000..cd3f537 --- /dev/null +++ b/docs/RELEASE_GUIDE.md @@ -0,0 +1,107 @@ +# MVP release and acceptance guide + +This guide is the reproducible handoff for the ESP32-C6 Battleship MVP. It +does not replace the locked rules in [MVP.md](MVP.md), the HTTP contract in +[API_CONTRACT.md](API_CONTRACT.md), or the resource limits in +[RESOURCE_BUDGET.md](RESOURCE_BUDGET.md). + +## Release prerequisites + +- Target environment: `esp32-c6-devkitm-1` from `platformio.ini`. +- ESP32-C6FH4, revision v0.2, 4 MB flash; no PSRAM is assumed. +- PlatformIO Core 6.1.19, `espressif32` 7.0.1, ESP-IDF 6.0.1, and + `esp_littlefs` 1.20.4. +- USB serial device: normally `/dev/ttyACM0`; confirm with `pio device list` + before an upload. +- A local `include/wifi_config.h`, copied from `include/wifi_config.h.example`. + It is ignored by Git. Never commit the SSID or password. + +## Build and upload + +From the repository root, run the automated release checks: + +```sh +make -C test/host run +pio run -e esp32-c6-devkitm-1 -t buildfs +pio run -e esp32-c6-devkitm-1 +``` + +Confirm the build remains within the limits in `RESOURCE_BUDGET.md`, then +connect only the intended board and upload the browser assets before firmware: + +```sh +pio run -e esp32-c6-devkitm-1 -t uploadfs --upload-port /dev/ttyACM0 +pio run -e esp32-c6-devkitm-1 -t upload --upload-port /dev/ttyACM0 +``` + +Replace `/dev/ttyACM0` when `pio device list` identifies another device. Do +not use erase targets for this release procedure. + +After boot, obtain the DHCP address from the router or serial log, then open +`http:///`. The web application and API must be used only on +the local network. The API health check is: + +```sh +curl http:///api/health +``` + +The response includes free/minimum heap, largest free block, connection count, +rejected input count, Wi-Fi state, and reset reason. It must not contain Wi-Fi +credentials or session tokens. + +## MVP acceptance checklist + +Record the observed result, device address, browser/device model, and any +deviation for every item. A `PASS` requires all thirteen checks. + +| MVP criterion | Required physical check | +| --- | --- | +| 1 | Cold boot, Wi-Fi join, and Russian interface load from LittleFS. | +| 2 | Two phones complete a human-versus-human game. | +| 3 | One phone completes a human-versus-ESP32 game, including delayed bot turns. | +| 4–6 | Verify fleet rules, rejected duplicate/out-of-turn shots, and role-safe views. | +| 7 | Connect at least two spectators during a game; confirm controls stay unavailable. Repeat to the eight-spectator target. | +| 8 | Interrupt WebSocket connectivity; confirm two-second HTTP fallback and WebSocket recovery. | +| 9 | Refresh each player and a spectator; confirm token-based role/state recovery. | +| 10–11 | Finish, inspect winner and statistics, rematch, then confirm fresh fleets and preserved cumulative totals. | +| 12 | Check narrow-phone and tablet portrait/landscape views, including tabs and side-by-side boards. | +| 13 | Complete 20 representative consecutive games with no reset, hang, or material heap decline. | + +For the final load run, keep two players and eight spectators connected and +sample `/api/health` before, during, and after the run. The final report must +compare minimum free heap, largest free block, reset reason, and observed +state/delivery latency with the hard limits in `RESOURCE_BUDGET.md`. + +## Recovery and incident handling + +- A player refreshes the page to resume with the token stored in browser + `localStorage`; a reboot intentionally invalidates all tokens and resets + game/statistics state. +- If WebSocket is unavailable, leave the page open: the browser uses HTTP + state polling and retries WebSocket at 1, 2, 5, then 10 seconds. +- If the board has a new DHCP address, use the router/serial information and + open the new local URL. No fixed IP or external service is required. +- If LittleFS assets fail to load, repeat `uploadfs` for the confirmed target + port before reflashing firmware. Do not format LittleFS automatically. +- Capture `/api/health`, reset reason, and the exact source revision before + reporting a failure. Never capture or publish tokens or Wi-Fi credentials. + +## Release record template + +Complete this only after all physical checks pass: + +```text +Source revision: +PlatformIO / ESP-IDF / esp_littlefs: +Firmware bytes / LittleFS bytes: +RAM bytes / minimum heap / largest free block: +Largest state payload / maximum observed delivery latency: +Reset reason before and after run: +20-game result: +2-player + 8-spectator result: +MVP criteria 1–13: PASS / FAIL with evidence: +Release decision: PASS +``` + +Post-MVP work begins only after this record is complete and Milestone 017 is +marked `DONE`.