Files
cleveragents-core/docs/api/checkpoints.md
T

6.6 KiB
Raw Blame History

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 1100
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:

  1. Plan is applied — Once a plan reaches the applied terminal state, rollback is rejected with a BusinessRuleViolation.
  2. Sandbox is missing — If the sandbox has been cleaned up, rollback is rejected because there is nothing to restore.

See Also