Skip to content

fix(core): reap worktrees for terminated sessions#1532

Open
ChiragArora31 wants to merge 5 commits into
AgentWrapper:mainfrom
ChiragArora31:codex/reap-terminated-worktrees
Open

fix(core): reap worktrees for terminated sessions#1532
ChiragArora31 wants to merge 5 commits into
AgentWrapper:mainfrom
ChiragArora31:codex/reap-terminated-worktrees

Conversation

@ChiragArora31

@ChiragArora31 ChiragArora31 commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Problem

ao session cleanup could report already-terminated sessions as handled while leaving their managed worktrees on disk. This happens when lifecycle metadata reaches terminated through paths such as runtime_lost or a previous interrupted kill before workspace cleanup ran.

Closes #1524.

What changed

  • Allows kill() to safely retry workspace-only cleanup for sessions whose lifecycle is already terminal.
  • Keeps runtime and agent teardown idempotent for already-terminated sessions.
  • Makes cleanup() report already-terminated sessions as cleaned only when it actually reaps a remaining managed worktree or OpenCode mapping.
  • Adds regression tests for direct kill, cleanup, and repeated cleanup idempotency.

Validation

  • pnpm --filter @aoagents/ao-core test -- src/__tests__/session-manager/lifecycle.test.ts
  • pnpm --filter @aoagents/ao-core typecheck
  • pnpm --filter @aoagents/ao-core build && pnpm --filter @aoagents/ao-plugin-tracker-github build && pnpm --filter @aoagents/ao-plugin-scm-github build
  • pnpm --filter @aoagents/ao-core test

Checklist

  • Tests added/updated
  • No breaking changes

Use a single expression for cleanedTerminatedWorkspace in cleanup() so eslint no-useless-assignment passes while preserving dry-run and kill-path behavior.

Made-with: Cursor
@ChiragArora31 ChiragArora31 marked this pull request as ready for review April 28, 2026 16:56
@greptile-apps

greptile-apps Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a resource-leak bug where managed worktrees could be left on disk after a session's lifecycle was already marked terminated (e.g., via runtime_lost or a previously interrupted kill). The fix allows kill() to perform a safe, workspace-only cleanup retry when a session is already terminal, and wires the cleanup loop to report those sessions as killed rather than skipped.

  • Extracts destroyManagedWorkspace() and hasReapableManagedWorkspace() helpers to deduplicate workspace-destruction logic across kill() and cleanup().
  • Updates the terminated-session fast-path in kill() to attempt workspace reap (with requireExisting: true) before returning { cleaned, alreadyTerminated: true }.
  • Updates the cleanup() second loop to call kill() for terminated sessions and use cleanedTerminatedWorkspace to decide killed vs skipped, covering both standalone-worktree and OpenCode-agent sessions.

Confidence Score: 5/5

Safe to merge; changes are narrowly scoped to workspace-only cleanup for already-terminated sessions, with no new side effects on live sessions.

The fix correctly adds requireExisting: true to the terminated fast-path to avoid spurious destroy calls, invalidates the cache only when a workspace was actually reaped, and keeps runtime/agent teardown skipped for already-terminated sessions. Three targeted regression tests cover the new paths including idempotency on double-cleanup.

No files require special attention.

Important Files Changed

Filename Overview
packages/core/src/session-manager.ts Core fix: adds destroyManagedWorkspace/hasReapableManagedWorkspace helpers and updates kill() terminated fast-path and cleanup() second loop to reap orphaned worktrees; logic is correct and idempotent.
packages/core/src/tests/session-manager/lifecycle.test.ts Adds three regression tests covering direct kill, cleanup reap, and idempotent double-cleanup for already-terminated sessions; mock isolation is correct via beforeEach/afterEach.
packages/core/src/types.ts Updates KillResult JSDoc to accurately reflect that cleaned and alreadyTerminated can both be true simultaneously.
.changeset/reap-terminated-session-worktrees.md Adds a patch-level changeset entry for @aoagents/ao-core describing the fix.

Reviews (2): Last reviewed commit: "Merge remote-tracking branch 'upstream/m..." | Re-trigger Greptile

@ChiragArora31

Copy link
Copy Markdown
Contributor Author

Rechecked this after the earlier lint failure: the current PR checks are green, including Lint. I also rebuilt locally before running tests so stale dist output does not affect validation.

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.

ao session cleanup leaves worktrees on disk for sessions already in terminal lifecycle state

1 participant