Skip to content

fix(reactor): never re-answer a parked call that already has a result - #1492

Merged
TheGreatAxios merged 2 commits into
cl-10764-persist-pending-operation-removal-when-an-approved-call-isfrom
cl-10765-never-inject-a-timeout-result-for-a-parked-call-that-already
Oct 17, 2026
Merged

TheGreatAxios merged 2 commits into
cl-10764-persist-pending-operation-removal-when-an-approved-call-isfrom
cl-10765-never-inject-a-timeout-result-for-a-parked-call-that-already

Conversation

@bwachman

Copy link
Copy Markdown
Contributor

Summary

  • On start, the reactor drops any persisted pending operation whose parked call already has a tool_result in history, writes that removal to metadata, and logs a warning, instead of re-arming its gate.
  • When an approval gate times out and its parked call already has a result, the reactor removes the operation without injecting a synthetic approval timed out result, and logs that it skipped it.
  • This closes the remaining window after the persistence fix in fix(reactor): persist resolved approval removal with its result turn #1485, where a crash between the turns write and the metadata write still leaves a stale operation for an answered call.

Stacked on #1485; review that first. The diff against its branch is this change only.

Verification

  • bun run check and bun run test pass (9203 tests)
  • The new reactor tests fail on the base branch (a stale operation re-armed into Malformed tool sequence: duplicate tool_result, and a second result for an answered call) and pass on this branch

Fixes CL-10765
Part of CL-10763

The pending-operation removal reaches metadata in a second await after
the result turn, so a crash between the two leaves a stale op for a
call history already answers. A reactor rebuilt from that store
re-armed its gate and, at the original deadline, appended a second
tool_result for the same call id, which the prompt tripwire rejects.

Startup now drops and persists the removal of any loaded op whose
parked call already has a result, and the approval timeout injects no
synthetic result for such a call.
@linear-code

linear-code Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

CL-10765

CL-10763

@TheGreatAxios TheGreatAxios left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review · Approve

Drops stale pending operations at startup (and persists the removal) plus skips the approval-timeout synthetic result when the parked call already has a result, closing the crash-window double-tool_result.

Findings

No findings.

@bwachman

Copy link
Copy Markdown
Contributor Author

Superseded by CL-10781, which stores a pending approval in turns.jsonl next to the call it parks. Once the call's result is in the log, a rebuilt agent never sees an open approval for it, so neither the start-up drop nor the timeout skip in this PR is needed, and nothing changes under vendor/. We don't intend to merge or keep working on this PR. It stays open, as a draft, until CL-10781 is proven, then it gets closed.

@bwachman
bwachman marked this pull request as draft October 17, 2026 05:18
Crash recovery could reload a pending operation for a call the turns already answer, re-arming its gate and injecting a second tool result at the deadline. load() now drops any pending operation whose suspended call id already has a tool result, warning per drop; marker operations without a suspended call pass through. The removal converges to disk on the next metadata write.
@TheGreatAxios
TheGreatAxios marked this pull request as ready for review October 17, 2026 16:11
@corbits-triage

Copy link
Copy Markdown
Contributor

Triage: Pass

No changes needed from you. A maintainer will review this pull request.

@TheGreatAxios
TheGreatAxios merged commit ebd3fbe into cl-10764-persist-pending-operation-removal-when-an-approved-call-is Oct 17, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants