Repository navigation
fix(level6): targeted API contract and checker quality fixes - #65
Merged
Merged
Conversation
- P01 README: fix the 404-vs-422 contradiction — an unknown monster_name
outside the Literal schema is a 422 validation error, not a 404; explain
why (schema-enforced set vs. runtime lookup) instead of stating it as a
universal rule.
- M06 README: promote GET /monsters/{name} from an undocumented "Side
Quest" to a required Task 5, matching the scaffold's existing TODO and
check.py's existing hard requirement. Note the def_ -> defense renaming
at the schema boundary where it first appears.
- M01 check.py: replace the non-empty-list-only GET /monsters check with a
real comparison against data/monsters.json, so a hardcoded fake list
fails while any behaviorally-correct implementation passes.
- M05 check.py: isolate the session endpoints with a tempdir-backed
SessionRepository via app.dependency_overrides (the same technique the
mission teaches) instead of writing real files into data/sessions/.
M07 check.py previously only verified structural markers (TestClient, dependency_overrides, >=6 test functions, pytest passes) — a suite of `client.get(...); assert True` tests satisfied every gate. Add a second gate: after the student's suite passes against the correct app, run it against six independent, single-behavior mutants covering the mission's six required tests (health status, monster list, battle winner, invalid-monster 404, session persistence, session-not-found 404). Each mutant must be caught by the student's own suite, restored via try/finally with byte-identical verification, with __pycache__ cleared around every subprocess run.
- P03 README: the "Fill in rpg/api/schemas.py with the five Pydantic models" instruction was false — the file is pre-wired with four models. Reframe it as read-only reference material for the routers, and fix a second, previously-unnoticed doc bug (the MonsterOut table listed def_ instead of the schema's actual defense field). - P03 check.py: add a Gate 10 that runs `ruff check rpg/api/` (the directory the student actually implements) using the repo's root pyproject.toml — scoped there after confirming a full correct solution is clean under that scope while tests/ carries a pre-existing, unrelated lint error the student doesn't own. A real lint violation now fails the boss fight; correct code still passes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Targeted fixes to
level_6_api/based on the accepted Level 6 audit. This is not a Level 6 rebuild — mission/project count, order, and the HTTP → schemas → services/domain → repository architecture are unchanged, and Level 6 stays sync-only (no async introduced).monster_nameoutside theLiteral[...]schema is a 422 (Pydantic validation, before the endpoint runs), not a 404. The README now explains why — the allowed set is enforced at the schema boundary, not at a runtime lookup — and explicitly warns against reading this as a universal rule, contrasting it with Project 02's realGET /monsters/{name}404 case.GET /monsters/{name}from an undocumented "Side Quest" to a required Task 5, matching the scaffold's existing TODO andcheck.py's existing hard requirement. Added thedef_→defenseschema-boundary naming note here, where the mapping first appears.data/monsters.json. A hardcoded fake list now fails; any behaviorally-correct implementation (including one that never touches_service) passes.SessionRepositorythroughapp.dependency_overrides(the exact technique the mission teaches), instead of leaking real files intodata/sessions/.client.get(...); assert Truesuite now fails. Verified against two structurally different correct suites (different names/order/assertion style) — both pass — and five negative/fake scenarios — all correctly rejected. Mutants are applied via exact string replacement and restored via try/finally with byte-identical verification;__pycache__is cleared around every subprocess run.MonsterOuttable listeddef_instead ofdefense. Added a closing note pointing back to Level 5's Ruff habit.ruff check rpg/api/(scoped there after confirming a full correct solution is clean under that scope, whiletests/carries a pre-existing, unrelated lint error the student doesn't own). A real lint violation in student code now fails the boss fight; correct code still passes.Explicitly not done (per audit scope)
No async,
BackgroundTasks, middleware, lifecycle events, new service architecture, custom exception hierarchy, new missions, or Mypy/Pyright/coverage/CI added to Level 6.Test plan
data/sessions/, overrides clearedtools/author_check.py→ 727 checks passed, 0 errorstools/course_status.py→ runs clean__pycache__/.pytest_cache/session files/dependency overrides🤖 Generated with Claude Code