Let a lesson list review keys beside the two it introduces

A lesson's `keys` was capped at two outright, which made it impossible to write
"K, with the four keys before it still in play". The cap now counts only what is
*new*; keys already taught can be listed freely, and the spotlight falls on the
new ones alone, so a lesson titled "K" drills K instead of spreading itself
evenly over all five keys it names. A round that introduces nothing new still
spotlights its whole list - that is the "mixed" replay, unchanged.

Also documents `unlocks:` paths as relative to the library root. Absolute and
"~" paths still resolve, so an existing file keeps working, but a relative path
survives moving the library.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-19 18:05:19 +02:00
parent b6342cc117
commit 36e93be79b
3 changed files with 37 additions and 17 deletions

View File

@@ -117,19 +117,21 @@ def test_wrong_world_count_is_one_problem(tmp_path: Path) -> None:
def test_multiple_problems_are_all_reported_at_once(tmp_path: Path) -> None:
worlds = [dict(w) for w in VALID["worlds"]]
# Two independent problems in one file: a reused reward, and a lesson with too many
# keys - both should show up in a single error, not just the first one found.
# Two independent problems in one file: a reused reward, and a lesson introducing
# too many keys at once - both should show up in a single error, not just the first
# one found. ("a" and "s" are already taught in world 1, so only the three unseen
# keys count against the cap.)
worlds[1] = {**worlds[1], "reward": "clownfish"}
worlds[2] = {
**worlds[2],
"lessons": [{"title": "Zu viel", "subtitle": "x", "keys": ["a", "s", "d"]}],
"lessons": [{"title": "Zu viel", "subtitle": "x", "keys": ["a", "s", "q", "w", "e"]}],
}
with pytest.raises(CurriculumError) as excinfo:
load_curriculum(_write(tmp_path, {"worlds": worlds}))
message = str(excinfo.value)
assert "2 problems" in message
assert "reuses reward" in message
assert "at most two keys" in message
assert "at most two new keys" in message
def test_letters_kind_cannot_have_words(tmp_path: Path) -> None: