# Undo is a layer, not a feature

> Every agent framework will eventually add a rollback helper. That is not the same as an undo layer, and the difference shows up the first time a single reasoning turn touches four systems.

2026-08-20. 7 min. Source: https://www.voidagent.tech/blog/undo-is-a-layer

The saga pattern is forty years old. Compensating transactions are standard practice in distributed systems. So why does an agent that issues a refund, updates a CRM record and sends an email leave you with a manual cleanup ticket?

Because the compensation logic lives inside whichever framework happened to make the call. Each framework owns its own retry semantics, its own error taxonomy, and its own idea of what a rollback means. None of them own the boundary where the write actually leaves your perimeter.

<a id="undo-is-a-layer-the-boundary-is-the-only-honest-place-to-stand"></a>
## The boundary is the only honest place to stand

A tool call is the moment intent becomes effect. Before it, everything is reversible because nothing has happened. After it, reversibility is a property of the target system, not of your code. That asymmetry is why undo has to sit at the boundary and not in the agent loop.

```
agent -> interceptor -> preflight -> policy -> tool
                          |                       |
                     blast radius            before snapshot
                          |                       |
                    class + budget  ->  compensation plan -> ledger
```

Once you stand at the boundary, three things become possible that are not possible from inside a framework: you can classify reversibility before the call, you can capture a before snapshot that the framework never sees, and you can replay in the order that actually matters, which is last in, first out.

<a id="undo-is-a-layer-what-a-layer-buys-you-that-a-helper-does-not"></a>
## What a layer buys you that a helper does not

- One record for every system, instead of one per framework.
- A veto that happens before the write, not an exception after it.
- Replay ordering that respects causality across tools.
- A budget that means something, because it counts every irreversible call, not the ones one framework knows about.

The uncomfortable part is that a layer cannot promise everything is undoable. It can only promise you know which class you are in before the agent acts. In practice that turns out to be the more useful promise.

---

This document is the markdown form of https://www.voidagent.tech/blog/undo-is-a-layer, published for agents that read
text rather than a rendered page. It is generated from the same data the page
renders, so the two cannot disagree. Tag: `architecture`.

