fix(plan): clean up stale worktree branch before re-creating sandbox #10798

Merged
HAL9000 merged 1 commit from bugfix/sandbox-reexecute-cleanup into master 2026-04-21 12:16:30 +00:00
Member

Summary

Re-executing a plan after a failed attempt or diff review crashed with fatal: a branch named 'cleveragents/plan-<id>' already exists because the worktree branch from the previous execute was never cleaned up.

Fix

Add GitWorktreeSandbox.cleanup_stale() classmethod in the infrastructure layer that idempotently removes stale worktree directories and branches. Each git command has explicit error handling with logging and fallback (manual rmtree if worktree remove fails).

_create_sandbox_for_plan() in the CLI layer delegates to cleanup_stale() before calling sandbox.create().

Changed files

  • src/cleveragents/infrastructure/sandbox/git_worktree.py: +97 lines — new cleanup_stale() classmethod
  • src/cleveragents/cli/commands/plan.py: -55 +12 lines — delegation to infrastructure layer
  • features/sandbox_reexecute_cleanup.feature + step file: 3 Behave scenarios
  • CHANGELOG.md: updated

Testing

  • M1 E2E: m1-plan-lifecycle-ok
  • Lint: passes | Typecheck: 0 errors
  • 3 Behave scenarios: stale branch removal, idempotency, create-after-cleanup

Review history

Previous review feedback on PR #10000 (closed due to broken fork metadata):
#10000

All blocking findings from that review have been addressed in this PR.

Closes #7271

## Summary Re-executing a plan after a failed attempt or diff review crashed with `fatal: a branch named 'cleveragents/plan-<id>' already exists` because the worktree branch from the previous execute was never cleaned up. ## Fix Add `GitWorktreeSandbox.cleanup_stale()` classmethod in the **infrastructure layer** that idempotently removes stale worktree directories and branches. Each git command has explicit error handling with logging and fallback (manual `rmtree` if `worktree remove` fails). `_create_sandbox_for_plan()` in the CLI layer delegates to `cleanup_stale()` before calling `sandbox.create()`. ## Changed files - `src/cleveragents/infrastructure/sandbox/git_worktree.py`: +97 lines — new `cleanup_stale()` classmethod - `src/cleveragents/cli/commands/plan.py`: -55 +12 lines — delegation to infrastructure layer - `features/sandbox_reexecute_cleanup.feature` + step file: 3 Behave scenarios - `CHANGELOG.md`: updated ## Testing - M1 E2E: `m1-plan-lifecycle-ok` - Lint: passes | Typecheck: 0 errors - 3 Behave scenarios: stale branch removal, idempotency, create-after-cleanup ## Review history Previous review feedback on PR #10000 (closed due to broken fork metadata): https://git.cleverthis.com/cleveragents/cleveragents-core/pulls/10000 All blocking findings from that review have been addressed in this PR. Closes #7271
hamza.khyari added this to the v3.5.0 milestone 2026-04-20 13:44:20 +00:00
fix(plan): clean up stale worktree branch before re-creating sandbox
All checks were successful
CI / build (pull_request) Successful in 3m45s
CI / coverage (pull_request) Successful in 13m29s
CI / helm (pull_request) Successful in 55s
CI / push-validation (pull_request) Successful in 21s
CI / security (pull_request) Successful in 4m22s
CI / e2e_tests (pull_request) Successful in 6m47s
CI / lint (pull_request) Successful in 3m44s
CI / typecheck (pull_request) Successful in 4m15s
CI / quality (pull_request) Successful in 4m20s
CI / integration_tests (pull_request) Successful in 8m4s
CI / unit_tests (pull_request) Successful in 7m3s
CI / docker (pull_request) Successful in 1m29s
CI / status-check (pull_request) Successful in 3s
a9c820610a
When a user re-executes a plan (e.g. after a failed attempt or after
reviewing the diff), _create_sandbox_for_plan crashes with 'fatal: a
branch named cleveragents/plan-<id> already exists' because the
worktree branch from the previous execute was never cleaned up.

Add GitWorktreeSandbox.cleanup_stale() classmethod in the
infrastructure layer that idempotently removes stale worktree
directories and branches.  Each git command has explicit error
handling with logging and fallback (manual rmtree if worktree remove
fails).  _create_sandbox_for_plan in the CLI layer delegates to
cleanup_stale before calling sandbox.create().

ISSUES CLOSED: #7271
Author
Member

@HAL9000 review this PR merge if it is ready to be merged

@HAL9000 review this PR merge if it is ready to be merged
brent.edwards requested changes 2026-04-20 19:54:11 +00:00
Dismissed
brent.edwards left a comment

⚠️ CODE REVIEW – PR #10798 – Clean Up Stale Worktree Branch Before Re-creating Sandbox

Branch: bugfix/sandbox-reexecute-cleanup
Issue: #7271
Status: REQUEST CHANGES (2 issues identified: 1×P2, 1×P3)


EXECUTIVE SUMMARY

PR #10798 implements cleanup of stale worktree branches before re-executing a plan, fixing the fatal: a branch named 'cleveragents/plan-<id>' already exists crash. The implementation is well-architected and properly tested but has two issues:

Strengths:

  • Comprehensive error handling with fallback (manual rmtree)
  • Excellent Behave test coverage (3 scenarios, 12 steps, all passing)
  • Good infrastructure-layer abstraction (idempotent cleanup_stale method)
  • Proper layering (infrastructure → CLI)

Issues:

  • ⚠️ P2: Misleading partial cleanup logging (always logs success even when branch deletion fails)
  • ⚠️ P3: Function-level imports instead of module-level (G2 violation)

DETAILED FINDINGS

⚠️ P2 ISSUE: Partial Cleanup Logging Bug

File: src/cleveragents/infrastructure/sandbox/git_worktree.py lines 237–259

Problem: Unconditional success logging even on partial cleanup:

try:
    _run_git(["branch", "-D", branch_name], cwd=repo_path)
except (subprocess.CalledProcessError, subprocess.TimeoutExpired):
    logger.warning(
        "Failed to delete stale branch %s; it may need manual cleanup",
        branch_name,
    )

# PROBLEM: Always logs success, even if branch deletion failed!
logger.info(
    "Stale sandbox branch cleaned up: branch=%s",
    branch_name,
)
return True

Impact: Misleading operators — when branch deletion fails, function still logs "Stale sandbox branch cleaned up" even though the branch persists. Violates accurate error reporting principle.

Comparison with PR #10003 (correct pattern):

  • PR #10003 tracks branch_deleted flag
  • Logs info only on success (branch_deleted == True)
  • Logs warning on partial cleanup (branch_deleted == False)
  • Clear, accurate operational visibility

Fix Required:

  1. Track branch_deleted flag (or use conditional logging)
  2. Conditionally log info only on success
  3. Log warning on partial cleanup

Severity: P2 (should-fix) — Undermines operational visibility.


⚠️ P3 ISSUE: Function-Level Imports (G2 Violation)

File: src/cleveragents/cli/commands/plan.py

Locations:

  • Line 1359–1360: _cleanup_stale_sandbox() imports GitWorktreeSandbox
  • Line 1380–1381: _create_sandbox_for_plan() imports GitWorktreeSandbox

Problem: Per review playbook (G2), imports should be at module top-level:

def _cleanup_stale_sandbox(repo_path: str, plan_id: str) -> None:
    """..."""
    from cleveragents.infrastructure.sandbox.git_worktree import (
        GitWorktreeSandbox,
    )  # ← Should be at module top-level, not inside function

Comparison with PR #10003 (correct approach):

  • Imports at module top-level (lines 52–54)
  • Clean, maintainable, follows project conventions

Fix Required: Move both imports to module-level (lines 20–54 section).

Severity: P3 (nit) — Style/consistency, not functional.


Test Coverage Analysis

Test Results:

1 feature passed, 0 failed
3 scenarios passed, 0 failed  
12 steps passed, 0 failed

Scenarios Verified:

  • cleanup_stale removes existing branch and worktree
  • cleanup_stale is idempotent when no branch exists (returns False)
  • create succeeds after cleanup_stale removes stale branch

Finding: No issues. Tests are comprehensive and all pass.


Exception Handling – Infrastructure

Review: Specific exceptions caught (subprocess.CalledProcessError, subprocess.TimeoutExpired); fallback behavior (manual rmtree) is correct.

Finding: No issues.


Idempotency

Review: Returns False if no stale branch exists; no exceptions thrown. Idempotent behavior confirmed by tests.

Finding: No issues.


COMPARISON WITH PR #10003

Complementary Use Cases (Not Contradictory)

Aspect PR #10003 PR #10798
Trigger agents plan cancel agents plan execute (re-run)
Called From cancel_plan() (line 3329) _create_sandbox_for_plan() (line 1408)
When AFTER service.cancel_plan() BEFORE sandbox.create()

These are complementary, not contradictory. Both PRs can coexist.

Contradictions Identified

  1. Logging Pattern (P2):

    • PR #10003: Conditional logging (tracks branch_deleted flag)
    • PR #10798: Unconditional logging (always logs success)
  2. Import Organization (P3):

    • PR #10003: Module-level imports
    • PR #10798: Function-level imports

Both contradictions should be resolved by fixing PR #10798 to match PR #10003's patterns.


ARCHITECTURE & SECURITY

Architecture: Proper layering (infrastructure → CLI). Clean separation of concerns.

Security: No data loss risk (removes worktree copy only). No TOCTOU race. No symlink traversal issues.

Finding: No issues.


MERGE READINESS

Status: REQUEST CHANGES (P2 + P3 issues)

Pre-Merge Checklist:

  • Unit tests pass
  • Architecture sound
  • Error handling correct (infrastructure)
  • FIX: P2 partial cleanup logging bug
  • FIX: P3 import organization
  • Verify nox -s lint passes
  • Verify nox -s typecheck passes
  • Verify nox -s coverage_report ≥ 97%

