Skip to content

Anthropic built Scion for itself. Carbon Forge is yours →

Carbon Forge
Menu

指南

把 Carbon Forge 工作区回退到一个 cut

假设一个智能体一夜之间改写了四十个页面,而你想要回昨天的状态。在 Carbon Forge 中这只是对一个 cut 的一次调用,而且它不删除任何东西:恢复作为一个新的 changeset 落地,所以夜里的工作和撤销并排留在历史中。

其他语言: English, Español, Português, 日本語, Deutsch, Français, 한국어, Italiano, हिन्दी · 全部中文指南

声明:Carbon Forge 由 100monkeys.ai 开发,因此请把这篇指南当作开发方的说明来读。它由我们的一个 AI 智能体根据公开文档(英文)起草,主要是 Snapshots 目录页和 Working in lanes,并经公司审阅;这个简体中文版是英文原版指南的译文。工具名、参数和引文都是文档自己的,引文保留英文原文,译文附在旁边;文档没有为这些调用给出完整的 JSON 示例,所以这里也不展示。文档没有回答的问题,最后一节会说明。

snapshot 和 cut 是什么

snapshot 记录每个页面、atom、代码树和库条目的当前修订,以及每条打开的 lane 的当前补丁,"as one sealed manifest of ids and hashes chained to the previous snapshot."(作为一份由 id 和哈希组成、与上一个 snapshot 链接起来的封存清单。)它只保存 "ids and hashes only, never a body or a blob's bytes"(只有 id 和哈希,从不保存正文或 blob 的字节),所以代价很小。cut 是某一个 snapshot 的名字,而且 "it never moves."(它永不移动。)snapshot 和 cut 只能追加:"the database refuses to change or remove either while the workspace exists."(只要工作区存在,数据库就拒绝修改或删除二者。)

切出你可能想要回来的状态

在一次大的或有风险的改动之前,带上 name 调用 snapshots.cut。名称是 1 到 128 个字母、数字、点、连字符和下划线,以字母或数字开头;文档的例子是 stable、v0.9 和 release-2026.10.16。重复使用名称会被拒绝,因为 cut 永不移动:拒绝信息会让你用一个新的 cut 为新状态命名。切出 cut 需要 editor 角色。

之后找到这个 cut

cuts.list 按从新到旧返回工作区的 cut,每个都带有它命名的 snapshot。带 cut 调用 snapshots.get 返回一个 snapshot:它的摘要、封印、前驱、计数,以及它记录的打开的 lane。两者都是 viewer 角色可用的读取。

阅读 cut 之后改了什么

cuts.notes 按落地顺序列出从一个边界之后到另一个边界之间落地的每个 changeset,按 intent 的第一个词分组。它的 to 必须是一个 cut 或 snapshot id,所以要把 cut 和工作区的现状比较,先不带名称调用 snapshots.cut,再把你的 cut 作为 from、新 snapshot 的 id 作为 to 传入。加上 path_glob 可以只保留触及你关心的路径的 changeset。每个 changeset 都写明它的 intent、执行者、落地来源的 lane 和触及的路径,通常足以看出你要撤销的是谁的工作。

查看 cut 中保存的某个实体

带 cut 调用 snapshots.materialize 会返回 cut 清单的一页,每个条目有这些字段:

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

加上 entity_id,它会返回该实体在 cut 所指修订时的样子:页面的正文和元数据、atom 的正文、树的条目、库条目的哈希。"The same snapshot answers the same every time."(同一个 snapshot 每次都给出同样的回答。)如果条目的修订之后被清除了,会返回 purged,不带任何内容。

确认谁可以回退

snapshots.revert 需要 admin 角色,在令牌预设中只有 full 包含它,所以持有 SCM agent 或 SCM release 令牌的智能体无法调用它。在 trunk 受保护的工作区,如果回退会写入代码树或库条目,或者在页面也受保护时写入页面或 atom,它会在写入任何东西之前被拒绝:workspace <slug> protects its trunk: the trunk lands by lanes.land only; write on a lane。

回退到这个 cut

带 cut 和 intent(changeset 的消息,1 到 4,096 个字符)调用 snapshots.revert。"Revert is forward only: nothing is removed or rewritten."(回退只向前:不删除也不改写任何东西。)内容与 cut 不同的每个实体都会得到一个新修订,内容为 cut 中的内容,全部在一个封存的 changeset 中。恢复的页面或 atom 修订带有注释 Restored from cut <cut> (R#<revision>)。在 cut 记录了路径和标题的地方,改过名的页面会回到旧的路径和标题,它离开的路径继续重定向到它。然后会切出一个新的 snapshot,并标明它是从哪个 cut 回退而来。

读懂回答

回答是新的 snapshot,带有这些字段:

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

每一行 restored 是:

kind, entity_id, from_revision_id, new_revision_id

unchanged 是一个计数。collisions 列出旧路径如今被另一个现存页面或 atom 占用的实体:在那里 "the body and metadata alone are restored, and nothing moves."(只恢复正文和元数据,什么都不移动。)有两种拒绝完全不写入:cut 指向一个已被清除的修订,或者一个实体现在在回收站里,拒绝信息会让你先恢复它;以及工作区已经与 cut 一致,回答是 Every entity already holds what cut <cut> names; nothing changes.

处理回退不会动的东西

"Entities created after the cut are reported as extraneous and left as they are."(cut 之后创建的实体会被报告为 extraneous,保持原样。)夜里那个智能体创建的页面在回退后依然存在;逐个决定它们是否保留。因为回退和其他 changeset 一样也是一个 changeset,夜里的工作和对它的撤销都会留在历史中可读,跨过回退运行 cuts.notes 能看到两者。如果只想撤销一次落地而不是整个工作区,changesets.revert 撤销单个 changeset,而且它接受 lane,所以在受保护的 trunk 上可以存到一条 lane 上再从那里落地。

想用 cut 为版本命名并发布,请阅读我们的指南 在 Carbon Forge 中切出一个版本并推送到 GitHub。

文档没有回答的问题

一个 changeset 撤销糟糕的一夜。