Skip to content

Claude closed queries can retain running subagents in the session pending-work probe #305

Closed

Description

@lukemaj

What: Claude's session pending-work probe can retain running native subagents after their CLI query has detached.
Why: Query closure ends open tool calls and projection rows, but the session registry's running status still feeds hasPendingBackgroundWork without checking the live process.
So what: Reproduce the session retention through the adapter and repair the probe or registry owner; #285 keeps its urgent-delivery scope.

Outcome

A closed Claude CLI process does not indefinitely pin its idle provider session through native subagents it can no longer run. This supports reliable long-running Promachos and Drafter work in the Objective.

Source evidence and limits

Observed while reviewing #285 at PR #300 head 1a8a1977be27a7d0207accdfa9be5e8e44acc3ab against main 14f6e5d5b3465e12fb77362cc0ef88db5f8f1fac:

  • ClaudeAdapterV2.hasPendingBackgroundWork returns true for any sessionSubagentsByTaskId entry whose task status is running.
  • endSubagentCallsOfClosedQuery ends open tool calls but does not change that registry; active-turn finalization likewise does not terminalize its session task entries.
  • liveProcessRunsBackgroundWork already distinguishes entries from earlier processes through subagentsFromEarlierProcesses, while the session-wide pending-work probe does not.
  • Query-exit/Stop paths predate Restore explicit urgent interruption after Claude steer queuing #285. Its hard restart adds another caller of the same close path. Projection settlement alone cannot update this adapter-local registry.

This is a source finding, not a native leak or hung-root reproduction. The SDK may deliver terminal task notifications before some closes; that does not establish the probe when the query exits without them. #222 is a root-turn hang with unknown cause, while #299 is surviving work's event ownership; neither currently records this closed-process session-retention case.

Acceptance

  • Use the real adapter with a native background subagent that starts but emits no terminal notification, then close/detach the query and assert the session probe becomes false once buffers/other live work are empty.
  • Keep actually running sibling-native-thread tasks and buffered wake output pending.
  • Decide whether the registry needs terminal state or whether the probe should derive runtime ownership, without losing resumable child identity.
  • Use Deferred/receipt milestones and TestClock, no sleeps; check upstream before implementation.

Non-goals and blockers

No native process leak, root-turn hang, immediate production action or deployment is claimed. No implementation in this report. The adapter reproduction is the next proof.

Elon record

Requirements and who asked: Global Work requires recording found owner defects; the user requires truthful lifecycle state and stable Promachos/Drafter orchestration.
Deleted: No speculative #222 cause, native leak claim, production cleanup, new watcher or broad registry rewrite.
Bottleneck: Establish the adapter-level probe result after a close that has no native task terminal frame.
Checked myself: Read the session-wide probe, live-process predicate, registry writes, query-exit and closed-query call settlement; searched open Claude/background-session Issues and compared #222/#299.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions