phase: 02_level_content_and_validation
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.
This commit is contained in:
+46
@@ -0,0 +1,46 @@
|
||||
# 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.
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
# The recipe book for the `_bad` fixture campaign (phase 02 task 05).
|
||||
#
|
||||
# `undercooked-levels validate --dir tests/fixtures/levels/_bad` needs a book of
|
||||
# its own so the fixture stays self-contained: the tests assert on the rule hits
|
||||
# of `99_broken_room.yaml`, and those numbers depend on this book, not on the
|
||||
# shipped `levels/recipes.yaml`. One dish, `soup`, whose steps name a
|
||||
# `chop_board`, a `stove` and a `prep` station — the fixture kitchen omits the
|
||||
# stove on purpose.
|
||||
ingredients: [tomato, onion]
|
||||
|
||||
recipes:
|
||||
soup:
|
||||
id: soup
|
||||
name: Tomato Soup
|
||||
base_score: 40
|
||||
ingredients:
|
||||
- {kind: tomato, form: raw}
|
||||
- {kind: onion, form: raw}
|
||||
steps:
|
||||
- {kind: pick, station: spawn_shelf}
|
||||
- {kind: chop, station: chop_board, seconds: 0.9}
|
||||
- {kind: cook, station: stove, seconds: 5.0}
|
||||
- {kind: plate, station: prep, seconds: 0.4}
|
||||
Reference in New Issue
Block a user