How rollback works on OBTO
An AI agent that can write to a deployed application must be able to un-write. Not by remembering a backup, not by asking the model nicely, but with a control a person can click and a receipt a person can read. This post is the exact contract, including the parts that are not finished, with a real receipt from a staging app at the end.
Every agent change leaves a restore point
When the OBTO agent in DevZone changes an artifact — a page, a frontend module, a stylesheet, an API route, a server script — the platform captures the full previous source before the write lands, along with who asked, which tool wrote, when, and how many lines moved. That capture is a restore point. It is per artifact, it stores the whole file (up to 1.5 MB; larger files record that the change happened but store no source, and say so), and the newest 200 per app are kept.
You see them in DevZone under Versions: every point with a then→now diff against the artifact’s current source, and a name you can give the ones that matter.
Restore is a forward write, never a delete
Restoring a point does not rewind history. It writes the stored previous source back as a new change, and before it does, it records a counter-point holding the state it is about to overwrite. If that counter-point cannot be written, nothing is written. So a restore can itself be undone, and the history never loses a state it once had.
API routes are restored through the same code path the platform uses for any route save, so the handler is re-registered and the change reaches every server, not just the one you talked to.
One agent turn is one change set
A single request to the agent usually touches more than one file. Restoring them one by one is how partial states happen. So the Versions panel groups the restore points of one agent turn into a change set, and the set is the unit you inspect, name, mark as your release, and restore.
Restore all works like this:
- For every artifact in the set, pick its oldest point — the state from before the turn began.
- Pre-flight all of them before the first write: the previous source exists, the live artifact still exists, a route is unambiguous, the route-save path is available. If any artifact fails, nothing is written and the receipt lists why.
- Write them one by one, each behind its own counter-point. Artifacts that already match are skipped and reported as such.
- Store a set receipt: which points were restored, which counter-points hold the pre-restore state, and which set this one undoes.
A real receipt
Captured on 5 September 2026 on a synthetic staging app (a made-up quote-approval tool, not a customer). The agent changed a page and a stylesheet in one turn; a person clicked Restore all. Identifiers are as stored.
{
"setId": "rs_mtonty29_yfy2jzuj",
"kind": "restore",
"restoredFromSet": "cs_rp_mtonnx55_h9rtxk4o",
"items": [
{ "name": "index", "collection": "pltf_page",
"pointId": "rp_mtonnx55_h9rtxk4o", "counterPointId": "rp_mtonty2a_xwha94m5", "chars": 514 },
{ "name": "App", "collection": "pltf_stylesheet",
"pointId": "rp_mtonnx5g_ci2jpi4p", "counterPointId": "rp_mtonty6f_ddrc2lln", "chars": 28417 }
],
"created_by": "rvaid", "created_on": "2026-09-05T17:31:54.724Z"
}
Then the same Restore all was clicked a second time. The answer was “Every artifact already matched the state before this set — nothing was written.” That check is a strict byte comparison of the live source against the stored one, so it doubles as the proof that both files are back to exactly what they were.
What it is not (yet)
- Not a transaction. Pre-flighted, sequential, receipted — see above.
- Captured for the DevZone agent. Today restore points are recorded when the OBTO agent in DevZone writes. A write from your own MCP client (Claude Code, Codex, Cursor) returns the previous source’s hash in its receipt and can refuse a stale write by passing the hash it last saw — but it is not yet stored as a restore point. Capturing those writes is the next step.
- No environments. “Mark as release” names the set you consider your release; it does not promote to a separate stage.
- Grouping is by conversation turn and time until every capture carries the run id. Two very slow approvals inside one turn can split it into two sets; the artifacts stay individually restorable either way.
Try it on your own app
Open your app in DevZone, ask the agent for a change, then open the app menu → Versions… → Change sets. Expand the set, read the diff, click Restore all, and read the receipt. If the agent’s change was fine, click nothing — the point is that you could.