Skip to content

fix(acp): prevent process startup after disposal - #6186

Open
Sun-GLiang wants to merge 5 commits into
apache:mainfrom
Sun-GLiang:codex/fix-acp-cleanup-retry
Open

Sun-GLiang wants to merge 5 commits into
apache:mainfrom
Sun-GLiang:codex/fix-acp-cleanup-retry

Conversation

@Sun-GLiang

@Sun-GLiang Sun-GLiang commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

Summary

Disposing an ACP conversation or executor while initialization is awaiting state or filesystem checks can return before the Agent process starts. Initialization then continues, allowing a process and prompt to run after disposal. Check executor and session disposal immediately before creating the connection, and return acp_unavailable instead.

This is a defensive fix for direct executor lifecycle calls. Production PluginExecutorService already cancels and drains active operations before retirement. The change is limited to this startup guard and two real stdio regressions.

Verification

  • 97 ACP tests and 9 Antigravity adapter tests pass, including real-process regressions for conversation disposal and executor disposal during startup. The regressions use real filesystem checks, the ACP SDK, and OS processes, with no mocked connections, delayed I/O, or injected cleanup failures.
  • Removing only the startup guard makes both new tests fail: a real Agent starts and completes the prompt after disposal. Restoring the guard makes both pass. Failure-path test cleanup terminates the spawned process.
  • Full-repository build, typecheck, lint, and format checks pass. Desktop/UI knip checks, Windows test inventory (135 declarations), and diff checks pass.
  • Full-repository tests and Desktop UI end-to-end tests were not run.

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: OpenAI Codex implemented the startup guard and real-process regressions, performed baseline and ablation checks, ran validation, and prepared this PR. AI-authored commits include Generated-by: OpenAI Codex trailers.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@github-actions github-actions Bot added the effort/L Under 1000 readable lines label Oct 20, 2026
Opt ACP disposal into retryable Effects and keep failed resource owners reachable through parent shutdown. Retry only unfinished cleanup while preserving default Effect semantics and disposed Context fencing.

Generated-by: OpenAI Codex
Retain failed cleanup attempts through Platform, domain modules, and execution composition. Retry once before Kernel releases root ownership, preserve persistent failures, and skip resources already closed successfully.

Generated-by: OpenAI Codex
Retain only the pre-spawn disposal check and real stdio regressions for conversation and executor disposal. Restore retry-related changes to the PR base.

Generated-by: OpenAI Codex
@Sun-GLiang Sun-GLiang changed the title fix(acp): retry failed session and catalog cleanup fix(acp): prevent process startup after disposal Oct 20, 2026
@github-actions github-actions Bot added effort/S Under 100 readable lines and removed effort/L Under 1000 readable lines labels Oct 21, 2026
@Sun-GLiang
Sun-GLiang marked this pull request as ready for review October 21, 2026 08:34

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review notice: This comment was posted by an automated review agent. It is not an independent human review and does not replace one.

I reviewed both changed files at 796182866727b040561f1d31018442fe0ca5ff84 (+37/-0). I found no confirmed P0–P2 issue.

packages/acp-executor-plugin/src/index.ts:627 now checks executor shutdown and conversation loss after the asynchronous state/executable checks and immediately before creating the stdio connection. disposeConversation marks the retained session lost, and executor disposal sets the executor flag first, so either closure fences a startup that resumes later. There is no asynchronous gap between the new check and connection creation.

All 97 ACP executor-plugin tests passed, including the two real-process startup/disposal regressions. As a countercheck, I left the tests unchanged and removed only the new guard from the loaded implementation: both regressions failed because the request completed after disposal instead of returning acp_unavailable. Their cleanup terminated the fixture processes. Normal startup and the existing disposal/restore cases also passed in the unchanged suite.

Fresh dependency installation/patches, the normal clean root test build, plugin type checking, Biome on both changed files and git diff --check passed. There is no protocol change. A static merge with current main 9826db1b9dad32897be105b2c1c621becedb27ce is clean, and the protocol guard passes on that merge result at epoch 226; the branch itself remains at 225. I did not build the merged tree separately.

The exact-head CI test and label checks succeeded. These checks use controlled stdio agents on Linux; I did not exercise a real authenticated agent, Windows/macOS, or the full Desktop application.

This branch has not been deployed

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

Labels

effort/S Under 100 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants