@@ 115,3 115,24 @@ No automated tests (per `TDD: no`). Manual acceptance:
- `wasm_exec.js` at `$GOROOT/lib/wasm/` — confirmed present for Go 1.26.2 (user's toolchain). Would fail loudly on Go <1.24; acceptable per design's fail-fast principle.
- WASM binary size (~10–20 MB) — known and out of scope per Design.
+
+## Verify
+
+**Result:** passed
+
+Positive:
+- `go build ./...` → clean
+- `go vet ./...` → clean
+- `GOOS=js GOARCH=wasm go build` → produces valid wasm (WebAssembly MVP, ~12 MB)
+- `make build` → `bin/ftl-shape` Mach-O arm64
+- `make build-wasm` → `web/main.wasm` + `web/wasm_exec.js` copied from `$GOROOT/lib/wasm/`
+- `make -n play-web` → recipe expands to platform-detected open + `wasmserve .`
+- Native binary smoke: ran `bin/ftl-shape` 2s in background, window alive, clean kill
+- Browser smoke: served `web/` via `python3 -m http.server`, loaded in Chrome, WASM instantiated and rendered 5 colored rooms with labels (Pilot, Weapons, Shields, MedBay, Engines) on dark background at 1280×720. Console shows only a benign 404 for `favicon.ico`.
+
+Invariants:
+- `ship.go` has no Ebitengine import (`grep` returned empty)
+- No `//go:build` directives, no platform-suffixed `*_js.go` / `*_windows.go` / `*_linux.go` / `*_darwin.go` files
+- `TilePx` references confined to `render.go` — pixel conversion happens only at render time
+- No external asset files (png/jpg/wav/ttf/otf) anywhere in the repo
+- `git status` clean after `make build` + `make build-wasm` — `.gitignore` correctly excludes all artifacts