feat(cli): add a fail-closed --cancel-worktree command that safely tears down a cancelled agent's leased workspace (#230)#231
Merged
Conversation
…ars down a cancelled agent's leased workspace (#230) cleanWorktreeLease (#50) only cleans a lease after its work is verified complete and merged; nothing defined the safe teardown path for an agent cancelled mid-work, so a naive cancellation could leave a dangling worktree, an unreleased lease, or silently discard committed work. Add cancelWorktreeLease plus an opt-in --cancel-worktree [--cancel-force] command that preserves committed work by keeping the lease branch (reporting the preserved commits for later integration via #228), removes the worktree, and fails closed on uncommitted changes unless --cancel-force acknowledges the discard. Idempotent (cancelling an absent lease is a no-op) and never touches the parent worktree.
Owner
Author
E2E verification
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an opt-in (
--cancel-worktree) fail-closed command that safely tears down a cancelled agent's leased workspace, decomposed from roadmap #39 (isolated parallel agents).cleanWorktreeLease(#50) only cleans a lease after its work is verified complete and merged; nothing defined the safe teardown path for an agent cancelled mid-work, so a naive cancellation could leave a dangling worktree, an unreleased lease, or silently discard committed work.Design
src/worktree-lease.ts: newcancelWorktreeLease(opts, { force })(reusing the module's identity/git helpers) plusformatWorktreeCancelResult. UnlikecleanWorktreeLease, cancellation preserves committed work by keeping the lease branch (reporting the preserved, bounded/redacted commits for later integration via Parallel integration: reviewably integrate a parallel agent's branch into the target, preserving commit identity and failing closed on conflict or dirty state #228) and only removing the worktree. It fails closed on uncommitted changes unlessforceacknowledges the discard, is idempotent (cancelling an absent lease is a no-op), and never touches the parent worktree.src/index.ts: opt-in--cancel-worktreewith--cancel-force, wired into the existing leased-worktree mode (JSON + text), exiting 0 on success, 1 on a safety refusal, and 2 on a usage/git error.Testing
tests/unit/cancellation-cleanup.test.ts(8 tests): clean cancellation (worktree removed, branch preserved), preserved-commit reporting, fail-closed on uncommitted work,--cancel-forcediscard, idempotent no-op on an absent lease, missing-identity refusal, and formatting.tests/integration/cancellation-cleanup.test.ts(4 tests): CLI cancels a clean lease (worktree removed, branch preserved), refuses a dirty lease without--cancel-force(exit 1, worktree retained), discards with--cancel-force(exit 0), and rejects combining--cancel-worktreewith--clean-worktree(exit 2).Gates: typecheck, build, unit (1647), integration (455 + desktop), smoke (51) all pass.
Closes #230