Files
ducoterra 95ca3fd1fa 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`.
2026-10-10 18:03:52 -04:00

107 lines
5.8 KiB
XML

<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32">
<!-- Undercooked station fixtures (phase 07, task 01). 32x32 symbols.
The spawn shelf's stock circle is drawn neutral on purpose: the
renderer tints it per ingredient with the atlas `tint` option. -->
<symbol id="station-spawn_shelf" viewBox="0 0 32 32">
<rect x="4" y="5" width="24" height="4" rx="1.5" fill="#a5825a"/>
<rect x="4" y="22" width="24" height="4" rx="1.5" fill="#a5825a"/>
<rect x="6" y="9" width="3" height="13" fill="#8a6b45"/>
<rect x="23" y="9" width="3" height="13" fill="#8a6b45"/>
<circle cx="16" cy="15.5" r="6" fill="#cfc5b5"/>
<circle cx="16" cy="15.5" r="6" fill="none" stroke="#8a6b45" stroke-width="1.2"/>
</symbol>
<symbol id="station-chop_board" viewBox="0 0 32 32">
<rect x="5" y="9" width="22" height="15" rx="3" fill="#c99e63"/>
<rect x="5" y="9" width="22" height="15" rx="3" fill="none" stroke="#a5825a" stroke-width="1.4"/>
<path d="M9 13 H23 M9 17 H23 M9 21 H23" stroke="#a5825a" stroke-width="0.9" fill="none"/>
<path d="M7 6 L21 4 L21 6 L8 8 Z" fill="#dfe3e6"/>
<rect x="21" y="3.6" width="6" height="2.8" rx="1.2" fill="#6b5a48"/>
</symbol>
<symbol id="station-stove" viewBox="0 0 32 32">
<rect x="3" y="6" width="26" height="21" rx="3" fill="#4a4238"/>
<rect x="3" y="6" width="26" height="21" rx="3" fill="none" stroke="#3a322a" stroke-width="1.4"/>
<circle cx="16" cy="16.5" r="7" fill="none" stroke="#6b625a" stroke-width="2.4"/>
<circle cx="8.5" cy="24" r="1.4" fill="#6b625a"/>
<circle cx="12.5" cy="24" r="1.4" fill="#6b625a"/>
</symbol>
<symbol id="station-stove-off" viewBox="0 0 32 32">
<rect x="3" y="6" width="26" height="21" rx="3" fill="#4a4238"/>
<rect x="3" y="6" width="26" height="21" rx="3" fill="none" stroke="#3a322a" stroke-width="1.4"/>
<circle cx="16" cy="16.5" r="7" fill="none" stroke="#6b625a" stroke-width="2.4"/>
<circle cx="8.5" cy="24" r="1.4" fill="#6b625a"/>
</symbol>
<symbol id="station-stove-working" viewBox="0 0 32 32">
<rect x="3" y="6" width="26" height="21" rx="3" fill="#4a4238"/>
<rect x="3" y="6" width="26" height="21" rx="3" fill="none" stroke="#3a322a" stroke-width="1.4"/>
<path d="M12.5 20.5 q1.5 -2.5 3.5 0 q2 -2.5 3.5 0 z" fill="#ffa63d"/>
<rect x="10" y="11" width="12" height="8" rx="2" fill="#8b8b8b"/>
<rect x="9" y="9.6" width="14" height="2.6" rx="1.3" fill="#a3a3a3"/>
<circle cx="16" cy="8.6" r="1.1" fill="#a3a3a3"/>
</symbol>
<symbol id="station-stove-ready" viewBox="0 0 32 32">
<rect x="3" y="6" width="26" height="21" rx="3" fill="#4a4238"/>
<rect x="3" y="6" width="26" height="21" rx="3" fill="none" stroke="#3a322a" stroke-width="1.4"/>
<rect x="10" y="11" width="12" height="8" rx="2" fill="#8b8b8b"/>
<rect x="9" y="9.6" width="14" height="2.6" rx="1.3" fill="#a3a3a3"/>
<circle cx="16" cy="8.6" r="1.1" fill="#a3a3a3"/>
<path d="M12 5 q1 -1.6 0 -3 M16 4.6 q1 -1.6 0 -3 M20 5 q1 -1.6 0 -3" stroke="#e8e2d4" stroke-width="1.4" stroke-linecap="round" fill="none" opacity="0.85"/>
</symbol>
<symbol id="station-stove-burning" viewBox="0 0 32 32">
<rect x="3" y="6" width="26" height="21" rx="3" fill="#4a4238"/>
<rect x="3" y="6" width="26" height="21" rx="3" fill="none" stroke="#3a322a" stroke-width="1.4"/>
<rect x="11" y="12" width="10" height="7" rx="2" fill="#3b3b3b"/>
<path d="M16 4.5 c2.6 2.2 4 4 4 6.2 a4 4 0 0 1 -8 0 c0 -2.2 1.4 -4 4 -6.2 z" fill="#ff5a4e"/>
<path d="M16 8 c1.4 1.4 2.2 2.4 2.2 3.6 a2.2 2.2 0 0 1 -4.4 0 c0 -1.2 0.8 -2.2 2.2 -3.6 z" fill="#ffa63d"/>
</symbol>
<symbol id="station-pot" viewBox="0 0 32 32">
<rect x="8" y="12" width="16" height="11" rx="2.5" fill="#8b8b8b"/>
<rect x="6.6" y="10.4" width="18.8" height="3" rx="1.5" fill="#a3a3a3"/>
<circle cx="16" cy="9.2" r="1.4" fill="#a3a3a3"/>
<rect x="4.6" y="14" width="3.4" height="2.4" rx="1.2" fill="#6f6a63"/>
<rect x="24" y="14" width="3.4" height="2.4" rx="1.2" fill="#6f6a63"/>
</symbol>
<symbol id="station-pan" viewBox="0 0 32 32">
<ellipse cx="14" cy="17" rx="9.5" ry="6" fill="#55504a"/>
<ellipse cx="14" cy="15.8" rx="8" ry="4.6" fill="#6b625a"/>
<rect x="22" y="14.6" width="8" height="3" rx="1.5" fill="#6b5a48"/>
</symbol>
<symbol id="station-prep" viewBox="0 0 32 32">
<rect x="4" y="10" width="24" height="15" rx="2.5" fill="#d8c49a"/>
<rect x="4" y="10" width="24" height="15" rx="2.5" fill="none" stroke="#a5825a" stroke-width="1.4"/>
<ellipse cx="13" cy="17.5" rx="6" ry="3.4" fill="#f6f1e7"/>
<ellipse cx="13" cy="17.5" rx="6" ry="3.4" fill="none" stroke="#cfc5b5" stroke-width="1"/>
<circle cx="24" cy="17.5" r="3.4" fill="#8b8b8b"/>
</symbol>
<symbol id="station-serve" viewBox="0 0 32 32">
<rect x="4" y="8" width="24" height="18" rx="2.5" fill="#d8c49a"/>
<rect x="7" y="12" width="18" height="10" rx="1.8" fill="#4a4238"/>
<path d="M11 17 h10" stroke="#f6f1e7" stroke-width="1.6" stroke-linecap="round" fill="none"/>
<path d="M16 4.5 a3 3 0 0 1 3 3 v1 h-6 v-1 a3 3 0 0 1 3 -3 z" fill="#ffd95e"/>
<circle cx="16" cy="3.4" r="1" fill="#ffd95e"/>
</symbol>
<symbol id="station-sink" viewBox="0 0 32 32">
<rect x="5" y="9" width="22" height="16" rx="2.5" fill="#b9b9b9"/>
<rect x="8" y="12" width="16" height="10" rx="2" fill="#8f8f8f"/>
<circle cx="16" cy="18.5" r="1.5" fill="#6f6f6f"/>
<path d="M22 6 v4 a3 3 0 0 1 -3 3 h-2" stroke="#a3a3a3" stroke-width="2.4" stroke-linecap="round" fill="none"/>
</symbol>
<symbol id="station-trash" viewBox="0 0 32 32">
<path d="M10 9 L22 9 L20.5 27 L11.5 27 Z" fill="#7a7f85"/>
<rect x="8.4" y="5.6" width="15.2" height="3.4" rx="1.4" fill="#9aa0a6"/>
<path d="M13.4 12 V24 M16 12 V24 M18.6 12 V24" stroke="#62676d" stroke-width="1.3" fill="none"/>
</symbol>
</svg>