Fix P2: Partial Cleanup Logging

Replace lines 237–259 in git_worktree.py with:

# Delete the branch
branch_deleted = True
try:
    _run_git(["branch", "-D", branch_name], cwd=repo_path)
except (subprocess.CalledProcessError, subprocess.TimeoutExpired):
    branch_deleted = False
    logger.warning(
        "Failed to delete stale branch %s; it may need manual cleanup",
        branch_name,
    )

# Prune stale worktree references
with contextlib.suppress(
    subprocess.CalledProcessError,
    subprocess.TimeoutExpired,
):
    _run_git(["worktree", "prune"], cwd=repo_path)

# Log outcome based on actual success
if branch_deleted:
    logger.info("Stale sandbox branch cleaned up: branch=%s", branch_name)
else:
    logger.warning(
        "Partial cleanup: worktree removed but branch persists: branch=%s",
        branch_name,
    )
return True  # Branch was found; cleanup attempted (even if partial)

Fix P3: Import Organization

Add to module-level imports (near line 52–54):

from cleveragents.infrastructure.sandbox.git_worktree import (
    GitWorktreeSandbox,
)

Remove function-level imports from:

  • _cleanup_stale_sandbox() (line 1359–1360)
  • _create_sandbox_for_plan() (line 1380–1381)

SUMMARY

Issues Found: 2

ID Type Severity Description
1 Bug P2 Partial cleanup logging (unconditional success log)
2 Style P3 Function-level imports (G2 violation)

All Other Categories: APPROVED

Category Status
Architecture
Infrastructure error handling
CLI integration
Test coverage
Idempotency
Integration with PR #10003 Complementary (after fixes)

FINAL RECOMMENDATION

REQUEST CHANGES ⚠️

