Skip to main content
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

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.
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.
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

/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. 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.