Skip to content

fix(coding-agent): reject headless idle waiters when a post-compaction continuation cannot start - #1583

Merged
xeophon merged 5 commits into
mainfrom
fix/headless-idle-continuation-failures
Aug 20, 2026
Merged

fix(coding-agent): reject headless idle waiters when a post-compaction continuation cannot start#1583
xeophon merged 5 commits into
mainfrom
fix/headless-idle-continuation-failures

Conversation

@snimu

@snimu snimu commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #1494 and #800; ports the failure semantics from #881 (closed in favor of #1494's settlement placement).

Linear: ENG-5400 — https://linear.app/primeintellect/issue/ENG-5400/headless-idle-must-surface-post-compaction-continuation-start-failures

Problem

#1494's post-compaction continuation settlement is resolve-only: _runScheduledPostCompactionContinue swallows a continuation that fails to start (.catch(() => undefined)), and _settlePostCompactionContinue resolves the waiters. A headless caller (ACP session/prompt, print mode) waiting on waitForHeadlessIdle then observes a clean finish for a continuation that never ran — the turn silently loses its tail.

#881 solved this by rejecting idle waiters, but built the wait into waitForIdle globally, which would have exposed interactive and extension callers to a new rejection path. #1494's placement (headless-scoped waitForHeadlessIdle wrapper, waitForIdle untouched) is the right architecture, so this PR ports only the failure semantics onto it.

Change

  • The settlement is now one-shot (settled flag): a failed settlement is cleared in the same step and never re-exposed to later waiters.
  • _settlePostCompactionContinue(error?) rejects waiters on a non-retryable start failure; an error settles immediately, while a resolve still defers to a scheduled/timer-pending retry that owns the settlement next.
  • The "already processing" retry loop is unchanged; "continue from" errors (turn already completed — nothing left to continue) still settle as a clean finish. That benign race was previously invisible under the blanket swallow; feat(acp): harden resident session lifecycle #1494's own "headless idle includes a successful post-compaction continuation" test caught the distinction when the swallow came off.
  • Interactive waitForIdle is untouched — a placement-contract test pins that it keeps resolving through a failed continuation.

isSessionActive integration and all #1494 settle sites (cancel, dispose, abort, update-restart, ownership change) are unchanged; they settle as resolves.

Consumer

#1494's ACP error boundary already handles a rejected waitForHeadlessCompletion: the turn gets one correlated error response-boundary and never an invented terminal-quiescence update. This PR completes that path — before it, the rejection branch was unreachable from the continuation side.

Tests

Two, both pinning behavior this PR introduces (adapted from #881 — credit @parkerpettit):

  • rejects headless idle waiters when a continuation cannot start
  • does not expose a failed continuation to later headless idle waiters

Validation

  • npm run check, build clean
  • 595 tests across the affected suites (compaction-continuation, compaction, acp-mode, print-mode, recursion, queue, daemon connections): all passing

+56/−6 in three files.


Note

Cursor Bugbot is generating a summary for commit 20d4f80. Configure here.

Note

Reject headless idle waiters when post-compaction continuation fails to start in AgentSession

  • Introduces PostCompactionContinuationSettlement with a settled flag so a failed settlement is one-shot and not re-exposed to later waiters.
  • _settlePostCompactionContinue now accepts an optional Error and rejects the settlement promise on failure instead of always resolving.
  • _runScheduledPostCompactionContinue calls _settlePostCompactionContinue with the error when agent.continue() fails for reasons other than already processing.
  • Interactive idle behavior is unchanged; only ACP and print-mode headless waiters are affected.
  • Risk: callers of AgentSession.waitForHeadlessIdle that did not handle rejection may now see unhandled promise rejections when a scheduled continuation cannot start.

Macroscope summarized eb0a42c.

…n continuation cannot start

A continuation that fails to start settled headless idle as a clean finish,
so ACP and print-mode callers reported a turn as completed that never ran.
The settlement is now one-shot with reject support: non-retryable start
failures reject waiters, cancellation and the benign nothing-to-continue
race still resolve, a settled failure is never re-exposed to later waiters,
and interactive waitForIdle is unchanged.

Ports the failure semantics from #881 onto the resident-lifecycle settlement
from #1494. Co-authored-by: Parker Pettit <parkerpettit@users.noreply.github.com>

@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 1 potential issue.

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 20d4f80. Configure here.

Comment thread packages/coding-agent/src/core/agent-session.ts Outdated
xsyetopz added a commit to xsyetopz/prime-agent-next that referenced this pull request Aug 20, 2026
snimu added 2 commits August 20, 2026 12:54
…tinuation-failures

# Conflicts:
#	packages/coding-agent/CHANGELOG.md
…tinuation-failures

# Conflicts:
#	packages/coding-agent/CHANGELOG.md
@xeophon
xeophon merged commit ab3db32 into main Aug 20, 2026
20 checks passed
@xeophon
xeophon deleted the fix/headless-idle-continuation-failures branch August 20, 2026 13:57
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