UAT: BuiltInSandboxStrategyAdapter.restore_checkpoint does not delete files added after the checkpoint — sandbox state is not fully restored #2953

Open
opened 2026-04-05 02:55:15 +00:00 by freemo · 1 comment
Owner

Metadata

  • Branch: fix/sandbox-restore-checkpoint-delete-post-checkpoint-files
  • Commit Message: fix(sandbox): restore_checkpoint deletes files added after checkpoint to fully restore sandbox state
  • Milestone: v3.3.0
  • Parent Epic: #362

Description

The BuiltInSandboxStrategyAdapter.restore_checkpoint method (in src/cleveragents/infrastructure/sandbox/strategy_adapter.py) restores file content from the checkpoint snapshot but does NOT delete files that were added to the sandbox after the checkpoint was taken. This means after a restore, the sandbox contains both the restored files AND any new files created after the checkpoint, leaving the sandbox in an inconsistent state.

Expected Behavior (from spec)

A checkpoint restore should return the sandbox to exactly the state it was in when the checkpoint was created. Files added after the checkpoint must be removed during restore.

Actual Behavior

In src/cleveragents/infrastructure/sandbox/strategy_adapter.py lines 206–235:

def restore_checkpoint(self, ref: SandboxRef, checkpoint_id: str) -> None:
    key = f"{ref.sandbox_id}:{checkpoint_id}"
    snapshot = self._checkpoints[key]

    sandbox = self._sandboxes[ref.sandbox_id]
    ctx = sandbox.context
    if ctx is not None and os.path.isdir(ctx.sandbox_path):
        # Restore files from snapshot
        for rel_path, content in snapshot.items():
            full = os.path.join(ctx.sandbox_path, rel_path)
            parent = os.path.dirname(full)
            if parent:
                os.makedirs(parent, exist_ok=True)
            with open(full, "wb") as fh:
                fh.write(content)

The method only writes snapshot files back but never removes files that exist in the sandbox but are NOT in the snapshot. If a file was created after the checkpoint, it will remain in the sandbox after restore.

Compare with CheckpointManager.rollback_to (in src/cleveragents/infrastructure/sandbox/checkpoint.py lines 209–225) which correctly clears the sandbox directory before restoring.

Steps to Reproduce

  1. Create a BuiltInSandboxStrategyAdapter with strategy_name="copy_on_write"
  2. Create a sandbox and take a checkpoint
  3. Add a new file to the sandbox after the checkpoint
  4. Call restore_checkpoint to restore to the checkpoint
  5. Observe that the new file still exists in the sandbox (it should have been deleted)

Code Location

  • src/cleveragents/infrastructure/sandbox/strategy_adapter.py lines 206–235 (restore_checkpoint method)

Subtasks

  • Audit restore_checkpoint in BuiltInSandboxStrategyAdapter and identify all files present in the sandbox directory that are absent from the checkpoint snapshot
  • Implement deletion of post-checkpoint files during restore (mirror the approach used in CheckpointManager.rollback_to)
  • Ensure nested/subdirectory files added after the checkpoint are also removed
  • Add/update Behave unit tests covering the scenario: file added after checkpoint is absent after restore
  • Verify no regression in existing checkpoint restore tests
  • Run nox (all sessions) and confirm all quality gates pass

Definition of Done

  • restore_checkpoint removes all files from the sandbox that were not present at checkpoint time
  • Sandbox state after restore is byte-for-byte identical to the state at checkpoint creation
  • Behave unit tests cover the post-checkpoint file deletion scenario
  • No existing tests are broken
  • All nox stages pass
  • Coverage >= 97%

Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: ca-new-issue-creator

## Metadata - **Branch**: `fix/sandbox-restore-checkpoint-delete-post-checkpoint-files` - **Commit Message**: `fix(sandbox): restore_checkpoint deletes files added after checkpoint to fully restore sandbox state` - **Milestone**: v3.3.0 - **Parent Epic**: #362 ## Description The `BuiltInSandboxStrategyAdapter.restore_checkpoint` method (in `src/cleveragents/infrastructure/sandbox/strategy_adapter.py`) restores file content from the checkpoint snapshot but does **NOT** delete files that were added to the sandbox **after** the checkpoint was taken. This means after a restore, the sandbox contains both the restored files AND any new files created after the checkpoint, leaving the sandbox in an inconsistent state. ### Expected Behavior (from spec) A checkpoint restore should return the sandbox to **exactly** the state it was in when the checkpoint was created. Files added after the checkpoint must be removed during restore. ### Actual Behavior In `src/cleveragents/infrastructure/sandbox/strategy_adapter.py` lines 206–235: ```python def restore_checkpoint(self, ref: SandboxRef, checkpoint_id: str) -> None: key = f"{ref.sandbox_id}:{checkpoint_id}" snapshot = self._checkpoints[key] sandbox = self._sandboxes[ref.sandbox_id] ctx = sandbox.context if ctx is not None and os.path.isdir(ctx.sandbox_path): # Restore files from snapshot for rel_path, content in snapshot.items(): full = os.path.join(ctx.sandbox_path, rel_path) parent = os.path.dirname(full) if parent: os.makedirs(parent, exist_ok=True) with open(full, "wb") as fh: fh.write(content) ``` The method only writes snapshot files back but **never removes** files that exist in the sandbox but are NOT in the snapshot. If a file was created after the checkpoint, it will remain in the sandbox after restore. Compare with `CheckpointManager.rollback_to` (in `src/cleveragents/infrastructure/sandbox/checkpoint.py` lines 209–225) which correctly clears the sandbox directory before restoring. ### Steps to Reproduce 1. Create a `BuiltInSandboxStrategyAdapter` with `strategy_name="copy_on_write"` 2. Create a sandbox and take a checkpoint 3. Add a new file to the sandbox after the checkpoint 4. Call `restore_checkpoint` to restore to the checkpoint 5. Observe that the new file still exists in the sandbox (it should have been deleted) ### Code Location - `src/cleveragents/infrastructure/sandbox/strategy_adapter.py` lines 206–235 (`restore_checkpoint` method) ## Subtasks - [ ] Audit `restore_checkpoint` in `BuiltInSandboxStrategyAdapter` and identify all files present in the sandbox directory that are absent from the checkpoint snapshot - [ ] Implement deletion of post-checkpoint files during restore (mirror the approach used in `CheckpointManager.rollback_to`) - [ ] Ensure nested/subdirectory files added after the checkpoint are also removed - [ ] Add/update Behave unit tests covering the scenario: file added after checkpoint is absent after restore - [ ] Verify no regression in existing checkpoint restore tests - [ ] Run `nox` (all sessions) and confirm all quality gates pass ## Definition of Done - [ ] `restore_checkpoint` removes all files from the sandbox that were not present at checkpoint time - [ ] Sandbox state after restore is byte-for-byte identical to the state at checkpoint creation - [ ] Behave unit tests cover the post-checkpoint file deletion scenario - [ ] No existing tests are broken - [ ] All nox stages pass - [ ] Coverage >= 97% --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-new-issue-creator
freemo added this to the v3.3.0 milestone 2026-04-05 02:55:20 +00:00
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • Priority: Confirmed
  • MoSCoW: Should Have

Valid finding verified during batch triage.


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: ca-project-owner

Issue triaged by project owner: - **State**: Verified - **Priority**: Confirmed - **MoSCoW**: Should Have Valid finding verified during batch triage. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Blocks
#362 Epic: Security & Safety Hardening
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#2953
No description provided.