Phase `02_level_content_and_validation` — final verification **green**. - **Gate:** `bash .agents/validate.sh` → ruff ✅ · pyright 0 errors ✅ · `undercooked-levels validate` OK (2 levels) ✅ · **668 passed** (incl. 10 Playwright e2e) ✅ · coverage **100%** ✅ · repo hygiene ✅ - **Criteria:** `validate` exit 0, one line per level; `list` = `01_first_kitchen`, `02_double_shift` in campaign order; live `:8000` `/healthz` 200, `/api/levels` (+detail) carries both levels with numeric `target_score`/`time_limit` and no grid/station leakage, `/api/config` correct, unknown id → 404, startup log `content loaded: 2 level(s), 4 recipe(s)`; `validate --dir tests/fixtures/levels/_bad/` → exit 1 with named `RECIPE_STATION_MISSING` / `SERVE_REACHABLE` / `TARGET_IMPLAUSIBLE`; A8 lock test proves a YAML-only level reaches loader+API+CLI. - **Defect fixed (pre-existing path, phase-02-triggered):** `undercooked` with unusable content printed the report then a raw traceback and exited `1`. `src/undercooked/__main__.py` now catches `ContentError` → one closing line, exit `2` (like a bad setting); 2 new tests in `tests/unit/test_main.py` (incl. non-content failures still propagate). - **Docs pass (full, project-wide):** README (content gate + exit `2`, config section), AGENTS.md §3, `docs/LEVELS.md` (startup refusal + exact CLI exit codes), `docs/DEPLOYMENT.md` (crash-loop diagnosis bullet); DESIGN/TESTING re-read, consistent. - **Container re-verified (no phase-01 regression):** `podman build -f Containerfile` succeeds; the image ships `levels/` and serves `/healthz` 200, `/api/levels` (2 levels), `/` 200 as non-root. - **Deviation to note:** the phase overview names `tests/fixtures/levels/bad/`; the actual broken-fixture dir is `tests/fixtures/levels/_bad/` (the `_` prefix is what keeps it out of normal discovery). Overview files are read-only to me — README/LEVELS.md document the real path. - No git index/history commands run; all changes left unstaged for the harness. ntfy notification sent.
47 lines
1.6 KiB
YAML
47 lines
1.6 KiB
YAML
# A deliberately broken level for `undercooked-levels validate` (phase 02 task 05).
|
|
#
|
|
# It *loads* (the schema is satisfied) and then breaks three PLAN §8 rules, so
|
|
# the CLI's exit-1 path, its named-rule report and the `show --grid` "?" overlay
|
|
# all have a stable input to be tested against:
|
|
#
|
|
# * the right-hand box (x6..x9, y1..y2) is sealed on all four sides, so the
|
|
# serve window inside it is cut off from the spawn -> SERVE_REACHABLE, and
|
|
# those same cells show up as `?` in `show --grid`;
|
|
# * the recipe's steps name a stove this kitchen does not have
|
|
# -> RECIPE_STATION_MISSING;
|
|
# * target_score 999 is far past 60 % of the theoretical maximum
|
|
# -> TARGET_IMPLAUSIBLE.
|
|
#
|
|
# The `_bad` directory name opts out of content discovery (`_is_draft`), so this
|
|
# campaign is only loaded when something points `--dir` straight at it — the
|
|
# server and the rest of the test suite never see it.
|
|
id: 99_broken_room
|
|
name: Broken Room
|
|
order: 1
|
|
difficulty: 5
|
|
time_limit: 60
|
|
target_score: 999
|
|
blurb: A kitchen with a sealed-off servery, the fixture for the validator itself.
|
|
grid:
|
|
- "###########"
|
|
- "#T..C#..V.#"
|
|
- "#....#....#"
|
|
- "#.#########"
|
|
- "#S........#"
|
|
- "###########"
|
|
tiles:
|
|
"#": {kind: wall}
|
|
".": {kind: floor}
|
|
"T": {kind: floor, station: spawn_shelf, item: tomato}
|
|
"C": {kind: floor, station: chop_board}
|
|
"V": {kind: floor, station: serve}
|
|
"S": {kind: floor, station: spawn_shelf, item: onion}
|
|
spawns: [[1, 4]]
|
|
orders:
|
|
pool: [soup]
|
|
concurrent: 1
|
|
spawn_interval: [12, 16]
|
|
deadline: 60
|
|
hazards: []
|
|
escalation_notes: Fixture only, never shipped and never part of a real campaign.
|