Skip to content

refactor(coding-agent): add session action scheduler kernel - #573

Merged
snimu merged 1 commit into
refactor/session-action-contractsfrom
refactor/session-action-kernel
Aug 3, 2026
Merged

snimu merged 1 commit into
refactor/session-action-contractsfrom
refactor/session-action-kernel

Conversation

@snimu

@snimu snimu commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Second PR of the session-action stack: introduces the scheduler kernel - a typed SessionAction envelope, a guarded lifecycle, per-message two-edge delivery records, and an ActionStore that becomes the sole owner of the queued-input lists - and routes the existing queued pump through it. External and wire behavior is preserved bit-for-bit via one private legacy projection (deleted in #4).

Stack: #572 contracts <- #573 kernel (this) <- #574 admission <- #575 protocol <- #576 cleanup

Motivation

Queued prompts and session commands were typed (PreparedPromptInput | PreparedCommandInput) but ~15 call sites mutated _steeringMessages/_followUpMessages directly, lifecycle was inferred from loosely coupled fields (_activeSessionInput phases, pump flags), and the ambiguous "pending" projection conflated queued future work with active executing work - the root cause of the executing-/compact-shows-as-queued bug and of /compact seeing itself as its own successor. This PR builds the authoritative ownership model while deliberately not yet touching direct prompt paths, so queue mechanics can be verified in isolation before the risky cutover.

Code changes

  • New src/core/session-action-store.ts:
    • SessionAction envelope (id, source, delivery policy, wake policy, payload union turn | session_command, lifecycle, queueKey, correlation).
    • DeliveryRecord with independent started (message_start -> acceptance settlement) and durable (message_end/transcript membership -> gates rollback/restore) edges.
    • Guarded transitionSessionAction() asserting the legal-transition table, including committing -> queued rollback only with transcript-membership proof of non-delivery.
    • Idempotent ActionTicketController (accepted/delivered/completed legs).
    • ActionStore: facade over the two per-policy FIFO lists; enqueue/enqueueFront (goal-context front insertion)/selectFirst/remove/rollback-at-original-position; named projections (queuedActions, clearableActions, snapshotActions, unfinishedActions, activeActions, queuePreview).
  • Queued pump routed through the kernel: selection-time ephemeral batching (queue mode read at selection, commands are barriers, batches never cross policies), kind-specific executors, per-constituent ticket settlement.
  • /compact successor detection now uses literal queuedActions() (internal fix; wire semantics unchanged).
  • legacyPendingProjection reproduces the old external behavior exactly, including the known executing-command-in-queue display bug (fixed in add model agnostic rlm system prompt #4, not here).
  • Internal SessionActionRecoverySnapshot with a private adapter emitting/reading the current restart-manifest format unchanged.
  • Deleted: direct _steeringMessages/_followUpMessages fields and their scattered mutation sites, PreparedPromptInput/PreparedCommandInput/QueuedSessionInput, _startPreparedPromptItems, _activeSessionInput.
  • New reference-style tests: policy priority, per-policy FIFO, one/all batching incl. mode switch while queued and command barriers, coalescing, front insertion, transition table incl. illegal transitions, ticket idempotency, rollback ordering, /compact self-successor exclusion.

LOC: +853/-399 production (net +454), +264/-54 tests.

Note

Add session action scheduler kernel to AgentSession with lifecycle state machine and two-lane queue

  • Introduces session-action-store.ts with a typed state machine (queued→selected→preparing→committing→running→completed/failed), a LEGAL_TRANSITIONS table, and an ActionStore class managing two delivery lanes (next_turn_boundary and when_run_idle).
  • Replaces _steeringMessages/_followUpMessages arrays and _activeSessionInput in agent-session.ts with a single ActionStore, binding action lifecycle transitions to message_start/message_end agent events.
  • Each enqueued action gets an ActionTicketController with three independently settled promises (accepted, delivered, completed), enabling precise rollback and cancellation on deferral or error.
  • Session commands and turn batches are dispatched through explicit lifecycle transitions; canSelectSessionAction and shouldYieldLowerRun gate admission based on runtime activity flags and pause state.
  • Risk: The pump, stop-before-turn, clearQueue, and checkpoint logic all change semantics; any code relying on the removed internal arrays or _activeSessionInput state will break (test suite internals were updated accordingly).

Macroscope summarized 09e9e1e.


Note

High Risk
Large rewrite of queued scheduling, lifecycle, rollback, and agent-event delivery in AgentSession; regressions are plausible in coalescing, deferral, multi-turn batching, and restart recovery despite preserved legacy projections.

Overview
Introduces session-action-store.ts, a scheduler kernel with typed SessionAction envelopes (turn vs session_command), delivery policies (next_turn_boundary / when_run_idle), wake policies, per-message DeliveryRecord edges (started / durable), guarded transitionSessionAction, and ActionTicketController settlement for accepted/delivered/completed.

AgentSession drops _steeringMessages, _followUpMessages, _activeSessionInput, and the old PreparedPromptInput / PreparedCommandInput shapes in favor of _actionStore. Enqueue, cancel, clear-queue, coalescing, steering-stop, and recovery snapshots all go through the store; legacyPendingProjection keeps external queue/previews/recovery wire behavior unchanged until a later protocol break.

The session input pump selects via canSelectSessionAction / shouldYieldLowerRun, batches turns at selection time (commands as barriers), runs preparing → committing → running → completed (or rollback with transcript proof), and settles tickets on success/failure. message_start / message_end now update delivery records and drive committing → running for primary turns. /compact successor checks use literal queuedActions() so an executing command no longer counts as its own queued successor (internal fix; display quirk preserved via legacy projection).

Tests add session-action-store.test.ts and retarget harnesses from internal queue fields to _actionStore / _createPreparedTurnAction.

Reviewed by Cursor Bugbot for commit 09e9e1e. Bugbot is set up for automated code reviews on this repo. Configure here.

Comment thread packages/coding-agent/src/core/agent-session.ts
Comment thread packages/coding-agent/src/core/agent-session.ts
Comment thread packages/coding-agent/src/core/agent-session.ts
@snimu
snimu force-pushed the refactor/session-action-kernel branch from 1b02e9c to 6ae3af0 Compare August 1, 2026 21:20
Comment thread packages/coding-agent/src/core/agent-session.ts
Comment thread packages/coding-agent/src/core/agent-session.ts
snimu added a commit that referenced this pull request Aug 1, 2026
…tion pending checks

The underlying bugs originate in PR #573, but this fix lands at the stack head in PR #576 to avoid rebasing three dependent PRs immediately before release.
@snimu
snimu force-pushed the refactor/session-action-kernel branch from 6ae3af0 to 38da9c5 Compare August 2, 2026 10:14
snimu added a commit that referenced this pull request Aug 2, 2026
…tion pending checks

The underlying bugs originate in PR #573, but this fix lands at the stack head in PR #576 to avoid rebasing three dependent PRs immediately before release.
@snimu
snimu force-pushed the refactor/session-action-kernel branch from 38da9c5 to e9e7486 Compare August 2, 2026 13:43
snimu added a commit that referenced this pull request Aug 2, 2026
…tion pending checks

The underlying bugs originate in PR #573, but this fix lands at the stack head in PR #576 to avoid rebasing three dependent PRs immediately before release.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e9e7486. Configure here.

Comment thread packages/coding-agent/src/core/agent-session.ts
Comment thread packages/coding-agent/src/core/agent-session.ts
@alexzhang13
alexzhang13 force-pushed the refactor/session-action-kernel branch from e9e7486 to 46f328f Compare August 2, 2026 20:00
@alexzhang13
alexzhang13 force-pushed the refactor/session-action-kernel branch from 46f328f to 09e9e1e Compare August 2, 2026 20:23
alexzhang13 pushed a commit that referenced this pull request Aug 3, 2026
…tion pending checks

The underlying bugs originate in PR #573, but this fix lands at the stack head in PR #576 to avoid rebasing three dependent PRs immediately before release.
alexzhang13 pushed a commit that referenced this pull request Aug 3, 2026
…tion pending checks

The underlying bugs originate in PR #573, but this fix lands at the stack head in PR #576 to avoid rebasing three dependent PRs immediately before release.
alexzhang13 pushed a commit that referenced this pull request Aug 3, 2026
…tion pending checks

The underlying bugs originate in PR #573, but this fix lands at the stack head in PR #576 to avoid rebasing three dependent PRs immediately before release.
@snimu
snimu merged commit c1b2a7d into main Aug 3, 2026
11 checks passed
snimu added a commit that referenced this pull request Aug 3, 2026
* 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 #573, but this fix lands at the stack head in PR #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 #574/#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 #576)

* fix(coding-agent): revalidate commands after commit fence (fixes #576)

---------

Co-authored-by: Alex Zhang <alex.lx.zhang@gmail.com>
@kevinjosethomas
kevinjosethomas deleted the refactor/session-action-kernel branch August 5, 2026 18:54
zhengr pushed a commit to zhengr/prime-agent that referenced this pull request Aug 8, 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants