[P1] Scheduled runs need hard deadlines, restart recovery, and terminal-result validation #108
Labels
No labels
accessibility
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
nsaspy/a0-symbolics#108
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Scheduled tasks can remain RUNNING indefinitely because TaskScheduler awaits agent.monologue() without a deadline. It also treats any returned string as success, even when the persisted result is a raw tool request rather than a terminal response.
Exact live evidence (2026-09-06)
Four scheduled runs are still RUNNING:
Each current run appended exactly one user/task log entry and no subsequent agent, tool, warning, or final-response entry. The oldest has been running over 17 hours and the newest about 14 hours.
A previous prologrlm-reviewer run was recorded as successful with last_result equal to a raw exec tool-request JSON object, not a response-tool completion.
Three other schedules did reach the unusable-response circuit breaker, but that breaker only observes consecutive misformat/repeat warnings. It does not cover blocked context compilation, transport lock waits, long tool loops, or nonterminal monologue results.
Owning code
helpers/task_scheduler.py:
Impact
Acceptance criteria
Update after reviewing main up to
5116eb4d+bba5dcba(commits0b62cccb"fix: isolate scheduler run contexts" via PR #111, and7c057880"fix: route harness direct/complete through the context compiler" via PR #92):Now fixed by
0b62cccb:helpers/task_scheduler.py:1146-1160—_execute_tasknow raisesNonTerminalTaskResultErrorunless the monologue result matches an attested response-tool completion (recorded byextensions/python/tool_execute_after/_90_scheduler_terminal_result.py). The old behavior of recording a raw tool-request JSON as a successfullast_resultis gone._finish_runguards promotion withtask.current_run_id == run_id, so a late completion from a superseded run can't clobber state.Still missing (this issue's remaining scope), verified at
bba5dcba:await agent.monologue()athelpers/task_scheduler.py:1146still has no timeout wrapper. TheTaskRunStatus.TIMED_OUTclassification at:1190-1192only fires if something else raisesTimeoutError— the scheduler itself never imposes one. Suggested: wrap the monologue inasyncio.wait_for(..., timeout=task.run_deadline_seconds)with a configurable default (e.g. 3600s), and classify asTIMED_OUTonasyncio.TimeoutError.TaskState.RUNNING/last_run_status: runningwithcurrent_run_idset at scheduler load time. After a container restart, such tasks stay RUNNING forever andcheck_schedule(:732) skips future occurrences. Suggested: onSchedulerTaskList.load(), re-run any task withstate == RUNNINGthrough_finish_run(task_uuid, task.current_run_id, TaskRunStatus.FAILED, "scheduler restarted mid-run")(or CANCELLED).save_tmp_chaton every occurrence and never removed.Happy to split 1 and 2 into separate issues if preferred.