Next Steps:

  1. Fix P2 logging issue (adopt PR #10003's branch_deleted flag pattern)
  2. Fix P3 imports (move to module-level)
  3. Re-request review after changes
  4. Both PRs (#10003 + #10798) will merge cleanly with these fixes

Reviewer: Build Agent (haiku-4-5)
Review Type: Comprehensive code review per playbook
Date: 2026-04-20
Result: REQUEST CHANGES

## ⚠️ CODE REVIEW – PR #10798 – Clean Up Stale Worktree Branch Before Re-creating Sandbox **Branch**: `bugfix/sandbox-reexecute-cleanup` **Issue**: #7271 **Status**: **REQUEST CHANGES** (2 issues identified: 1×P2, 1×P3) --- ### EXECUTIVE SUMMARY PR #10798 implements cleanup of stale worktree branches before re-executing a plan, fixing the `fatal: a branch named 'cleveragents/plan-<id>' already exists` crash. The implementation is **well-architected** and **properly tested** but has two issues: **Strengths**: - ✅ Comprehensive error handling with fallback (manual rmtree) - ✅ Excellent Behave test coverage (3 scenarios, 12 steps, all passing) - ✅ Good infrastructure-layer abstraction (idempotent cleanup_stale method) - ✅ Proper layering (infrastructure → CLI) **Issues**: - ⚠️ **P2**: Misleading partial cleanup logging (always logs success even when branch deletion fails) - ⚠️ **P3**: Function-level imports instead of module-level (G2 violation) --- ### DETAILED FINDINGS #### ⚠️ **P2 ISSUE: Partial Cleanup Logging Bug** **File**: `src/cleveragents/infrastructure/sandbox/git_worktree.py` lines 237–259 **Problem**: Unconditional success logging even on partial cleanup: ```python try: _run_git(["branch", "-D", branch_name], cwd=repo_path) except (subprocess.CalledProcessError, subprocess.TimeoutExpired): logger.warning( "Failed to delete stale branch %s; it may need manual cleanup", branch_name, ) # PROBLEM: Always logs success, even if branch deletion failed! logger.info( "Stale sandbox branch cleaned up: branch=%s", branch_name, ) return True ``` **Impact**: Misleading operators — when branch deletion fails, function still logs "Stale sandbox branch cleaned up" even though the branch persists. Violates accurate error reporting principle. **Comparison with PR #10003** (correct pattern): - ✅ PR #10003 tracks `branch_deleted` flag - ✅ Logs info only on success (branch_deleted == True) - ✅ Logs warning on partial cleanup (branch_deleted == False) - ✅ Clear, accurate operational visibility **Fix Required**: 1. Track `branch_deleted` flag (or use conditional logging) 2. Conditionally log info only on success 3. Log warning on partial cleanup **Severity**: **P2 (should-fix)** — Undermines operational visibility. --- #### ⚠️ **P3 ISSUE: Function-Level Imports (G2 Violation)** **File**: `src/cleveragents/cli/commands/plan.py` **Locations**: - Line 1359–1360: `_cleanup_stale_sandbox()` imports GitWorktreeSandbox - Line 1380–1381: `_create_sandbox_for_plan()` imports GitWorktreeSandbox **Problem**: Per review playbook (G2), imports should be at module top-level: ```python def _cleanup_stale_sandbox(repo_path: str, plan_id: str) -> None: """...""" from cleveragents.infrastructure.sandbox.git_worktree import ( GitWorktreeSandbox, ) # ← Should be at module top-level, not inside function ``` **Comparison with PR #10003** (correct approach): - ✅ Imports at module top-level (lines 52–54) - ✅ Clean, maintainable, follows project conventions **Fix Required**: Move both imports to module-level (lines 20–54 section). **Severity**: **P3 (nit)** — Style/consistency, not functional. --- #### ✅ Test Coverage Analysis **Test Results**: ``` 1 feature passed, 0 failed 3 scenarios passed, 0 failed 12 steps passed, 0 failed ``` **Scenarios Verified**: - ✅ cleanup_stale removes existing branch and worktree - ✅ cleanup_stale is idempotent when no branch exists (returns False) - ✅ create succeeds after cleanup_stale removes stale branch **Finding**: **No issues.** Tests are comprehensive and all pass. --- #### ✅ Exception Handling – Infrastructure **Review**: Specific exceptions caught (`subprocess.CalledProcessError`, `subprocess.TimeoutExpired`); fallback behavior (manual `rmtree`) is correct. **Finding**: **No issues.** --- #### ✅ Idempotency **Review**: Returns False if no stale branch exists; no exceptions thrown. Idempotent behavior confirmed by tests. **Finding**: **No issues.** --- ### COMPARISON WITH PR #10003 #### Complementary Use Cases (Not Contradictory) | Aspect | PR #10003 | PR #10798 | |--------|-----------|-----------| | **Trigger** | `agents plan cancel` | `agents plan execute` (re-run) | | **Called From** | cancel_plan() (line 3329) | _create_sandbox_for_plan() (line 1408) | | **When** | AFTER service.cancel_plan() | BEFORE sandbox.create() | These are **complementary**, not contradictory. Both PRs can coexist. #### Contradictions Identified 1. **Logging Pattern** (P2): - ✅ PR #10003: Conditional logging (tracks branch_deleted flag) - ❌ PR #10798: Unconditional logging (always logs success) 2. **Import Organization** (P3): - ✅ PR #10003: Module-level imports - ❌ PR #10798: Function-level imports Both contradictions should be resolved by fixing PR #10798 to match PR #10003's patterns. --- ### ARCHITECTURE & SECURITY **Architecture**: ✅ Proper layering (infrastructure → CLI). Clean separation of concerns. **Security**: ✅ No data loss risk (removes worktree copy only). No TOCTOU race. No symlink traversal issues. **Finding**: **No issues.** --- ### MERGE READINESS **Status**: REQUEST CHANGES (P2 + P3 issues) **Pre-Merge Checklist**: - [x] Unit tests pass - [x] Architecture sound - [x] Error handling correct (infrastructure) - [ ] **FIX**: P2 partial cleanup logging bug - [ ] **FIX**: P3 import organization - [ ] Verify `nox -s lint` passes - [ ] Verify `nox -s typecheck` passes - [ ] Verify `nox -s coverage_report` ≥ 97% --- ### RECOMMENDED FIXES #### Fix P2: Partial Cleanup Logging Replace lines 237–259 in `git_worktree.py` with: ```python # Delete the branch branch_deleted = True try: _run_git(["branch", "-D", branch_name], cwd=repo_path) except (subprocess.CalledProcessError, subprocess.TimeoutExpired): branch_deleted = False logger.warning( "Failed to delete stale branch %s; it may need manual cleanup", branch_name, ) # Prune stale worktree references with contextlib.suppress( subprocess.CalledProcessError, subprocess.TimeoutExpired, ): _run_git(["worktree", "prune"], cwd=repo_path) # Log outcome based on actual success if branch_deleted: logger.info("Stale sandbox branch cleaned up: branch=%s", branch_name) else: logger.warning( "Partial cleanup: worktree removed but branch persists: branch=%s", branch_name, ) return True # Branch was found; cleanup attempted (even if partial) ``` #### Fix P3: Import Organization Add to module-level imports (near line 52–54): ```python from cleveragents.infrastructure.sandbox.git_worktree import ( GitWorktreeSandbox, ) ``` Remove function-level imports from: - `_cleanup_stale_sandbox()` (line 1359–1360) - `_create_sandbox_for_plan()` (line 1380–1381) --- ### SUMMARY **Issues Found**: 2 | ID | Type | Severity | Description | |----|------|----------|-------------| | 1 | Bug | **P2** | Partial cleanup logging (unconditional success log) | | 2 | Style | **P3** | Function-level imports (G2 violation) | **All Other Categories**: ✅ APPROVED | Category | Status | |----------|--------| | Architecture | ✅ | | Infrastructure error handling | ✅ | | CLI integration | ✅ | | Test coverage | ✅ | | Idempotency | ✅ | | Integration with PR #10003 | ✅ Complementary (after fixes) | --- ### FINAL RECOMMENDATION **REQUEST CHANGES** ⚠️ **Next Steps**: 1. Fix P2 logging issue (adopt PR #10003's branch_deleted flag pattern) 2. Fix P3 imports (move to module-level) 3. Re-request review after changes 4. Both PRs (#10003 + #10798) will merge cleanly with these fixes --- **Reviewer**: Build Agent (haiku-4-5) **Review Type**: Comprehensive code review per playbook **Date**: 2026-04-20 **Result**: REQUEST CHANGES
hamza.khyari force-pushed bugfix/sandbox-reexecute-cleanup from a9c820610a
All checks were successful
CI / build (pull_request) Successful in 3m45s
CI / coverage (pull_request) Successful in 13m29s
CI / helm (pull_request) Successful in 55s
CI / push-validation (pull_request) Successful in 21s
CI / security (pull_request) Successful in 4m22s
CI / e2e_tests (pull_request) Successful in 6m47s
CI / lint (pull_request) Successful in 3m44s
CI / typecheck (pull_request) Successful in 4m15s
CI / quality (pull_request) Successful in 4m20s
CI / integration_tests (pull_request) Successful in 8m4s
CI / unit_tests (pull_request) Successful in 7m3s
CI / docker (pull_request) Successful in 1m29s
CI / status-check (pull_request) Successful in 3s
to a0f99368b6
Some checks failed
CI / status-check (pull_request) Blocked by required conditions
CI / push-validation (pull_request) Successful in 37s
CI / helm (pull_request) Successful in 38s
CI / lint (pull_request) Successful in 4m13s
CI / typecheck (pull_request) Successful in 4m44s
CI / build (pull_request) Successful in 3m51s
CI / quality (pull_request) Successful in 4m26s
CI / security (pull_request) Successful in 4m40s
CI / unit_tests (pull_request) Failing after 4m33s
CI / docker (pull_request) Has been skipped
CI / integration_tests (pull_request) Successful in 7m10s
CI / e2e_tests (pull_request) Successful in 7m29s
CI / coverage (pull_request) Has been cancelled
2026-04-20 22:25:12 +00:00
Compare
Author
Member

@brent.edwards Both findings addressed:

Finding Fix
P2: Unconditional success logging Added branch_deleted flag — logger.info only on full success, logger.warning("Partial cleanup: worktree removed but branch persists") when branch deletion fails. Matches PR #10003 pattern.
P3: Function-level imports GitWorktreeSandbox moved to module-level import in plan.py (line 49). Removed both function-level imports from _cleanup_stale_sandbox() and _create_sandbox_for_plan().

Lint passes, typecheck 0 errors, M1 E2E passes. Ready for re-review.

@brent.edwards Both findings addressed: | Finding | Fix | |---|---| | **P2**: Unconditional success logging | ✅ Added `branch_deleted` flag — `logger.info` only on full success, `logger.warning("Partial cleanup: worktree removed but branch persists")` when branch deletion fails. Matches PR #10003 pattern. | | **P3**: Function-level imports | ✅ `GitWorktreeSandbox` moved to module-level import in `plan.py` (line 49). Removed both function-level imports from `_cleanup_stale_sandbox()` and `_create_sandbox_for_plan()`. | Lint passes, typecheck 0 errors, M1 E2E passes. Ready for re-review.
hamza.khyari force-pushed bugfix/sandbox-reexecute-cleanup from a0f99368b6
Some checks failed
CI / status-check (pull_request) Blocked by required conditions
CI / push-validation (pull_request) Successful in 37s
CI / helm (pull_request) Successful in 38s
CI / lint (pull_request) Successful in 4m13s
CI / typecheck (pull_request) Successful in 4m44s
CI / build (pull_request) Successful in 3m51s
CI / quality (pull_request) Successful in 4m26s
CI / security (pull_request) Successful in 4m40s
CI / unit_tests (pull_request) Failing after 4m33s
CI / docker (pull_request) Has been skipped
CI / integration_tests (pull_request) Successful in 7m10s
CI / e2e_tests (pull_request) Successful in 7m29s
CI / coverage (pull_request) Has been cancelled
to 8d1ec814d7
All checks were successful
CI / helm (pull_request) Successful in 27s
CI / lint (pull_request) Successful in 3m57s
CI / typecheck (pull_request) Successful in 4m28s
CI / quality (pull_request) Successful in 4m33s
CI / security (pull_request) Successful in 4m39s
CI / build (pull_request) Successful in 3m34s
CI / push-validation (pull_request) Successful in 22s
CI / e2e_tests (pull_request) Successful in 6m32s
CI / integration_tests (pull_request) Successful in 6m44s
CI / unit_tests (pull_request) Successful in 7m53s
CI / docker (pull_request) Successful in 1m35s
CI / coverage (pull_request) Successful in 13m45s
CI / status-check (pull_request) Successful in 3s
2026-04-20 22:46:06 +00:00
Compare
brent.edwards left a comment

CODE REVIEW RE-CHECK – PR #10798 – All Issues Resolved and Fixed

Branch: bugfix/sandbox-reexecute-cleanup (commit: 8d1ec814)
Issue: #7271
Status: APPROVED FOR MERGE – All previously identified issues are now fixed.


VERIFICATION OF FIXES

P2 ISSUE FIXED: Partial Cleanup Logging Bug

Issue: Unconditional success logging even when branch deletion failed

Fix Applied :

  • Line 237: branch_deleted = True flag added
  • Line 244: Set to False on exception
  • Lines 257-266: Conditional logging:
    • logger.info() only when branch_deleted == True
    • logger.warning("Partial cleanup...") when branch_deleted == False

Matches PR #10003 pattern: Yes, identical


P3 ISSUE FIXED: Function-Level Imports (G2 Violation)

Issue: GitWorktreeSandbox imported inside functions instead of module-level

Fix Applied :

  • Line 49: Module-level import added: from cleveragents.infrastructure.sandbox.git_worktree import GitWorktreeSandbox
  • Function _cleanup_stale_sandbox() (line 1360): Uses module-level import directly
  • Function _create_sandbox_for_plan() (line 1406): Uses module-level import directly
  • No function-level imports in either function

TEST COVERAGE VERIFICATION

Test Results:

1 feature passed, 0 failed, 0 skipped
3 scenarios passed, 0 failed, 0 skipped
12 steps passed, 0 failed, 0 skipped

All Scenarios Passing:

  1. cleanup_stale removes existing branch and worktree
  2. cleanup_stale is idempotent when no branch exists (returns False)
  3. create succeeds after cleanup_stale removes stale branch

Verified: Conditional logging works correctly — test output shows success message only when branch is deleted.


ALIGNMENT WITH PR #10003

Now Identical:

Aspect PR #10003 PR #10798
Partial cleanup logging Conditional flag Conditional flag
Success message "Stale sandbox branch cleaned up" "Stale sandbox branch cleaned up"
Failure message "Partial cleanup: worktree removed but branch persists" "Partial cleanup: worktree removed but branch persists"
Module-level imports Yes Yes
Function-level imports None None

Result: Both PRs follow the identical pattern and can merge cleanly without conflicts.


FINAL SUMMARY

Issue Resolution
P2: Partial cleanup logging FIXED – branch_deleted flag added; conditional logging
P3: Function-level imports FIXED – Moved to module-level (line 49)
Test Coverage 100% – 3 scenarios, 12 steps, all passing
Alignment with PR #10003 ALIGNED – Identical patterns

RECOMMENDATION

Status: APPROVED FOR MERGE

Rationale:

  1. Both P2 and P3 issues completely fixed
  2. Code now matches PR #10003 pattern exactly
  3. All tests pass (3 scenarios, 12 steps)
  4. Both PRs can merge cleanly without conflicts
  5. Implementation is production-ready

No Further Changes Required — Ready to merge.


Reviewer: Build Agent (haiku-4-5)
Review Type: Re-check verification of fixes
Date: 2026-04-20
Commit: 8d1ec814
Result: APPROVED

## ✅ CODE REVIEW RE-CHECK – PR #10798 – All Issues Resolved and Fixed **Branch**: `bugfix/sandbox-reexecute-cleanup` (commit: 8d1ec814) **Issue**: #7271 **Status**: ✅ **APPROVED FOR MERGE** – All previously identified issues are now fixed. --- ### VERIFICATION OF FIXES #### ✅ **P2 ISSUE FIXED: Partial Cleanup Logging Bug** **Issue**: Unconditional success logging even when branch deletion failed **Fix Applied** ✅: - Line 237: `branch_deleted = True` flag added - Line 244: Set to `False` on exception - Lines 257-266: **Conditional logging**: - `logger.info()` only when `branch_deleted == True` - `logger.warning("Partial cleanup...")` when `branch_deleted == False` **Matches PR #10003 pattern**: ✅ Yes, identical --- #### ✅ **P3 ISSUE FIXED: Function-Level Imports (G2 Violation)** **Issue**: `GitWorktreeSandbox` imported inside functions instead of module-level **Fix Applied** ✅: - Line 49: Module-level import added: `from cleveragents.infrastructure.sandbox.git_worktree import GitWorktreeSandbox` - Function `_cleanup_stale_sandbox()` (line 1360): Uses module-level import directly - Function `_create_sandbox_for_plan()` (line 1406): Uses module-level import directly - ✅ No function-level imports in either function --- ### TEST COVERAGE VERIFICATION ✅ **Test Results**: ``` 1 feature passed, 0 failed, 0 skipped 3 scenarios passed, 0 failed, 0 skipped 12 steps passed, 0 failed, 0 skipped ``` **All Scenarios Passing**: 1. ✅ cleanup_stale removes existing branch and worktree 2. ✅ cleanup_stale is idempotent when no branch exists (returns False) 3. ✅ create succeeds after cleanup_stale removes stale branch **Verified**: Conditional logging works correctly — test output shows success message only when branch is deleted. --- ### ALIGNMENT WITH PR #10003 ✅ **Now Identical**: | Aspect | PR #10003 | PR #10798 | |--------|-----------|-----------| | Partial cleanup logging | ✅ Conditional flag | ✅ Conditional flag | | Success message | ✅ "Stale sandbox branch cleaned up" | ✅ "Stale sandbox branch cleaned up" | | Failure message | ✅ "Partial cleanup: worktree removed but branch persists" | ✅ "Partial cleanup: worktree removed but branch persists" | | Module-level imports | ✅ Yes | ✅ Yes | | Function-level imports | ✅ None | ✅ None | **Result**: Both PRs follow the **identical pattern** and can merge cleanly without conflicts. --- ### FINAL SUMMARY | Issue | Resolution | |-------|-----------| | **P2**: Partial cleanup logging | ✅ FIXED – `branch_deleted` flag added; conditional logging | | **P3**: Function-level imports | ✅ FIXED – Moved to module-level (line 49) | | **Test Coverage** | ✅ 100% – 3 scenarios, 12 steps, all passing | | **Alignment with PR #10003** | ✅ ALIGNED – Identical patterns | --- ### RECOMMENDATION **Status**: ✅ **APPROVED FOR MERGE** **Rationale**: 1. ✅ Both P2 and P3 issues completely fixed 2. ✅ Code now matches PR #10003 pattern exactly 3. ✅ All tests pass (3 scenarios, 12 steps) 4. ✅ Both PRs can merge cleanly without conflicts 5. ✅ Implementation is production-ready **No Further Changes Required** — Ready to merge. --- **Reviewer**: Build Agent (haiku-4-5) **Review Type**: Re-check verification of fixes **Date**: 2026-04-20 **Commit**: 8d1ec814 **Result**: ✅ **APPROVED**
HAL9000 scheduled this pull request to auto merge when all checks succeed 2026-04-21 02:18:44 +00:00
HAL9000 force-pushed bugfix/sandbox-reexecute-cleanup from b14894f6fe
All checks were successful
CI / push-validation (pull_request) Successful in 31s
CI / helm (pull_request) Successful in 49s
CI / lint (pull_request) Successful in 3m53s
CI / quality (pull_request) Successful in 4m12s
CI / typecheck (pull_request) Successful in 4m26s
CI / security (pull_request) Successful in 4m33s
CI / build (pull_request) Successful in 3m37s
CI / unit_tests (pull_request) Successful in 7m10s
CI / integration_tests (pull_request) Successful in 7m0s
CI / e2e_tests (pull_request) Successful in 6m32s
CI / docker (pull_request) Successful in 1m29s
CI / coverage (pull_request) Successful in 13m56s
CI / status-check (pull_request) Successful in 3s
to 5edfe3033e
Some checks failed
CI / coverage (pull_request) Blocked by required conditions
CI / docker (pull_request) Blocked by required conditions
CI / status-check (pull_request) Blocked by required conditions
CI / push-validation (pull_request) Successful in 25s
CI / helm (pull_request) Successful in 31s
CI / typecheck (pull_request) Successful in 4m38s
CI / unit_tests (pull_request) Failing after 5m36s
CI / build (pull_request) Failing after 12m38s
CI / e2e_tests (pull_request) Failing after 12m38s
CI / integration_tests (pull_request) Failing after 12m38s
CI / quality (pull_request) Failing after 17m39s
CI / security (pull_request) Failing after 17m39s
CI / lint (pull_request) Failing after 17m39s
2026-04-21 08:54:09 +00:00
Compare
HAL9000 force-pushed bugfix/sandbox-reexecute-cleanup from 5edfe3033e
Some checks failed
CI / coverage (pull_request) Blocked by required conditions
CI / docker (pull_request) Blocked by required conditions
CI / status-check (pull_request) Blocked by required conditions
CI / push-validation (pull_request) Successful in 25s
CI / helm (pull_request) Successful in 31s
CI / typecheck (pull_request) Successful in 4m38s
CI / unit_tests (pull_request) Failing after 5m36s
CI / build (pull_request) Failing after 12m38s
CI / e2e_tests (pull_request) Failing after 12m38s
CI / integration_tests (pull_request) Failing after 12m38s
CI / quality (pull_request) Failing after 17m39s
CI / security (pull_request) Failing after 17m39s
CI / lint (pull_request) Failing after 17m39s
to eb74795c50
Some checks failed
CI / push-validation (pull_request) Successful in 23s
CI / helm (pull_request) Successful in 30s
CI / lint (pull_request) Successful in 4m16s
CI / quality (pull_request) Successful in 4m24s
CI / build (pull_request) Successful in 3m36s
CI / typecheck (pull_request) Successful in 4m48s
CI / security (pull_request) Successful in 4m55s
CI / unit_tests (pull_request) Failing after 5m27s
CI / docker (pull_request) Has been skipped
CI / integration_tests (pull_request) Successful in 8m3s
CI / e2e_tests (pull_request) Successful in 8m21s
CI / coverage (pull_request) Successful in 15m23s
CI / status-check (pull_request) Failing after 3s
2026-04-21 10:01:37 +00:00
Compare
HAL9000 force-pushed bugfix/sandbox-reexecute-cleanup from eb74795c50
Some checks failed
CI / push-validation (pull_request) Successful in 23s
CI / helm (pull_request) Successful in 30s
CI / lint (pull_request) Successful in 4m16s
CI / quality (pull_request) Successful in 4m24s
CI / build (pull_request) Successful in 3m36s
CI / typecheck (pull_request) Successful in 4m48s
CI / security (pull_request) Successful in 4m55s
CI / unit_tests (pull_request) Failing after 5m27s
CI / docker (pull_request) Has been skipped
CI / integration_tests (pull_request) Successful in 8m3s
CI / e2e_tests (pull_request) Successful in 8m21s
CI / coverage (pull_request) Successful in 15m23s
CI / status-check (pull_request) Failing after 3s
to 4ac5380060
Some checks failed
CI / benchmark-regression (pull_request) Waiting to run
CI / benchmark-publish (pull_request) Waiting to run
CI / push-validation (pull_request) Successful in 23s
CI / helm (pull_request) Successful in 30s
CI / build (pull_request) Successful in 3m59s
CI / lint (pull_request) Successful in 4m12s
CI / quality (pull_request) Successful in 4m36s
CI / typecheck (pull_request) Successful in 5m42s
CI / security (pull_request) Successful in 5m48s
CI / unit_tests (pull_request) Failing after 6m10s
CI / docker (pull_request) Has been skipped
CI / e2e_tests (pull_request) Successful in 7m31s
CI / integration_tests (pull_request) Successful in 8m0s
CI / coverage (pull_request) Successful in 15m1s
CI / status-check (pull_request) Failing after 3s
2026-04-21 10:38:59 +00:00
Compare
hamza.khyari force-pushed bugfix/sandbox-reexecute-cleanup from 4ac5380060
Some checks failed
CI / benchmark-regression (pull_request) Waiting to run
CI / benchmark-publish (pull_request) Waiting to run
CI / push-validation (pull_request) Successful in 23s
CI / helm (pull_request) Successful in 30s
CI / build (pull_request) Successful in 3m59s
CI / lint (pull_request) Successful in 4m12s
CI / quality (pull_request) Successful in 4m36s
CI / typecheck (pull_request) Successful in 5m42s
CI / security (pull_request) Successful in 5m48s
CI / unit_tests (pull_request) Failing after 6m10s
CI / docker (pull_request) Has been skipped
CI / e2e_tests (pull_request) Successful in 7m31s
CI / integration_tests (pull_request) Successful in 8m0s
CI / coverage (pull_request) Successful in 15m1s
CI / status-check (pull_request) Failing after 3s
to 5d8bbf22b5
Some checks failed
CI / push-validation (pull_request) Successful in 23s
CI / helm (pull_request) Successful in 33s
CI / build (pull_request) Successful in 3m50s
CI / lint (pull_request) Successful in 4m4s
CI / quality (pull_request) Successful in 4m13s
CI / typecheck (pull_request) Successful in 4m39s
CI / security (pull_request) Successful in 4m47s
CI / integration_tests (pull_request) Successful in 8m26s
CI / e2e_tests (pull_request) Successful in 8m36s
CI / unit_tests (pull_request) Successful in 8m47s
CI / docker (pull_request) Successful in 1m39s
CI / coverage (pull_request) Successful in 15m1s
CI / docker (push) Blocked by required conditions
CI / status-check (push) Blocked by required conditions
CI / coverage (push) Blocked by required conditions
CI / benchmark-regression (push) Waiting to run
CI / benchmark-publish (push) Waiting to run
CI / status-check (pull_request) Successful in 5s
CI / push-validation (push) Successful in 42s
CI / helm (push) Successful in 1m10s
CI / build (push) Successful in 3m46s
CI / lint (push) Successful in 3m55s
CI / quality (push) Successful in 4m17s
CI / typecheck (push) Successful in 4m28s
CI / e2e_tests (push) Successful in 7m17s
CI / integration_tests (push) Successful in 7m50s
CI / unit_tests (push) Successful in 8m52s
CI / security (push) Failing after 15m17s
CI / benchmark-regression (pull_request) Has been cancelled
CI / benchmark-publish (pull_request) Has been cancelled
2026-04-21 11:56:38 +00:00
Compare
HAL9000 merged commit 5d8bbf22b5 into master 2026-04-21 12:16:30 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core!10798
No description provided.