phase: 01_runnable_service_scaffold
**Phase 01 final verification pass — all criteria green**
- Verified (nothing left to implement; all 4 task files already in `complete/`): toolchain lock, typed `Settings`+`.env.example`, debugpy bootstrap, app factory, CLI (`--host/--port/--reload/--levels-dir`, `python -m undercooked`), static shell + `/static`, security headers, no-CDN/doc guards, `validate.sh`.
- `uv sync --extra dev` → exit 0; `uv.lock` present (untracked → harness commits it with the phase).
- `uv run undercooked --host 127.0.0.1 --port 8000` → `curl /healthz` = 200 `{"status":"ok","version":"0.1.0","rooms":0}` (superset of the criterion's body — now documented in README); `curl /` = 200 shell HTML; static css/js 200; CSP/nosniff/no-referrer/DENY on 200, 404 and 405 too.
- `DEBUGPY=1`: port 5678 is held on this machine by the user's own podman dev-container debugpy adapter — **no live change made/killed**; verified via `DEBUGPY=1 DEBUGPY_PORT=5679` → listener opens, `/healthz` still 200; the occupied-port case degraded gracefully as designed (warning, server serves). Bad config → one line + exit 2 ✓.
- `bash .agents/validate.sh` (root **and** `.agents/`) → exit 0: `ruff check .` 0 errors, `pyright` 0 errors, levels-CLI notice-skip (matches README prose), **284 passed** full suite incl. 10 Playwright e2e, coverage **100.00%** (floor 90), repo hygiene clean. `uv run pytest -m e2e` → 10 passed.
- Docs fixed: README Status → phase 01 complete + next pending 02 (was pointing at `todo/01…`), documented real `/healthz` body, precedence now "CLI flags > env > .env > default", added the PLAN §13-promised **How to play** section (honest about shell-only today), Layout rows marked what exists vs phases 02/07. AGENTS.md: recorded the `data:`-URL exemption in the no-CDN rule (test allows it) and matched the session-token rule to the browser's WebCrypto/base64url implementation. Also corrected a stale "session-wide chromium" docstring in `tests/e2e/conftest.py` (fixtures are function-scoped).
- Deviations: no container build run (needs an image pull; not a phase criterion — `Containerfile`/`compose.yaml` reviewed and consistent with `docs/DEPLOYMENT.md`); `HEAD /` is 405 (routes are GET-only by design; health checks use GET). No git index/history commands run.
- Next pending phase: `02_level_content_and_validation`.
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Undercooked: anonymous cooperative kitchen chaos in the browser. Create a lobby, read out the 5-character code, cook together."
|
||||
/>
|
||||
<meta name="color-scheme" content="dark" />
|
||||
<title>Undercooked</title>
|
||||
<!-- No favicon file yet: an empty data: URL stops the browser probing /favicon.ico
|
||||
while keeping every byte same-origin (PLAN.md A12). -->
|
||||
<link rel="icon" href="data:," />
|
||||
<link rel="stylesheet" href="/static/css/base.css" />
|
||||
</head>
|
||||
<body>
|
||||
<main id="app" class="shell">
|
||||
<header class="masthead">
|
||||
<p class="wordmark">Undercooked</p>
|
||||
<p class="tagline">Anonymous co-op kitchen chaos. No accounts, no install, 1–4 cooks.</p>
|
||||
</header>
|
||||
|
||||
<section id="screen-lobby" class="panel" aria-labelledby="lobby-heading">
|
||||
<h2 id="lobby-heading">Kitchen lobby</h2>
|
||||
<p id="lobby-help">
|
||||
Create a kitchen and read its 5-character code out loud, or join a kitchen that is
|
||||
already open. Nothing is saved and nothing is asked for.
|
||||
</p>
|
||||
|
||||
<button id="create-lobby" class="btn btn-primary" type="button">Create lobby</button>
|
||||
|
||||
<form id="join-form" class="join" autocomplete="off">
|
||||
<label for="join-code">Room code</label>
|
||||
<div class="join-row">
|
||||
<input
|
||||
id="join-code"
|
||||
name="code"
|
||||
type="text"
|
||||
inputmode="text"
|
||||
autocapitalize="characters"
|
||||
spellcheck="false"
|
||||
size="5"
|
||||
maxlength="5"
|
||||
placeholder="ABCDE"
|
||||
aria-describedby="join-hint"
|
||||
required
|
||||
/>
|
||||
<button class="btn" type="submit">Join</button>
|
||||
</div>
|
||||
</form>
|
||||
<p id="join-hint" class="hint">
|
||||
Five characters, letters and digits, never <code>I</code>, <code>L</code>, <code>O</code>
|
||||
or <code>U</code>.
|
||||
</p>
|
||||
|
||||
<div id="status" class="status" role="status" aria-live="polite">
|
||||
Pick a kitchen to start.
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- The renderer (phase 07) sizes and unhides this canvas; it stays out of
|
||||
the layout and the a11y tree until then. -->
|
||||
<canvas id="kcanvas" hidden aria-hidden="true"></canvas>
|
||||
</main>
|
||||
|
||||
<footer class="colophon">
|
||||
<p>
|
||||
An independent homage to Overcooked™ with its own art, code and content. Every byte
|
||||
you see is served by this one process — no third-party requests, no trackers.
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
<script type="module" src="/static/js/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user