> ## Documentation Index
> Fetch the complete documentation index at: https://docs.seriora.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Checkpoints and undo

> How much of seri's work is reversible, and the one case where it is not.

seri records your worktree into a shadow git repository as it works. The shadow history never
touches your branch, your index or your commit history, so undoing seri's work is not a git
operation you have to reason about.

## What is snapshotted, and when

| Tool                 | Snapshot                                                                    |
| -------------------- | --------------------------------------------------------------------------- |
| `write_file`         | always, before the call                                                     |
| `bash`, `powershell` | when the command looks destructive, or it is the first such call of the run |
| `edit`               | never                                                                       |

`edit` is a pure string transform. It takes no path and never touches disk, so a snapshot before
it would only record the tree that was already there. The model has to follow it with
`write_file`, which does snapshot.

<Warning>
  **Shell coverage is a heuristic, not a guarantee.** A `bash` or `powershell` call snapshots only
  when its command matches a curated destructive-command list, `rm`, `mv`, `unlink`, `rmdir`,
  `git reset`, `Remove-Item`, output redirects and similar. A command the list does not recognise,
  `python generate.py` or `make`, runs without a snapshot, and whatever it changed is folded into
  the next one instead.

  The practical effect: `/undo` steps around such a change rather than back to the instant before
  it. Files that command created are also absent from the write ledger, and the removal pass only
  deletes ledger-verified paths, so they are left in place rather than cleaned up.

  The list leans deliberately broad, because a false positive costs one extra git call and a false
  negative costs undo coverage. If you are about to run something destructive through an unusual
  wrapper, take your own commit first.
</Warning>

The first mutating call of each run always snapshots regardless of the command, because a
resumed session's previous tree came from an earlier process and cannot be trusted to match
what is on disk now.

## Walking it back

| Command          | Acts on          | Does                                                       |
| ---------------- | ---------------- | ---------------------------------------------------------- |
| `/undo [n]`      | your files       | step the worktree back `n` file states                     |
| `/restore <sha>` | your files       | put back a specific checkpoint, whichever it was           |
| `/rewind [n]`    | the conversation | drop the last `n` turns, leaving every file byte-identical |

`/rewind` leaving files alone is structural rather than a promise. It reads the log and has no
path to the shadow repository at all.

## `n` does not mean the same thing to both

This trips people up, so it is worth being exact.

| Command     | Counts                                                | Three writes in one turn |
| ----------- | ----------------------------------------------------- | ------------------------ |
| `/undo n`   | distinct **file states**, newest first                | three steps              |
| `/rewind n` | distinct **points in the conversation**, newest first | one step                 |

A call that changed nothing is not an `/undo` step, because it produced no new file state.
`/undo` also skips the states it created itself when undoing, so `/undo 2` means two steps back
through your history rather than undoing the undo.

## What `/rewind` refuses

Two things make every anchor recorded before them meaningless, and `/rewind` will not step across
either.

* **Compaction**, which splices the message array.
* **A previous rewind**, which truncates it, after which later messages reuse the freed positions.

A stale anchor would still land, on a different message, which is worse than falling off the end.
Refusing is the honest answer, and seri says which of the two it hit.

## Subagents are covered

A dispatch that includes any agent able to change the filesystem takes **one parent-anchored
snapshot before any child runs.** That is `code`, and also `test`, which holds `bash` and
`powershell`.

One snapshot rather than one per child is deliberate. A per-child snapshot would append a
child-derived anchor to the parent session's rewind log, which would corrupt `/rewind`. So
`/undo` steps over a whole dispatch as one unit rather than child by child.

Each child's writes are still recorded individually in the write ledger, so a later `/undo` can
prove a file it created is safe to delete.

## Retention

The checkpoint store keeps the 20 most recently touched sessions per project.

A session's conversation stays in the database indefinitely, and `/clear` leaves it there,
resumable with `--resume`. Its checkpoint history is the part that can be pruned, so clearing
repeatedly in one long-lived process can eventually retire an earlier session's undo history
while its conversation remains.
