Repository navigation
feat(workspace): add transactional checkpoints, rewind, and fork - #111
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
摘要
workspace-checkpoint.v1,将精确 Workspace/root identity、base commit、branch、原始 Git index、稳定 manifest、内容 SHA-256、触发 receipt、attempt、capability generation 与恢复等级绑定为不可变检查点。index.lock,遇到外部修改、root/commit/branch/case/link/index 漂移时 fail closed。Closes #101.
协议、恢复等级与内容存储
workspace-checkpoint.v1以 Run/Workspace/root fingerprint 为身份边界,并保存捕获时的 Git base/branch、原始 index presence + digest + bytes、排序 manifest、内容 hash、文件模式、大小、换行类型、触发来源和 recovery reasons。complete:边界内所有已知变化都有可恢复字节与完整归因。partial:Workspace 内已知状态已记录,但存在明确排除或归因不完整;没有可移植 filesystem watcher 时,命令批次固定为 partial,不夸大恢复能力。unavailable:root/Git identity、大小写、index、link 或必要内容不能安全物化,Restore/Fork 直接拒绝。manifest 明确区分
stored、missing、excluded_ignored、excluded_generated、excluded_large、excluded_sensitive、excluded_link、excluded_special与unreadable。限额内文本和二进制均按原始字节保存;LF、CRLF、mixed 与 no-newline 可逐字节恢复。ignored、生成物、超限、疑似敏感文件、symlink/junction/reparse、特殊或根目录外内容绝不被静默描述为可恢复。内容存储按 SHA-256 去重,schema v117 在同一 SQLite 事务内提交 blob、entry、seal 与事件;未 sealed manifest 不可读取。硬上限为:
SQLite trigger 在并发写者下执行内容与元数据配额,重复 SHA blob 不重复计费;配额失败规范化为
RESOURCE_EXHAUSTED并回滚候选 blob。sealed checkpoint、entry、transaction 的身份/状态不可变,refcount 与 GC 只回收无引用内容,不静默修剪不可变历史。统一 mutation 边界与归因
每个高层 mutation 使用一个稳定 operation key 和一组 pre/post checkpoint,而不是按底层 syscall 产生碎片快照:
agent-code-tools.v1apply/deletecommand-runtime.v2前台批次BeginBoundary/CompleteBoundary合同自动边界要求 Run 正在运行、Session active、execution lease 精确且未过期;同一 Run 同时只能有一个 open mutation transaction。手工 Capture 在 writer 未结束时返回
CONFLICT,不会从正在写入的边界下方移动 cursor。open transaction 查询有 2,000 条 fail-closed 上限;启动 reconciliation 分批收敛,避免积压被静默遗漏。三方 Preview 与安全恢复
Preview 每次重新捕获一个不持久化的 live observed manifest,并比较:
文本、二进制、create/modify/rename/delete、未跟踪文件、mode、换行和 index 均按精确 hash 比较。目标涉及的任一路径若不再等于审阅时 current side,就返回有界三方冲突而不是覆盖;root identity/path case、base commit、branch、link/reparse、unsupported content 与 index drift 同样停止操作。
确认后的 Undo/Redo/Rewind 是新的追加写,不改写旧历史。执行前重新校验 paused Code/Deliver Run、active Session、无 live execution lease、当前非 conservative permission、进程启动 capability、显式 operator、operation key 与 expected-current cursor。历史 checkpoint 中的权限、审批、凭据、lease 或进程状态不能提供当前 authority。
文件应用通过
os.Root限制在注册根目录内,采用临时文件 + 原子 replace/remove,并在提交前后复核 root identity。Git index 通过标准index.lock做 presence + digest CAS,再原子 rename;能精确恢复“捕获时 index 不存在”的状态,并保留 index mode。若最终 cursor CAS 竞争失败,prepared Restore 会以workspace_cursor_race进入明确 failed 终态,不留下无法解释的 open transaction。Undo、Redo、Rewind 与独立 Fork
after回到该边界before。after。Fork 使用 typed literal Git argv 在历史 commit 建立新 branch/worktree,校验完整 commit、精确 branch 与目标内容,再原子注册独立 Workspace、Mission、Run、Session、初始 events 与 continuity node。新 Run 从
created开始;只继承明确的上下文/配置快照,不继承审批、凭据、permission capability、execution lease、终端、进程或网络授权,源 Run cursor 永不移动。CLI 的
--workspace-root是显式 operator-only 输入。HTTP/Desktop 不接受 renderer 提供的绝对主机路径;Go 从受信源 Workspace 确定性派生一个不存在的 sibling worktree,响应只投影新 Workspace/Run ID。Fork 本身还要求 Application 层Confirm=true,不能绕过 controller 直接调用。WAL、崩溃恢复与 reconciliation
operation digest + request fingerprint 让同意图 retry 收敛、不同意图复用 operation key 冲突;transaction prepare 先于文件写入,terminal transaction/event 在同一 DB transaction 中提交,Run cursor 使用 CAS。
启动 reconciliation 覆盖以下窗口:
before:仅从 exact expected cursor CAS 前移,再捕获 observed partial result 并关闭为interrupted;beforeCAS 到 terminalafter;Fork 明确排除,源 cursor 不动;json:"-",不进入 timeline/event/HTTP/OpenAPI),reconciliation 校验 source/destination、完整 commit、branch、完整 manifest 与原始 index 后才让 Git 移除已注册的 orphan worktree/branch。注册前 Fork 清理会先重捕获全部 manifest/index;崩溃后的任何用户编辑都会导致 fail closed、保留文件并让 transaction 可重试。清理失败不伪装成功,也不进行递归目录删除或按不可信路径操作。
安全边界与非目标
git reset --hard,也不 blanket-delete 未跟踪文件。unborn、non-git或小写 40/64 位 hex。API、Desktop 与 CLI
认证 HTTP/OpenAPI 新增:
GET 使用 read bearer;POST 使用独立 control bearer、严格 JSON、duplicate/unknown-field 拒绝和有界 body。Rewind/Undo/Redo/Fork 要求
confirm: true,operation key 可与标准Idempotency-Keyheader 绑定。生成后的 OpenAPI 为 117 paths / 130 operations / 293 schemas,TypeScript schema 已同步重建。CLI 新增
workspace checkpoint timeline|capture|preview|rewind|undo|redo|fork,结果使用 machine-readable JSON。恢复命令要求匹配当前 permission 的 process startup flags 与--confirm。Desktop Run 页面新增双语“工作区检查点 / Checkpoints”面板,展示不可变时间线、来源 receipt、attempt/capability、Git identity、恢复等级/incomplete reasons、影响路径、index drift 与冲突;只有 preview 无冲突时才开放确认。Fork 在 Go 完成 worktree、新 Run 和 final checkpoint 校验后才切换 UI。
主线兼容性
本分支直接基于当前
main1c8761a,包含 #99 的 schema v115 模型工作区工具与 #100 的 schema v116 Run-owned command runtime;本 PR 顺延为 schema v117 与 ADR 0118,不改写既有迁移历史。authority_json、v116 command-runtime records 与全部 legacy migration fixture;新增 checkpoint/blob/entry/transaction/cursor 表及 trigger。edit apply、模型工具、command runtime 与 typed Git 共用相同边界。internal/workspaceidentity,避免 checkpoint 与既有 agent-code 路径出现两套身份算法。验收条件对应
本地验证
go test -count=1 -timeout 20m ./...:全仓通过;internal/store完整 v1–v117 迁移/恢复矩阵 854.588s、internal/application414.658s、internal/httpapi180.525s。go test -race定向覆盖internal/workspacecheckpoint、internal/repository、schema v117/store 与 Application checkpoint/reconciliation 路径。go vet ./...、go mod verify、go mod tidy -diff。staticcheck -checks='SA*,S1*,QF*'覆盖全部受影响 Go 包。npm run check:api,并验证 OpenAPI/TypeScript 连续生成 SHA-256 不变。npm run typecheck、完整npm test(61 files / 249 tests)、npm run build。npm audit --audit-level=high:0 vulnerabilities;首次请求遇到 npm registry TLS 建连中断,立即重试成功。git diff --check、私有 Fork 字段投影扫描、本机绝对路径/临时文件/凭据扫描、隔离 worktree 清洁检查。额外
govulncheck ./...如实报告本机 Go 1.26.5 标准库的 5 项可达已知问题(GO-2026-6218、GO-2026-6090、GO-2026-6089、GO-2026-5972、GO-2026-5026,上游修复版本为 Go 1.26.6);它们不是仓库依赖或本次代码引入,不能把该本机扫描描述为 zero finding。远端固定补丁版的扫描结果见下节。远端 CI
No vulnerabilities found);TypeScript、Rust、Windows Desktop 与 macOS Desktop 同时通过。Go control plane 18m39s,Windows 5m19s,macOS 2m11s。审计
仍需人工证据
PR 暂保持 Draft。合并前仍建议人工确认 Desktop 时间线、三方冲突、确认按钮与 Fork 切换的 reviewer-facing 交互;实现不会把这项尚未取得的人工证据写成已完成。