Skip to content

Checkpoints: what they capture and where they live

A checkpoint is a snapshot of your workspace source. env.checkpoint() returns an ID, env.restore(id) puts the files back. Undo in the REPL, the transaction wrapper, and the tree-search strategies all sit on top of it.

The important word is source. A checkpoint deliberately does not contain your virtualenv, your node_modules, your build output, or your .git directory.

It used not to. LocalEnvironment.checkpoint() copied the entire working directory, so on a real project a single checkpoint reached 2.0 GB — containing a .venv, 759 MB of site/node_modules, and a duplicate of an unrelated output directory. Nothing surfaced it; the directory was also created on every setup(), so deleting it just brought it back.

Measured on this repository’s checkout (2026-07-28), the same checkpoint is now 2,299.1 MB → 186.6 MB — 91.9% smaller, 22,503 files instead of 139,450, and 7.3 seconds instead of 66. Your own numbers depend on what is vendored in your tree; the shape does not.

The excluded set is NOT_SOURCE_DIRS in chimera/config/ignore.py: version control internals, virtualenvs and installed packages, node_modules, tool caches, editor state, and build output. It is the same list list_files, repo_map, and definition lookup use to decide what is not worth showing you, so a directory a tool hides from the model is a directory a checkpoint does not copy.

Exclusion applies at every depth. A nested site/node_modules is skipped exactly like a top-level one — that nesting was the single largest component of the 2.0 GB tree.

Restore does not delete what it did not capture

Section titled “Restore does not delete what it did not capture”

This is the half that matters in practice. restore() clears the workspace before copying files back, but it skips the same directories the checkpoint skipped:

env.write_file("app.py", "v1")
cp = env.checkpoint() # .venv is not copied
env.write_file("app.py", "v2")
env.restore(cp) # app.py is back at v1; .venv is untouched

Your virtualenv, your node_modules, your .git history, and your project’s .chimera state survive a restore. A checkpoint that excluded them and a restore that deleted them would be strictly worse than the bug being fixed.

<workdir>/.chimera/checkpoints/<id>/

That is the project-checkpoints store in the path registry (Where Chimera keeps your data), so chimera doctor can account for it and lifecycle tooling can reason about it. The directory is created the first time something checkpoints — not on every setup().

They lived in <workdir>/.chimera_checkpoints, a sibling of .chimera rather than a child. Those trees are:

  • still restorablerestore() looks in the registry store first, then the legacy directory, so an ID from an old session still resolves;
  • never written to again — new checkpoints only go to the registry store;
  • never deleted or pruned — retention does not reach them, by construction.

New IDs are allocated above the highest ID in both locations, so one ID can never mean two different snapshots.

If you want the disk space back, move the directory yourself:

Terminal window
mv .chimera_checkpoints ~/archive/checkpoints-$(date +%F)

Nothing in Chimera will do that for you.

Retention is off by default: with no configuration, every checkpoint is kept forever. To bound it, add one line to any config file in the chain (~/.chimera/config.toml, or <project>/.chimera/config.toml):

[storage.checkpoints]
retain = 5

Now checkpoint() drops the oldest beyond the newest five, immediately after writing. The checkpoint just written is never a candidate, and the legacy directory is never touched. Remove the line and nothing is ever deleted again.

Past 256 MB a checkpoint emits a LargeCheckpointWarning naming the path and the size. It is not a limit — the checkpoint is written either way — it is the signal that was missing for four months. Because vendored and build directories are already excluded, a warning now means real workspace content, which is usually worth looking at.

To raise or lower it in code:

import chimera.env.local as local
local.CHECKPOINT_SIZE_WARN_BYTES = 1024 * 1024 * 1024 # 1 GB

To silence it without changing the threshold:

import warnings
from chimera.env.local import LargeCheckpointWarning
warnings.filterwarnings("ignore", category=LargeCheckpointWarning)

It has its own category so silencing it silences nothing else.

GitEnvironment checkpoints with real commits rather than file copies, which sidesteps the size question entirely — .gitignore already says what is not source:

from chimera.env.git_env import GitEnvironment
env = GitEnvironment(workdir="/path/to/project")
env.setup()
sha = env.checkpoint() # a commit
env.restore(sha) # git checkout

Use it when the workspace is a git repository and you want checkpoints you can inspect with git log.

  • A checkpoint is not a backup. It lives inside the workspace it snapshots; losing the directory loses both.
  • Excluded directories are not versioned at all. If a run’s result depends on the exact contents of node_modules, a checkpoint will not reproduce it — pin your lockfile instead.
  • Nothing prunes without configuration. If checkpoints are accumulating and you did not set retain, they will keep accumulating.