fix: restore automatic goal continuation on OpenCode V2 - #46
Merged
Conversation
spencer2211
added a commit
to spencer2211/opencode-goal-plugin
that referenced
this pull request
Sep 7, 2026
A Task child session that never reports a terminal state, or whose terminal result is never reconciled by an orchestrator turn, could defer goal continuation forever. Bound it with a `max_task_block_seconds` ceiling (default 900, `0` to disable), measured from `runningSince` for a listed child and from `terminalAt` for an unreconciled terminal one. `markTerminal` now carries the original `terminalAt` when it re-marks the same still-unreconciled terminal state, along with the assistant marker captured at that moment. `refreshLiveChildren` re-marks a listed idle child on every poll, so rewriting the timestamp each time meant the terminal branch of the ceiling could never fire for the case it exists to bound. The deferral also validates the goal before re-arming. The retry runs at 1 Hz and writes nothing to the goal, so a goal closed, cleared, or paused while a child still blocks would otherwise keep polling until the ceiling - and forever with `max_task_block_seconds: 0`. Rebased onto b7e185c (prevalentWare#46). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MLdQ88tCqSgfEsaGR978UF
5 tasks
danyel117
pushed a commit
that referenced
this pull request
Sep 7, 2026
* fix: bound task-deferred goal continuation A Task child session that never reports a terminal state, or whose terminal result is never reconciled by an orchestrator turn, could defer goal continuation forever. Bound it with a `max_task_block_seconds` ceiling (default 900, `0` to disable), measured from `runningSince` for a listed child and from `terminalAt` for an unreconciled terminal one. `markTerminal` now carries the original `terminalAt` when it re-marks the same still-unreconciled terminal state, along with the assistant marker captured at that moment. `refreshLiveChildren` re-marks a listed idle child on every poll, so rewriting the timestamp each time meant the terminal branch of the ceiling could never fire for the case it exists to bound. The deferral also validates the goal before re-arming. The retry runs at 1 Hz and writes nothing to the goal, so a goal closed, cleared, or paused while a child still blocks would otherwise keep polling until the ceiling - and forever with `max_task_block_seconds: 0`. Rebased onto b7e185c (#46). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MLdQ88tCqSgfEsaGR978UF * fix: match the task-deferral predicate to reserveContinuation's rules `taskDeferralGoalContinuable` treated every `budgetLimited` / `usageLimited` goal as continuable. That holds only until the single wrap-up is reserved: `reserveWrapup` returns null once `budgetWrapupSent` is set, so a child still blocking after the wrap-up had been sent kept the 1 Hz poll re-arming with no possible continuation - indefinitely with `max_task_block_seconds: 0`. The predicate now mirrors the reservation rules instead of restating them: a limited goal is continuable only while its wrap-up is unspent, and every other non-active status fails `canContinue` outright. Lifecycle coverage is now symmetric. V1 and V2 each cover cleared, paused, completed, and the two-legged wrap-up case. Leg A of that pair is the control: a predicate that simply refused every non-active status would pass leg B while silently dropping the wrap-up a blocked limited goal is still owed. Both wrap-up tests also assert the deferral returns after `update_goal_status active` clears `budgetWrapupSent`, proving the loop stayed reachable and only the predicate was holding it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MLdQ88tCqSgfEsaGR978UF --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Summary
Verification
Release
User requested publication and installation after validation. Publishing uses the existing main-branch GitHub Actions workflow; exact npm version will be smoke-tested again after release.