Skip to content

Fix retained sub-agent session leaks and close_agent false success - #623

Closed
TheGreatAxios wants to merge 1 commit into
mainfrom
cl-7001-retained-sessions-never-release-and-close-agent-can-false-succeed
Closed

Fix retained sub-agent session leaks and close_agent false success#623
TheGreatAxios wants to merge 1 commit into
mainfrom
cl-7001-retained-sessions-never-release-and-close-agent-can-false-succeed

Conversation

@TheGreatAxios

Copy link
Copy Markdown
Collaborator

Summary

Four resource-leak / false-success defects in the CL-6943 retained-session lifecycle (session-store.ts, agent-fleet.ts, run.ts):

  1. Every spawn_agent worker leaked by default. pruneCompleted no longer exempts retained-completed sessions from any bound — they now share the same maxCompleted cap every other finished session already used, and eviction releases the session's close handle (LSP sidecars, reactor, @intx/agent lock entry) instead of abandoning it. cancelAll and clear() now also release every still-open retained session directly (not gated on status === "running", which a retained "done" session never satisfies).
  2. close_agent during agent setup falsely reported success. closeOne now waits (bounded by the same deadline) for registerClose to fire if it hasn't yet, instead of finding no handle and returning a false "shutdown". If the window never closes in time it returns the session's honest in-progress status so a retry can still find it.
  3. A disposed salvage looked resumable. complete() takes an agentRetained flag (threaded from RunSubAgentResult.agentRetained, set only on run.ts's clean-completion path when persist actually skipped teardown); a deadline/cancel salvage resolves the same promise but always disposed its agent, so it now clears retained instead of leaving the session resumeOne-eligible.
  4. The parent-abort listener was torn down on the persist path. createSubAgentRunController.dispose() takes a keepParentListener option; a persisting run keeps the forwarding listener alive so a later parent cancel still reaches the registered close handle (which fully disposes the controller once the session actually closes).

Test plan

  • bun test src/subagent/ — 273 pass (includes new src/subagent/retain-salvage.test.ts, copied from the provided starting point and extended with setup-window / clear() / genuinely-resumable cases)
  • bun run check (lint + typecheck + build + full test suite) — 5342 pass, 0 fail

Retained sessions were exempt from any cap/TTL and never released on
cancelAll/clear; close_agent during agent setup returned false success
over an unreleasable session; a disposed salvage still looked resumable;
and the parent-abort listener was torn down on the persist path,
stranding a retained session's LSP sidecars, reactor, and @intx/agent
lock entry.

- session-store.ts: fold retained-completed sessions into the existing
  maxCompleted bound (no separate cap needed) and release their close
  handle on eviction; cancelAll and clear() now invoke closeHandles for
  every still-open retained session; closeOne waits (bounded) for
  registerClose during the setup window instead of reporting shutdown
  with nothing to release, and reports the honest in-progress status if
  the window never closes in time; complete() only leaves a session
  resumable when the caller confirms the agent actually survived the
  turn (agentRetained), so a disposed salvage can't look reusable.
- run.ts: keep the run controller's parent-abort forwarding alive for a
  persisted session so a later parent cancel still reaches the
  registered close handle; the close handle itself fully disposes the
  controller once the session actually closes.
- types.ts / agent-fleet.ts: thread agentRetained through
  RunSubAgentResult so the store can tell a clean, still-open completion
  apart from a resolved-but-disposed salvage.
@linear-code

linear-code Bot commented Aug 24, 2026

Copy link
Copy Markdown

CL-7001

@TheGreatAxios

Copy link
Copy Markdown
Collaborator Author

Superseded by the same commits on a correctly-named branch — this one would have auto-closed CL-7001 instead of CL-7002.

@TheGreatAxios
TheGreatAxios deleted the cl-7001-retained-sessions-never-release-and-close-agent-can-false-succeed branch August 28, 2026 00:09
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.

1 participant