Skip to content

fix(opencode): close Linux stop orphan windows#460

Draft
vansin wants to merge 1 commit into
mainfrom
fix/opencode-stop-orphan-window
Draft

fix(opencode): close Linux stop orphan windows#460
vansin wants to merge 1 commit into
mainfrom
fix/opencode-stop-orphan-window

Conversation

@vansin

@vansin vansin commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Outcome

This draft closes the Linux OpenCode stop-orphan window and records the 2.3.0-preview.35 / 2.5.0-preview.27 evidence pair. It does not publish either package or change any dist-tag.

  • launches OpenCode behind a detached Linux session/process-group supervisor with prepare/activate receipts
  • makes wrapper shutdown TERM-only and requires exact PID/start-time plus empty session/group proof before reporting exit
  • retains owner state on timeout, SIGSTOP, supervisor loss, or residual descendants
  • hardens launch-root markers, stale-root cleanup, and shutdown admission so queued turns cannot reopen a runtime during exit
  • makes bound stop/rename/project/batch/delete paths fail closed instead of falling back to alias/PID SIGKILL behavior
  • preserves failure reports from the iterative gate work

Root cause

The old launcher could time out and SIGKILL only the agent-node wrapper while its detached OpenCode ACP process survived. A second race allowed a turn queued before SIGTERM to enter the OpenCode opening path after shutdown had already cleaned the first client, leaving a credential-scoped launch root behind.

Linux validation on commit 1f1f04d9

All seven RFC-029/OpenCode Docker gates passed on this exact source tree:

  • PR1 registration/start smoke — PASS
  • PR2 mocked ACP shim — PASS
  • PR3 preset + safe-refusal exit code — PASS
  • PR4 real opencode-ai@1.18.1 kernel-live — PASS, zero post-stop PIDs
  • test226 release pin matrix — PASS, zero post-stop PIDs
  • test386 agent-node/security/lifecycle gate — PASS
  • test384 local-package E2E — PASS in 3 consecutive runs; L5 transient roots=0 and L7 global orphan audit=0

git diff --check is clean. The staged secret scan found only explicitly synthetic test fixtures; no real credential was added.

DO NOT MERGE / promote remains frozen

This is intentionally a draft. Review found two unresolved blockers:

  1. Non-Linux bound stop: exact wrapper ownership currently depends on Linux /proc. Windows/macOS bound stop therefore fails closed rather than completing successfully. A platform design plus real Windows validation is required.
  2. Concurrent start/rename: rename snapshots wrapper liveness once, while start does not participate in a durable external lifecycle lock. A start racing after the scan can outlive removal of the old binding/config. Add a per-node cross-process lifecycle lock and deterministic race coverage.

Required before merge/promote: resolve both blockers, rerun affected gates on the new head, pass true Windows validation, and review the draft CI (especially the hard rename-ghost-gate).

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