127 lines
5.7 KiB
Markdown
127 lines
5.7 KiB
Markdown
# 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.
|
||
- No firmware-embedded Wi-Fi credentials are required. On first boot, join the
|
||
open `Battleship-open` network and open `http://192.168.4.1/setup` if the
|
||
captive portal does not appear.
|
||
|
||
## 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://<device-address>/`. The web application and API must be used only on
|
||
the local network. The API health check is:
|
||
|
||
```sh
|
||
curl http://<device-address>/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.
|
||
|
||
## Network configuration and local-security limitation
|
||
|
||
The `/setup` screen and `/api/network/*` routes are intentionally unauthenticated
|
||
so a new device can be configured through either the fallback AP or its regular
|
||
local address. Any client that can reach the device can change or delete the
|
||
saved Wi-Fi configuration. The open AP and plain local HTTP do not protect a
|
||
submitted password from a nearby network observer. Configure the board only on
|
||
a network you trust, and do not use this feature for credentials that require
|
||
strong confidentiality.
|
||
|
||
## 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.
|
||
- For a saved network that does not become operational, the serial log records
|
||
the profile outcome, Wi-Fi disconnect reason, the 30-second timeout, AP
|
||
startup result, and STA/AP addresses. `fallback AP active` means that
|
||
`Battleship-open` should be available; connect to it and open
|
||
`http://192.168.4.1/setup`. These diagnostics never include the password.
|
||
- A corrupt or unsupported saved record is left intact for diagnosis but is
|
||
ignored for that boot; the board starts `Battleship-open`. Do not erase NVS
|
||
or flash as an initial recovery step.
|
||
- 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`.
|