Summary
The make_engine test helper in tests/test_stories_engine.py constructs its RunState without the max_stories field, even though production (cli.py:404, cmd_run) persists max_stories on RunState so resume can rebuild the cap (cli.py:746). The helper only passes max_stories to the StoriesEngine constructor.
Consequence: any test that runs a stories engine with --max-stories, pauses, and then calls resume_engine(...) gets state.max_stories == None on resume — so the resumed engine has no cap, diverging from production behavior. This surfaced while writing the A5 regression test (test_max_stories_survives_a_checkpoint_pause_resume), which had to work around it with:
engine, _ = make_engine(project, [stories_dev_effect()], max_stories=2)
engine.state.max_stories = 2 # cli.py persists this on RunState so resume rebuilds the cap
Why it matters
- Tests that resume with a
--max-stories cap silently test the wrong (uncapped) behavior unless every author remembers the manual engine.state.max_stories = N line.
- It is an easy trap:
make_engine(..., max_stories=N) looks like it fully configures the cap, but the durable half (RunState) is missing.
Proposed fix
Make make_engine mirror production by seeding the field it already accepts as a kwarg. Roughly, when building the RunState inside make_engine, also set max_stories (and, for symmetry, story_filter/epic_filter) from the same kwargs it forwards to the engine — so resume_engine reconstructs the real launching scope without per-test boilerplate.
After the helper is fixed, drop the manual engine.state.max_stories = 2 workaround in test_max_stories_survives_a_checkpoint_pause_resume.
Context
Found during PR #77 review remediation (finding A5 — durable --max-stories gate, commit e56f9db). Not a product bug; a test-fidelity gap that could mask future resume-durability regressions.
Acceptance
Summary
The
make_enginetest helper intests/test_stories_engine.pyconstructs itsRunStatewithout themax_storiesfield, even though production (cli.py:404,cmd_run) persistsmax_storiesonRunStatesoresumecan rebuild the cap (cli.py:746). The helper only passesmax_storiesto theStoriesEngineconstructor.Consequence: any test that runs a stories engine with
--max-stories, pauses, and then callsresume_engine(...)getsstate.max_stories == Noneon resume — so the resumed engine has no cap, diverging from production behavior. This surfaced while writing the A5 regression test (test_max_stories_survives_a_checkpoint_pause_resume), which had to work around it with:Why it matters
--max-storiescap silently test the wrong (uncapped) behavior unless every author remembers the manualengine.state.max_stories = Nline.make_engine(..., max_stories=N)looks like it fully configures the cap, but the durable half (RunState) is missing.Proposed fix
Make
make_enginemirror production by seeding the field it already accepts as a kwarg. Roughly, when building theRunStateinsidemake_engine, also setmax_stories(and, for symmetry,story_filter/epic_filter) from the same kwargs it forwards to the engine — soresume_enginereconstructs the real launching scope without per-test boilerplate.After the helper is fixed, drop the manual
engine.state.max_stories = 2workaround intest_max_stories_survives_a_checkpoint_pause_resume.Context
Found during PR #77 review remediation (finding A5 — durable
--max-storiesgate, commite56f9db). Not a product bug; a test-fidelity gap that could mask future resume-durability regressions.Acceptance
make_enginepersistsmax_stories(and scope selectors) on theRunStateit creates, matchingcmd_run.test_max_stories_survives_a_checkpoint_pause_resumeis removed and the test still passes.resume_engineround-trip test assertsstate.max_storiessurvives without manual seeding.