Skip to content

[Bug] Windows ACP shutdown can leave descendants running or silently accept cleanup failure #429

Description

@slashdevcorpse

Affected area

Agent runtime / ACP

Installation method

Built from source

Lody version or commit

12f919b

Operating system

Windows x64; deterministic Windows-platform unit fixtures, with POSIX regression coverage.

Agent or runtime

Lody auxiliary ACP processes and session sandbox process handles; provider-independent shutdown code.

What happened?

Source inspection found that auxiliary ACP shutdown calls ChildProcess.kill on Windows, which only targets the wrapper. The fallback session sandbox invokes taskkill /T but treats any helper close code as success and has no deadline. Session.killAndWait waits indefinitely after forced termination and recognizes exitCode but not signalCode; Session.terminate also swallows sandbox errors before reporting terminated.

These are reproducible lifecycle defects. They do not establish a native Codex memory leak or prove that completed native subagents retain MCP servers.

What did you expect?

For a still-live owned Windows root, await bounded recursive termination, validate helper success, observe root exit, and surface cleanup failure. Recognize signal-only exits. Never use an exited root's cached PID to authorize killing another process.

How can we reproduce it?

  1. In a Windows-platform auxiliary ACP fixture, provide a live wrapper and invoke cleanup; observe direct child.kill without recursive taskkill.
  2. In the fallback sandbox fixture, make taskkill emit close with code 1; termination currently resolves.
  3. Give Session a process handle whose force termination resolves but which never exits; advance a fake clock beyond five seconds and observe that shutdown remains pending.
  4. Make sandbox termination reject; observe that Session still emits terminated.

The accompanying patch adds deterministic regression tests for these boundaries.

How often does it happen?

Every time with the specified fixtures.

Additional context

Scope is normal explicit shutdown of live owned roots. Unexpected wrapper exit and native provider subagent cleanup need durable descendant ownership (for example Windows Job Objects); taskkill success alone does not prove the entire tree is empty. No global process scans or image-name killing are proposed.

Before submitting

  • I searched the existing issues and did not find a duplicate.
  • This report concerns an open-source component in this repository, not a hosted service, Web or mobile app, account, or billing issue.
  • This is not a security vulnerability; security reports follow the repository's security policy.
  • I removed credentials, private source, conversations, prompts, personal data, and other sensitive information.

Implementation: upstream PR series

The implementation is submitted to LodyAI/Lody in dependency order:

  1. [1/3] fix: bound Windows ACP shutdown and retain failed cleanup #456 — bounded shutdown and retained cleanup ownership.
  2. [2/3] fix: protect background sessions and record resource history #457 — background-aware eviction and resource history; depends on [1/3] fix: bound Windows ACP shutdown and retain failed cleanup #456.
  3. [3/3] fix: own Windows process trees with native job supervision #458 — native Windows Job Object ownership; depends on [1/3] fix: bound Windows ACP shutdown and retain failed cleanup #456 and [2/3] fix: protect background sessions and record resource history #457.

These replace the fork-only PRs and the earlier closed #430/#435 submissions. Source branches retain linear ancestry; later PRs have cumulative upstream diffs, with individual-layer comparisons in their descriptions. GitHub native cross-fork stack metadata is unavailable. The complete series supplies the Windows descendant/crash ownership fix. Nothing has merged; this issue remains open.

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