v0.4.1
Lifecycle patch over v0.4.0. Three resume/shutdown bugs that surfaced
during the v0.4 SQLite live test.
Lane A — Pipeline
- Graceful shutdown (closes #5):
@app.on_event("shutdown")now
cancels in-flight runner tasks and transitions papers topaused.
Skips state.json-says-completed papers. Stops the "zombie row at
designing/revision after every uvicorn restart" failure mode. - Resume writes terminal status (closes #6): when resume runs on a
paper whose state.json already has every stage complete, the runner
now mirrorsstate.last_statusback to the DB before returning.
Previously the DB row stayed atdesigning(the entry value). - Resume accepts zombies (closes #7):
/api/papers/{id}/resumeno
longer requires status to bepaused/failed. Any non-terminal
status with no live runner task in_RUNNINGis resumable. Combined
with #5, this removes the manual-UPDATE workaround entirely. - SQLite translation extensions (closes nothing — caught by live
SQLite smoke after v0.4.0 shipped, fixed before tagging):
NOW()→CURRENT_TIMESTAMP, plus::int/::bigint/::numeric/
::floatcasts stripped alongside the existing type/json/interval
casts. Without these, status UPDATEs silently failed and usage
aggregations crashed SQLite with "unrecognized token: ':'".
Tests
tests/pipeline/integration/test_graceful_shutdown.py— 3 new.tests/pipeline/integration/test_resume_terminal_status.py— 1 new.tests/pipeline/integration/test_resume_api.py— 4 new + 1 rewritten.
Test count: 326 → 333.