Skip to content

Anthropic built Scion for itself. Carbon Forge is yours →

Carbon Forge
Menu

Guide

Roll a Carbon Forge workspace back to a cut

Say an agent rewrote forty pages overnight and you want yesterday back. In Carbon Forge that is one call to a cut, and it removes nothing: the restore lands as a new changeset, so the night's work stays in the history beside the undo.

Also in: Español, Português, 日本語, Deutsch, Français, 한국어, 简体中文, Italiano, हिन्दी

Disclosure: we build Carbon Forge at 100monkeys.ai, so read this as a maker's account. This guide was drafted by one of our AI agents from the public docs, chiefly the Snapshots catalog page and Working in lanes, and reviewed by the company. Tool names, arguments and quoted sentences are the docs' own; the docs give no worked JSON for these calls, so none is shown. Where the docs leave a question open, the last section says so.

What a snapshot and a cut are

A snapshot records every page's, atom's, code tree's and library entry's current revision, and every open lane's live patches, "as one sealed manifest of ids and hashes chained to the previous snapshot." It holds "ids and hashes only, never a body or a blob's bytes", so it costs little to take. A cut is a name for one snapshot, and "it never moves." Snapshots and cuts are append-only: "the database refuses to change or remove either while the workspace exists."

Step 1. Cut the state you may want back

Before a large or risky change, call snapshots.cut with a name. A name is 1 to 128 letters, digits, dots, hyphens and underscores, starting with a letter or digit; the docs' examples are stable, v0.9 and release-2026.10.16. Reusing a name is refused, because a cut never moves: the refusal says to name the new state with a new cut. Cutting needs the editor role.

Step 2. Find the cut later

cuts.list answers the workspace's cuts, newest first, each with the snapshot it names. snapshots.get with cut answers one snapshot: its digest, seal, predecessor, counts and the open lanes it recorded. Both are reads for the viewer role.

Step 3. Read what changed since the cut

cuts.notes lists every changeset landed after one bound up to another, in landing order, grouped by the first word of its intent. Its to must be a cut or a snapshot id, so to compare the cut with the workspace as it is now, first call snapshots.cut with no name, then pass your cut as from and the new snapshot's id as to. Add path_glob to keep only changesets that touched the paths you care about. Each changeset names its intent, its actor, the lane it landed from and the paths it touched, which is usually enough to see whose work you are about to undo.

Step 4. Look at one entity as the cut holds it

snapshots.materialize with cut answers a page of the cut's manifest, each entry with these fields:

kind, entity_id, revision_id, content_hash, seal_hash, path, title

Add entity_id and it answers that entity at the revision the cut names: a page's body and metadata, an atom's body, a tree's entries, a library entry's hash. "The same snapshot answers the same every time." An entry whose revision has since been purged answers purged and carries no content.

Step 5. Check who may revert

snapshots.revert needs the admin role, and of the token presets it is in full only, so an agent holding an SCM agent or SCM release token cannot call it. On a workspace whose trunk is protected, a revert that would write a code tree or a library entry, or a page or atom where pages are protected too, is refused before anything is written: workspace <slug> protects its trunk: the trunk lands by lanes.land only; write on a lane.

Step 6. Revert to the cut

Call snapshots.revert with cut and intent, the changeset's message, 1 to 4,096 characters. "Revert is forward only: nothing is removed or rewritten." Every entity whose content differs from the cut's gets one new revision holding the cut's content, all in one sealed changeset. A restored page or atom revision carries the comment Restored from cut <cut> (R#<revision>). Where the cut recorded paths and titles, a renamed page goes back to its old path and title, and the path it leaves keeps redirecting to it. Then a new snapshot is cut, marked with the cut it was reverted from.

Step 7. Read the answer

The answer is the new snapshot with these fields:

snapshot, cut, changeset_id, restored, unchanged, extraneous, collisions

Each restored row is:

kind, entity_id, from_revision_id, new_revision_id

unchanged is a count. collisions lists entities whose old path another live page or atom now holds: there "the body and metadata alone are restored, and nothing moves." Two refusals write nothing at all: a cut naming a revision that was purged, or an entity now in the trash, which the refusal tells you to restore first; and a cut the workspace already matches, answered with Every entity already holds what cut <cut> names; nothing changes.

Step 8. Deal with what the revert leaves alone

"Entities created after the cut are reported as extraneous and left as they are." A page the overnight agent created is still there after the revert; decide for each one whether it stays. Because the revert is a changeset like any other, the night's work and its undo both stay readable in the history, and cuts.notes run across the revert shows both. For one landing rather than a whole workspace, changesets.revert undoes a single changeset, and it takes lane, so on a protected trunk it can be stored on a lane and landed there.

To name releases with cuts and publish them, read our guide Cut a release in Carbon Forge and push it to GitHub.

What the docs leave unanswered

Undo a bad night in one changeset.