feat(sessions): nudge alive tasks whose transcript ended mid-turn - #23
Open
Antisophy wants to merge 2 commits into
Open
feat(sessions): nudge alive tasks whose transcript ended mid-turn#23Antisophy wants to merge 2 commits into
Antisophy wants to merge 2 commits into
Conversation
A restart or crash that lands mid-turn is only recovered when the task was recorded "active": that resume path relaunches the process and sends the restart nudge telling the agent to retry its interrupted tool call. A turn started by the agent itself (a background-task notification inside the CLI) never passes through a send that marks the task active, so the shutdown snapshot says "alive", the resume relaunches silently, and the agent sits idle on its interrupted work until a human notices. Witness the turn lifecycle directly instead of trusting the status: a turn-scoped event (item/*, turn/*) marks the task's transcript mid-turn until a turn/result or process exit closes it, while session bootstrap and other non-turn events leave the witness unchanged, so a restart's own resume traffic cannot re-open an idle task. The flag is persisted on change, so a kill at any moment leaves the truth on disk. The alive resume branch sends the restart nudge when the witness says mid-turn and stays silent otherwise, so idle tasks cost nothing extra.
The restart nudge covered an interrupted tool call but said nothing about background work, and an agent whose pending work was a background shell or watcher rather than an in-flight tool call would conclude nothing was pending and end its turn; the background jobs died with the restart and their completion notifications never fire, so the task orphans. Name that case explicitly: check what was running, relaunch what is still needed, and do not end the turn without doing so.
CyberShadow
reviewed
Aug 29, 2026
CyberShadow
left a comment
Owner
There was a problem hiding this comment.
A turn started by the agent itself (a background-task notification inside the CLI) never passes through a send that marks the task active
I think this is the real bug here. We should already be switching the task state on a self-resume; it's possible that the behavior is an artifact of us not using a consolidated path that affects nudging properly.
Comment on lines
+137
to
+142
| // Migration 23: whether the transcript ends inside an open turn. | ||
| // Maintained on every translated event (set on turn activity, | ||
| // cleared on turn/result and process/exit), so a restart or crash | ||
| // landing mid-turn is visible at resume time regardless of what | ||
| // the status field recorded; such tasks get the restart nudge. | ||
| "ALTER TABLE tasks ADD COLUMN turn_open INTEGER NOT NULL DEFAULT 0;", |
Owner
There was a problem hiding this comment.
I really hope we don't actually need a migration here! Our existing data model should suffice to capture this corner case.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A restart or crash that lands mid-turn is only recovered when the task was recorded "active": that resume path relaunches the process and sends the restart nudge telling the agent to retry its interrupted tool call. A turn started by the agent itself (a background-task notification inside the CLI) never passes through a send that marks the task active, so the shutdown snapshot says "alive", the resume relaunches silently, and the agent sits idle on its interrupted work until a human notices.
Witness the turn lifecycle directly instead of trusting the status: a turn-scoped event (item/, turn/) marks the task's transcript mid-turn until a turn/result or process exit closes it, while session bootstrap and other non-turn events leave the witness unchanged, so a restart's own resume traffic cannot re-open an idle task. The flag is persisted on change, so a kill at any moment leaves the truth on disk. The alive resume branch sends the restart nudge when the witness says mid-turn and stays silent otherwise, so idle tasks cost nothing extra.
The second commit extends the restart nudge itself: it now also tells the resumed agent to check on background work (shells, subagents, watchers) that did not survive the restart, since an agent whose pending work was a background job rather than an in-flight tool call would otherwise conclude nothing was pending and end its turn.