6.6 KiB
Checkpoint and Rollback API (v3.3.0)
CleverAgents supports checkpointing and rollback to snapshot sandbox state during plan execution and restore it later. This page documents the CLI commands and Python API for managing checkpoints.
Overview
Checkpointing introduced in v3.3.0 allows operators to:
- Snapshot sandbox state at key points during plan execution.
- Roll back to a previous snapshot to undo tool side-effects.
- Integrate with the decision-correction revert flow for targeted re-execution.
Checkpoints are immutable records stored in the checkpoint_metadata SQLite table and
backed by a CheckpointRepository. The CheckpointService is registered in the DI
container and injected into ToolRunner, SubplanExecutionService, and PlanExecutor.
CLI Reference
agents plan checkpoint list
List all checkpoints for a plan.
agents plan checkpoint list <PLAN_ID> [OPTIONS]
Options:
| Flag | Description |
|---|---|
--format, -f |
Output format: json, yaml, plain, table, rich |
Examples:
# List checkpoints for a plan
agents plan checkpoint list 01HXYZ1234567890ABCDEFGH
# JSON output for scripting
agents plan checkpoint list 01HXYZ1234567890ABCDEFGH --format json
Each checkpoint entry shows:
| Field | Description |
|---|---|
checkpoint_id |
ULID identifier |
checkpoint_type |
pre_write, post_step, or manual |
decision_id |
Optional decision this checkpoint is aligned to |
sandbox_ref |
Git commit hash or patch reference |
size_bytes |
Size of the checkpoint data |
created_at |
UTC creation timestamp |
agents plan rollback
Roll back a plan's sandbox to a previously captured checkpoint.
agents plan rollback [--yes|-y] <PLAN_ID> <CHECKPOINT_ID>
Options:
| Flag | Description |
|---|---|
--yes, -y |
Skip the interactive confirmation prompt |
Examples:
# Rollback with confirmation prompt
agents plan rollback 01HXYZ1234567890ABCDEFGH 01HABC1234567890ABCDEFGH
# Skip confirmation (for scripts/CI)
agents plan rollback --yes 01HXYZ1234567890ABCDEFGH 01HABC1234567890ABCDEFGH
JSON output envelope (when using --format json):
{
"rollback_summary": {
"plan_id": "...",
"from_checkpoint_id": "...",
"restored_files_count": 3
},
"changes_reverted": ["path/to/file1.py", "path/to/file2.py"],
"impact": {
"files_affected": 3
},
"post_rollback_state": {
"active_checkpoint": "...",
"plan_id": "..."
},
"timing": {
"elapsed_seconds": 0.042
},
"messages": ["Rollback completed successfully."]
}
Error cases:
| Error | Cause |
|---|---|
Rollback blocked: plan is already applied |
Plan has reached terminal applied state |
Rollback blocked: sandbox is missing |
Sandbox was cleaned up before rollback |
Not found: checkpoint |
Checkpoint ID does not exist |
Validation Error |
Checkpoint does not belong to the specified plan |
Checkpoint Lifecycle
Checkpoint Types
| Type | When Created |
|---|---|
pre_write |
Automatically before each write-tool execution |
post_step |
Automatically after each write-tool execution |
manual |
Via CheckpointService.create_checkpoint() directly |
Automatic Checkpoint Triggers (v3.8.0+)
The execution engine supports four automatic triggers, configurable via
core.checkpoints.auto_create_on:
| Trigger | When | Component |
|---|---|---|
on_tool_write |
Before each write-tool execution | ToolRunner |
on_tool_write_complete |
After each write-tool execution | ToolRunner |
on_subplan_spawn |
Before first subplan execution attempt | SubplanExecutionService |
on_error |
When the Execute phase fails | PlanExecutor |
Configuration:
[core.checkpoints]
auto_create_on = ["on_tool_write", "on_tool_write_complete", "on_subplan_spawn", "on_error"]
To disable all automatic checkpoints:
[core.checkpoints]
auto_create_on = []
Retention Policy
A CheckpointRetentionPolicy governs how many checkpoints a plan may keep:
| Field | Default | Range |
|---|---|---|
max_checkpoints |
50 | 1–100 |
auto_prune |
true |
— |
When auto_prune is enabled and the count exceeds max_checkpoints, the oldest
interior checkpoints are removed. The first (earliest) and most recent checkpoints
are always preserved.
Checkpoint Data Model
Each checkpoint stores:
| Field | Type | Description |
|---|---|---|
checkpoint_id |
ULID | Unique identifier |
plan_id |
ULID | The plan that owns this checkpoint |
sandbox_ref |
str | Git commit hash or patch reference |
decision_id |
ULID | None | Optional decision alignment |
checkpoint_type |
str | pre_write, post_step, or manual |
resource_id |
ULID | None | Optional resource association |
filesystem_path |
str | Relative path within the checkpoint directory |
size_bytes |
int | Size of the checkpoint data in bytes |
created_at |
datetime | UTC creation timestamp |
metadata |
dict | Audit metadata: reason, source_tool, phase, extra |
Python API
The CheckpointService is obtained from the DI container:
from cleveragents.application.container import get_container
checkpoint_service = get_container().checkpoint_service()
# Create a manual checkpoint
checkpoint = checkpoint_service.create_checkpoint(
plan_id="01HV...",
sandbox_ref="abc123",
checkpoint_type="manual",
metadata={"reason": "pre-correction snapshot", "phase": "execute"},
)
# List checkpoints for a plan
checkpoints = checkpoint_service.list_checkpoints(plan_id="01HV...")
# Roll back to a checkpoint
result = checkpoint_service.rollback_to_checkpoint(
plan_id="01HV...",
checkpoint_id="01HABC...",
)
print(f"Restored {result.restored_files_count} files")
Rollback Guards
The rollback operation enforces two guards:
- Plan is applied — Once a plan reaches the
appliedterminal state, rollback is rejected with aBusinessRuleViolation. - Sandbox is missing — If the sandbox has been cleaned up, rollback is rejected because there is nothing to restore.
See Also
docs/reference/checkpointing.md— Full checkpointing domain model referencedocs/api/plan-corrections.md— Plan correction modes (revert uses checkpoints)- ADR-015: Sandbox & Checkpoint
- ADR-035: Decision Tree Rollback & Replay