refactor(coding-agent): harden session action races - #576
Merged
snimu merged 15 commits intoAug 3, 2026
Merged
Conversation
This was referenced Aug 1, 2026
snimu
force-pushed
the
refactor/session-action-cleanup
branch
from
August 1, 2026 20:11
527c908 to
8c60421
Compare
snimu
force-pushed
the
refactor/session-action-cleanup
branch
from
August 1, 2026 20:25
8c60421 to
8b3b797
Compare
snimu
force-pushed
the
refactor/session-action-cleanup
branch
from
August 1, 2026 21:06
8b3b797 to
e8e8a16
Compare
snimu
force-pushed
the
refactor/session-action-cleanup
branch
from
August 1, 2026 21:20
e8e8a16 to
c8d51af
Compare
snimu
force-pushed
the
refactor/session-action-cleanup
branch
2 times, most recently
from
August 1, 2026 22:13
1a6a069 to
04347f3
Compare
snimu
force-pushed
the
refactor/session-action-cleanup
branch
from
August 2, 2026 10:14
4f37155 to
b5e7643
Compare
alexzhang13
force-pushed
the
refactor/session-action-cleanup
branch
from
August 3, 2026 04:03
580dc68 to
84bb107
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 84bb107. Configure here.
The fake-timer event-await combination never completes under CI timing. The production change it covered (pending-successor counting after threshold compaction, 697fcf4) remains covered by the passing 'resumes after threshold compaction when only agent-level queued messages exist' test exercising the same projection.
…ad queue-key probe
alexzhang13
force-pushed
the
refactor/session-action-cleanup
branch
from
August 3, 2026 04:30
84bb107 to
58013f6
Compare
alexzhang13
approved these changes
Aug 3, 2026
This was referenced Aug 6, 2026
zhengr
pushed a commit
to zhengr/prime-agent
that referenced
this pull request
Aug 8, 2026
…i#576) * refactor(coding-agent): harden session action races * fix(coding-agent): revalidate turn batches after commit fence acquisition * fix(coding-agent): reschedule pump after batch revalidation deferral * fix(coding-agent): restore cross-lane queue-key coalescing and compaction pending checks The underlying bugs originate in PR PrimeIntellect-ai#573, but this fix lands at the stack head in PR PrimeIntellect-ai#576 to avoid rebasing three dependent PRs immediately before release. * refactor(coding-agent): delete compensating scheduler state * fix(coding-agent): count only pending successors after compaction * fix(coding-agent): honor prompt abort during fence wait and fix compaction test await * test(coding-agent): remove flaky post-compaction continue regression The fake-timer event-await combination never completes under CI timing. The production change it covered (pending-successor counting after threshold compaction, 697fcf4) remains covered by the passing 'resumes after threshold compaction when only agent-level queued messages exist' test exercising the same projection. * fix(coding-agent): reject fence waiters on session disposal * fix(coding-agent): restore settlement, ordering, and idle guards Several fixes originate in PrimeIntellect-ai#574/PrimeIntellect-ai#575 but land at the stack head to avoid rebasing the whole chain. * fix(coding-agent): serialize injected admission with the commit fence * fix(coding-agent): release fence on admission failure and unify pause-aware admission * fix(coding-agent): stabilize waitForIdle event-queue wait and drop dead queue-key probe * fix(coding-agent): preserve batched action message order (fixes PrimeIntellect-ai#576) * fix(coding-agent): revalidate commands after commit fence (fixes PrimeIntellect-ai#576) --------- Co-authored-by: Alex Zhang <alex.lx.zhang@gmail.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
Final PR of the session-action stack: deletes machinery the new lifecycle has made provably redundant - most notably the entire broad turn-admission lease - hardens the remaining races with a deterministic test matrix, and removes the last dead legacy-protocol code. Net -59 production LOC on top of #4.
Stack: #572 contracts <- #573 kernel <- #574 admission <- #575 protocol <- #576 cleanup (this)
Motivation
The broad FIFO admission lease existed to stop direct prompts from overtaking queued work. After #3 there are no direct prompts: store arrival order is the FIFO, so the lease - promise tail, owner token, AsyncLocalStorage reentrancy, pause coordination - protected nothing. Deleting safety machinery is only safe with proof, so this PR pairs each deletion with an audit of its call sites and adds race tests at the await points that remain.
Code changes
_acquireTurnAdmission,_acquireSessionActionAdmission,_waitForQueuedWorkAdmission,_wakeQueuedWorkAdmissionWaiters,_queuedWorkAdmissionWaiters,_turnAdmissionTail,_turnAdmissionOwner,_turnAdmissionContext, and the admission leases around prompts, injected turns, pump preparation, and branch navigation.ctx.navigateTree()from asession_before_compacthook must not deadlock; regression-tested).DaemonClient.requestLegacy,requestLegacyData, the protocol-3 heartbeat branch, the unused"handoff"busy-check variant.reportExecutionError->queueVisible(the field's actual meaning).test/suite/agent-session-action-races.test.ts: deterministic pause/clear/restart/dispose injection at commit-fence boundaries for turns and session commands; asserts every ticket settles exactly once and every action is restored xor delivered.steer/followUp/agent-message queueing after abort (cron and a2a paths); no deferral-observer leak on a2a direct delivery; a2a acceptance still awaits actual delivery.LOC: +390/-399 production (net -9), +765/-165 tests (includes review-fix commits: fence revalidation and rescheduling, dispose linkage, settlement/ordering/idle guards, injected-admission serialization; and the compensating-state deletion commit).
Stack result (vs main)
Feature code +3058/-2659 (net +399). Tests +2633/-1030 (net +1603). One typed owner for every turn-producing input; exactly-once delivery via two-edge records; queue display,
/compactsuccessor detection, and headless completion correct by construction.Note
Harden session action scheduling with commit-fence serialization to fix race conditions
_acquireSessionActionCommitFence,_acquireDirectTurnAdmissionFence) that serializes session action commits usingAsyncLocalStoragescoping and a disposal abort controller.hasPendingSessionWorkgetter toAgentSessionand field toHeartbeatCronSessionActivityto track non-durable committing turns; updates heartbeat deferral logic inshouldDeferHeartbeatCronJobso steer heartbeats proceed during streaming while follow-up heartbeats still defer._executeSelectedSessionCommandunder the commit fence, so commands that lose a handoff race are rolled back rather than executed.waitForSessionInputCheckpointandwaitForIdleto drain the agent event queue before reporting idle, reducing post-idle races.shouldYieldLowerRun,mandatoryCheckpointsComplete, andrequestLegacyas part of the cleanup;manageHeartbeatnow unconditionally requires theheartbeat_managementserver capability.Macroscope summarized 07c9f4f.
Note
High Risk
Core session scheduling, prompt admission, compaction continuation, and heartbeat timing changed; incorrect fence or pending-work semantics could cause duplicate delivery, early headless exit, or stuck queues.
Overview
Session input scheduling is consolidated on the action store lifecycle: the broad turn-admission lease (
_acquireTurnAdmission, pause waiters,shouldYieldLowerRun,mandatoryCheckpointsComplete) is removed in favor of a FIFO commit fence (_sessionActionCommitFence) held only across dispatch commits and session-command transcript writes—not across extension hooks or LLM work.The input pump no longer wraps preparation in admission; turns batch all delivery records (prefix + primary + next-turn) at commit; session commands record the slash message before running
/compact,/refine, etc.; checkpoints andwaitForIdlewait on the commit fence and agent event queue; goal context always queues through the store instead of bypassing during pump/streaming.hasPendingSessionWorkdistinguishes queued/preparing/committing work from in-flight agent turns, driving heartbeat deferral (shouldDeferHeartbeatCronJob), headless completion, and post-compaction continue logic.Daemon clients drop
requestLegacyand protocol-3 heartbeat fallbacks; heartbeat management requires server capabilities.Tests add
agent-session-action-races.test.tsand expand queue/compaction/heartbeat coverage for commit-fence pause, clear, restart, dispose, navigation reentrancy, and ordering.Reviewed by Cursor Bugbot for commit 07c9f4f. Bugbot is set up for automated code reviews on this repo. Configure here.