Is your feature request related to a problem? Please describe.
ScenarioRunService has deterministic coverage for cancellation, terminal progress, and deferred active-task cleanup after success or failure, but it does not directly cover the cancelled readback boundary:
- a scenario run is blocked inside
run_async();
cancel_run_async() cancels and awaits that task;
- persistence reports the run as
ScenarioRunState.CANCELLED;
get_run() reads the terminal database state;
- the completed/cancelled entry is removed from
_active_tasks.
No production defect has been reproduced. The missing regression matters because a stale active-task entry could make the in-memory lifecycle state disagree with the database, retain task/scenario objects longer than necessary, or affect subsequent status reads.
Describe the solution you'd like
Add a deterministic unit test in tests/unit/backend/test_scenario_run_service.py that:
- starts or installs a scenario task whose
run_async() is blocked on an asyncio.Event;
- waits until execution is definitely blocked before cancelling;
- calls and awaits
cancel_run_async();
- configures the persisted scenario header/result to report
CANCELLED;
- calls
get_run();
- asserts the returned state is the terminal persisted
CANCELLED state;
- verifies the stale active-task entry is cleaned up.
Prefer asserting observable behavior where possible. If direct inspection of _active_tasks is necessary to prove cleanup, keep that assertion narrowly scoped and document the intended internal invariant through the test name and setup rather than changing the public API solely for testing.
The test should control task scheduling with events rather than sleeps, verify cancellation is fully awaited, and ensure cleanup happens exactly once.
Describe alternatives you've considered, if relevant
Existing tests separately cover cancelled progress deltas and active-task cleanup after successful or failed runs, but neither proves the combined cancelled-readback path. A broad integration test would be slower and less deterministic than a focused service unit test.
Changing production code without first reproducing a failure is not proposed. If the test exposes a mismatch between persisted terminal state and in-memory cleanup, the smallest behavior-preserving fix should be included with the regression.
Additional context
This boundary was identified during the September 12, 2026 deterministic resilience audit with medium-high confidence. The audit found no exact existing issue or test covering it.
Suggested validation:
- the new focused
ScenarioRunService test;
- the complete backend scenario-run service test module;
- cancellation and progress route tests if production code changes;
- Ruff, typing, and
git diff --check.
Is your feature request related to a problem? Please describe.
ScenarioRunServicehas deterministic coverage for cancellation, terminal progress, and deferred active-task cleanup after success or failure, but it does not directly cover the cancelled readback boundary:run_async();cancel_run_async()cancels and awaits that task;ScenarioRunState.CANCELLED;get_run()reads the terminal database state;_active_tasks.No production defect has been reproduced. The missing regression matters because a stale active-task entry could make the in-memory lifecycle state disagree with the database, retain task/scenario objects longer than necessary, or affect subsequent status reads.
Describe the solution you'd like
Add a deterministic unit test in
tests/unit/backend/test_scenario_run_service.pythat:run_async()is blocked on anasyncio.Event;cancel_run_async();CANCELLED;get_run();CANCELLEDstate;Prefer asserting observable behavior where possible. If direct inspection of
_active_tasksis necessary to prove cleanup, keep that assertion narrowly scoped and document the intended internal invariant through the test name and setup rather than changing the public API solely for testing.The test should control task scheduling with events rather than sleeps, verify cancellation is fully awaited, and ensure cleanup happens exactly once.
Describe alternatives you've considered, if relevant
Existing tests separately cover cancelled progress deltas and active-task cleanup after successful or failed runs, but neither proves the combined cancelled-readback path. A broad integration test would be slower and less deterministic than a focused service unit test.
Changing production code without first reproducing a failure is not proposed. If the test exposes a mismatch between persisted terminal state and in-memory cleanup, the smallest behavior-preserving fix should be included with the regression.
Additional context
This boundary was identified during the September 12, 2026 deterministic resilience audit with medium-high confidence. The audit found no exact existing issue or test covering it.
Suggested validation:
ScenarioRunServicetest;git diff --check.