fix(coding-agent): honest status and prompt eviction for empty sessions - #1920
Merged
Conversation
…f pinning it at working (ENG-5809)
…last client disconnects (ENG-5809)
…G-5809 review) Adversarial-review killer tests for three mutants that survived the shipped suite: dropping the heartbeat/cron registration checks from isEvictableEmptySessionSummary, dropping the client-owned worker exclusion, and removing the post-refresh identity/stopping re-check in evictEmptySessionOnLastDetach.
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 d63475f. Configure here.
…dle sweep and detach eviction (ENG-5809 review)
xeophon
approved these changes
Aug 31, 2026
PR9000
pushed a commit
to PR9000/prime-agent
that referenced
this pull request
Sep 1, 2026
…ns (PrimeIntellect-ai#1920) * fix(coding-agent): report an empty resident session as idle instead of pinning it at working (ENG-5809) * feat(coding-agent): evict an empty unnamed session's worker when its last client disconnects (ENG-5809) * test(coding-agent): kill surviving empty-session eviction mutants (ENG-5809 review) Adversarial-review killer tests for three mutants that survived the shipped suite: dropping the heartbeat/cron registration checks from isEvictableEmptySessionSummary, dropping the client-owned worker exclusion, and removing the post-refresh identity/stopping re-check in evictEmptySessionOnLastDetach. * chore(coding-agent): fold empty-session tests and trim comments * fix(coding-agent): drain admitted mutations before deciding empty-session eviction (ENG-5809 Macroscope) * chore(coding-agent): drop comments that restate the code * fix(coding-agent): share one eviction-fence acquisition between the idle sweep and detach eviction (ENG-5809 review) * refactor(coding-agent): extract the shared fenced passivation primitive (ENG-5809)
ketema
added a commit
to ketema/prime-agent
that referenced
this pull request
Sep 1, 2026
- Direct session transport between TUI and worker (ENG-5817, PrimeIntellect-ai#1926) - Event-driven supervisor agent roster with push subscriptions (PrimeIntellect-ai#1897, PrimeIntellect-ai#1900, PrimeIntellect-ai#1895) - Hardened daemon startup, recovery ownership, and worker launch diagnostics (PrimeIntellect-ai#1929, PrimeIntellect-ai#1918) - Python REPL runtime single-dump snapshots and bash preview tool (PrimeIntellect-ai#1945, PrimeIntellect-ai#1911) - Non-blocking RLM subagent deletion and snapshot update suppression (PrimeIntellect-ai#1954, PrimeIntellect-ai#1944) - Saved catalog loading on Agents View open (PrimeIntellect-ai#1960) - Advanced Anthropic prompt caching marker across tool results (PrimeIntellect-ai#1927) - TUI process replacement on update and empty draft eviction (PrimeIntellect-ai#1631, PrimeIntellect-ai#1946, PrimeIntellect-ai#1920)
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.

Two empty-session lifecycle fixes, found while investigating the macOS "ctrl+c never ends the session / after a couple of sessions it can't create a new one" report (companion to #1918).
Status honesty
A 0-message detached session was pinned at "working" forever - rendered as a red running entry in the agents view and
prime-agent list- becauseactiveActivityForSessionholds sessions at "working" until a summarizer verdict exists, and an empty session never produces one. Users reasonably concluded that exiting "never ends the session". The fix is the same carve-out finished subagents already have: a session with 0 messages and nothing in flight is idle. An accepted in-flight first prompt still shows "working" (the busy guard runs first, pinned by test).Evict empty unnamed sessions on last-client disconnect
An abandoned empty session parked a resident worker (~80 MB) plus an IPython kernel for the 90-minute idle-eviction window, holding 2 daemon file descriptors - the accumulation ingredient behind the EMFILE failure fixed in #1918. Now, when the last client disconnects from a worker whose sessions are all empty (0 messages), unnamed, not busy, and hold no heartbeat/cron registration, the supervisor passivates it immediately through the existing eviction path. Action-driven only - no new timers. Naming a session exempts it (that is the "I want to come back" signal); client-owned workers keep their existing cleanup path; eviction remains passivation, so the on-disk session survives as a draft.
Races verified against the ownership machinery from #1756/#1864: a create/attach arriving mid-stop fails cleanly with "worker is stopping" and relaunches from the draft; the eviction re-checks worker identity after its summary refresh and cannot stop a relaunched successor (stopWorker additionally pins the entry pid). Cold reopen of an evicted draft measures ~0.55s on macOS, indistinguishable from a warm attach.
Deliberately not gated on
idleEvictionMinutes: "off": everything a user wants kept warm (messages, a name, a schedule, an attached client) already blocks this eviction, and gating would reinstate the leak for exactly the users most exposed to it.Tests
Six behavior tests plus one extended assertion across
daemon-session-listand a newdaemon-supervisor-evictioncase set: empty-idle status (proven red), the in-flight-first-prompt guard, last-client-only eviction (proven red), named/busy/non-empty exemptions, schedule-pinned and client-owned exemptions, and a replaced-worker race guard.Linear: ENG-5809
Note
Medium Risk
evictEmptySessionOnLastDetachstops workers on detach; reconnecting spins up a new worker, and fence/drain logic must stay correct alongside idle sweeps and mid-flight mutations.Overview
Fixes two empty-session lifecycle issues in the coding-agent daemon: misleading "working" status and workers staying resident after abandon.
Status:
activeActivityForSessionnow treats zero-message resident sessions as idle (like finished subagents), soprime-agent listand the agents view no longer show abandoned empty drafts as permanently running. Sessions with real in-flight work still report working first.Eviction: When the last client detaches or disconnects, the supervisor may passivate the worker immediately if every session on it matches
isEvictableEmptySessionSummary(no messages, no name, not busy, no heartbeat/cron). Named sessions, busy sessions, client-owned workers, and multi-attach cases are exempt; eviction reuses the idle-sweep mutation drain + fence (withEvictionFence) so detach eviction and periodic idle sweeps do not race. On-disk draft sessions are preserved.Tests cover empty-idle classification, detach-only eviction, exemptions, worker-replacement races, and fence coordination with idle sweeps.
Reviewed by Cursor Bugbot for commit 2114326. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Fix
coding-agentdaemon to report idle status and evict empty sessions on detach"idle"instead of staying pinned at"working"in daemon-session-list.ts.daemon-supervisor.evictEmptySessionOnLastDetach.withEvictionFence) that drains pending mutations before the decision, preventing races with in-flight worker refreshes or schedules registered during the drain.daemon-supervisorclient disconnect anddetachcommand handlers now trigger eviction for qualifying empty sessions; sessions that were previously kept alive will be passivated immediately.Macroscope summarized 2114326.