phase: 07_canvas_client_and_hud

**Final report — phase 07 final verification pass**

- **Verified:** all 5 tasks present in `complete/`; app boots (`/healthz` 200, `/` 200, static + atlas + `/api/levels` served); `docs/CLIENT.md` module map matches the on-disk `app/static/` tree; no code defects found.
- **Tests/lint/coverage:** `bash .agents/validate.sh` → ruff clean, pyright 0 errors, `undercooked-levels validate` pass, **full pytest 1838 passed, 97.21% coverage (floor 90%)**, slow sim stage 2 passed, repo hygiene clean. `uv run pytest tests/e2e -q` → **53 passed** (all 8 suites added this phase).
- **Criteria:** (1) two tabs create→join→ready→start→serve one dish, keyboard only — green via `test_us01/02/03/04` ✔; (2) e2e green ✔; (3) canvas non-blank, pixels change after a move — `test_us04_render_smoke` ✔; (4) HUD score within 200 ms of the `served` event — asserted, green ✔; (5) zero console errors + zero off-origin requests — `test_atlas_loads` / `test_us01_landing_surface` ✔; (6) `docs/CLIENT.md` matches layout ✔; (7) 100% suite + 97.21% ✔; (8) docs pass below ✔; (9) no regression in completed phases (all prior suites green) ✔.
- **README.md fixed:** status still said "next pending phase is 07" → now 07 complete, 08 pending; the phase-07 client text buried in the phase-05 bullet → its own "canvas client, art, HUD (phase 07)" bullet; stale "What does not exist yet" (claimed movement/controls missing) → rewritten to phases 08–14; "once the room flow ships" → "live in the browser today"; Layout `app/static/` "renderer arrives with the rest of phase 07" → full shipped-client map; Layout `docs/` "CLIENT lands with phase 07" → `CLIENT.md` listed; added `gen_art_index.py` Layout entry.
- **AGENTS.md fixed:** "the eight screens" (7 listed) → "the seven screens" (+ `dom.js` is the shared builder, not a screen); e2e naming line → notes the non-story guard `test_atlas_loads.py`.
- **Decisions:** no code changes were needed; only the two doc fixes above. Docs re-verified by `test_docs_commands`/`test_docs_index` (44 passed) plus the final full gate.
- **Next pending phase:** `08_client_prediction_and_touch`.
This commit is contained in:
2026-10-10 18:03:52 -04:00
parent f26849c1f3
commit 95ca3fd1fa
78 changed files with 13650 additions and 259 deletions
+61
View File
@@ -0,0 +1,61 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32">
<!-- Undercooked tileset (phase 07, task 01). One <symbol> per drawable,
32x32 viewBox, hand-authored vector cartoon. Served from
app/static/assets/ and indexed by index.json. -->
<symbol id="tile-floor" viewBox="0 0 32 32">
<rect width="32" height="32" fill="#b98a5c"/>
<path d="M0 10.5 H32 M0 21.5 H32" stroke="#a1734c" stroke-width="1.5" fill="none"/>
<path d="M9.5 0 V10.5 M23 10.5 V21.5 M14.5 21.5 V32" stroke="#a1734c" stroke-width="1" fill="none"/>
</symbol>
<symbol id="tile-floor-1" viewBox="0 0 32 32">
<rect width="32" height="32" fill="#b98a5c"/>
<path d="M0 10.5 H32 M0 21.5 H32" stroke="#a1734c" stroke-width="1.5" fill="none"/>
<path d="M9.5 0 V10.5 M23 10.5 V21.5 M14.5 21.5 V32" stroke="#a1734c" stroke-width="1" fill="none"/>
<ellipse cx="24" cy="5" rx="2.6" ry="1.7" fill="#a1734c"/>
<ellipse cx="24" cy="5" rx="1.1" ry="0.7" fill="#8d6340"/>
</symbol>
<symbol id="tile-floor-2" viewBox="0 0 32 32">
<rect width="32" height="32" fill="#b98a5c"/>
<path d="M0 10.5 H32 M0 21.5 H32" stroke="#a1734c" stroke-width="1.5" fill="none"/>
<path d="M9.5 0 V10.5 M23 10.5 V21.5 M14.5 21.5 V32" stroke="#a1734c" stroke-width="1" fill="none"/>
<path d="M3 15 L8 15 M25 25 L30 25 M5 27 L10 27" stroke="#ab7d52" stroke-width="1.4" stroke-linecap="round" fill="none"/>
</symbol>
<symbol id="tile-floor-3" viewBox="0 0 32 32">
<rect width="32" height="32" fill="#b98a5c"/>
<path d="M0 10.5 H32 M0 21.5 H32" stroke="#a1734c" stroke-width="1.5" fill="none"/>
<path d="M9.5 0 V10.5 M23 10.5 V21.5 M14.5 21.5 V32" stroke="#a1734c" stroke-width="1" fill="none"/>
<rect x="13" y="13.5" width="6" height="6" rx="1.6" fill="#c4976b"/>
</symbol>
<symbol id="tile-floor-4" viewBox="0 0 32 32">
<rect width="32" height="32" fill="#b98a5c"/>
<path d="M0 10.5 H32 M0 21.5 H32" stroke="#a1734c" stroke-width="1.5" fill="none"/>
<path d="M9.5 0 V10.5 M23 10.5 V21.5 M14.5 21.5 V32" stroke="#a1734c" stroke-width="1" fill="none"/>
<circle cx="6" cy="6" r="0.9" fill="#ab7d52"/>
<circle cx="27" cy="16" r="0.9" fill="#ab7d52"/>
<circle cx="12" cy="27" r="0.9" fill="#ab7d52"/>
<circle cx="24" cy="28" r="0.7" fill="#ab7d52"/>
</symbol>
<symbol id="tile-counter" viewBox="0 0 32 32">
<rect width="32" height="32" fill="#d8c49a"/>
<rect y="24" width="32" height="8" fill="#a5825a"/>
<rect y="22" width="32" height="3" fill="#8a6b45"/>
<path d="M3 3 H29" stroke="#c4b088" stroke-width="1.4" stroke-linecap="round" fill="none"/>
</symbol>
<symbol id="tile-wall" viewBox="0 0 32 32">
<rect width="32" height="32" fill="#6b5a48"/>
<path d="M0 10.5 H32 M0 21.5 H32" stroke="#5a4b3b" stroke-width="1.5" fill="none"/>
<path d="M16 0 V10.5 M8 10.5 V21.5 M24 10.5 V21.5 M16 21.5 V32" stroke="#5a4b3b" stroke-width="1.5" fill="none"/>
</symbol>
<symbol id="tile-void" viewBox="0 0 32 32">
<rect width="32" height="32" fill="#241f1a"/>
<path d="M-4 36 L36 -4 M-4 24 L24 -4 M8 36 L36 8 M20 36 L36 20" stroke="#3a322a" stroke-width="1.4" fill="none"/>
</symbol>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB