Files
ycode/docs/沙盒长期工作区接入-2026-10-18.md

12 KiB
Raw Permalink Blame History

沙盒长期工作区接入(2026-10-18)

当前状态:本文记录 0.6.0 长期草稿历史范围;0.7.0 已扩展宿主 Git 导入/写回/远程。本文后部关于“宿主 Git 尚未接通/下一步”的内容是当时状态,不代表当前;请以完整 Git 接入和验收矩阵为准。长期草稿的其他限制仍有效。

交付范围

组件升级为 0.6.0 / protocol 1,新增 workspaceState: 1。同一项目、同一会话可显式选择长期草稿:连续命令保留文件与沙盒私有 Git,检查变更后再审批提交到宿主项目。默认命令仍使用每命令快照;本批没有切换用户生产配置。

这是 P2 长期工作区的已验证子集。没有新增 WorkBuddy 取证,不代表完整 P2/P3、安全中心或原版等价验收。

入口 当前行为
execute_command 不传 workspace 沿用当前权限路由;默认权限使用快照,成功变更经审批写回
execute_command 显式 workspace: "snapshot" 强制使用隔离快照,包括原本为完全访问的调用上下文
execute_command 显式 workspace: "persistent" 强制使用当前会话隔离草稿;成功命令保存草稿,不自动写宿主
sandbox_workspace status、changes、commit、discard、recover;宿主根据工具上下文确定项目/会话,不接受模型指定任意归属或路径
window.ycode.app.sandboxWorkspace(sessionId) 只读状态;主进程根据保存的会话推导项目根,检查受信顶层页面,拒绝未知会话
维护 CLI 指定绝对项目根、状态根和会话;提交需要显式 --approve

普通 read_file、write_file、edit_file、list_dir 仍作用于宿主项目。读取或修改未提交草稿必须使用 workspace: "persistent" 的命令。只读宿主文件桥仍读取绑定的宿主项目,也没有自动重定向到草稿。

使用方式

模型工具调用示例:

{"command":"echo draft-value>draft.txt","workspace":"persistent"}
{"command":"type draft.txt","workspace":"persistent"}
{"action":"changes"}
{"action":"commit","expectedRevision":"已观察到的版本 UUID"}

后两项调用 sandbox_workspace。expectedRevision 可省略;提供时版本变化会拒绝操作。status 只查看已保存状态,changes 才同步未冲突的宿主外部修改并计算待提交变更。commit 复用现有对话审批和原生 v3 宿主事务;拒绝审批会保留草稿。规划模式不能调用草稿管理工具。

私有 Git 示例:

{"command":"git add . && git commit -m draft","workspace":"persistent","runtimes":["git"]}

Git 默认由应用携带,无需用户注册。此处提交只保存当前会话的沙盒私有历史,不触发宿主写回审批,不写宿主 .git,也不代表已经提交到用户原仓库。Node/Python 仍需维护者先导入;只读依赖通过已有 dependencies 参数显式选择。

npm run sandbox:maintain -- workspace-status --workspace 'C:\absolute\project' --session SESSION_ID --state-root 'C:\absolute\userData\sandbox'
npm run sandbox:maintain -- workspace-changes --workspace 'C:\absolute\project' --session SESSION_ID --state-root 'C:\absolute\userData\sandbox'
npm run sandbox:maintain -- workspace-commit --workspace 'C:\absolute\project' --session SESSION_ID --state-root 'C:\absolute\userData\sandbox' --draft-revision REVISION_UUID --approve
npm run sandbox:maintain -- workspace-discard --workspace 'C:\absolute\project' --session SESSION_ID --state-root 'C:\absolute\userData\sandbox'
npm run sandbox:maintain -- workspace-recover --workspace 'C:\absolute\project' --session SESSION_ID --state-root 'C:\absolute\userData\sandbox'

discard 归档旧草稿和私有 Git 引用,然后从当前宿主/策略建立新基线;它不是永久删除历史的保留清理。若宿主提交结果尚未确定,必须先 recover,避免把已发生的宿主写入当作未执行。

保存、隔离与冲突

状态位于 stateRoot/workspaces/<项目与会话摘要>/。活动引用指向摘要校验的不可变版本清单,文件内容保存在 SHA-256 blob 中。blob 先写临时文件并刷新,再发布到摘要名称;版本清单发布前限制为 8 MiB。默认文件/总容量/条目上限继续有效;保留历史没有自动回收,也不是操作系统磁盘硬配额。

正常成功命令之间保留同一个实际 NTFS 工作目录身份:执行前将 worktree 移入本次私有 stage,执行结束并清理 Job/profile/映射后移回。没有每次重新复制整个项目。恢复、丢弃可以重建物理目录并产生新身份。

新增宿主专用 --seal-workspace:使用原生相对目录句柄递归检查并设置受保护 DACL,只允许宿主用户和 SYSTEM。它拒绝 AppContainer 调用、链接、多重硬链接和过深/过量目录。保留文件移回前去除旧 AppContainer 权限;blob/版本存储由宿主独占,后续同会话 Job 也不能直接读取。运行时只向本次 stage 开放当前 Job 所需访问,宿主项目 ACL 不改变。

版本绑定规范项目根、宿主根卷/文件身份、会话、策略内容指纹和草稿 revision。换根、策略变更、物理草稿被替换、摘要损坏均拒绝自动复用;失效状态不返回旧文件名。明确 discard 后才按当前策略建立新草稿。

执行与管理操作复用项目队列,持有独占草稿锁。status 走队列外的只读检查,命令运行或等待提交审批时及时返回 busy。宿主外部修改在下一次同步时做三方合并:不相关修改进入草稿;同文件、目录祖先冲突停止执行/提交,保留双方内容。当前不进行行级文本合并;文件/目录互换在发布新版本前拒绝。

中断与提交结果

  • 非零退出、取消、超时不发布新文件版本,恢复最近的已保存草稿;未成功内容归档在宿主私有存储。
  • checkout.json 记录执行归属,mutation.json 记录同步意图;未完成记录阻止普通复用。显式恢复检查保存的 run 请求、会话、主进程锁和原生租约,活动进程或未清理租约继续拒绝接管。
  • 草稿提交先保存 commit-intent.json,授权绑定 revision、宿主根身份和完整变更摘要。原生宿主事务仍使用 v3 根身份/逐操作日志与独立备份。
  • 宿主已经提交、但随后草稿元数据失败时,结果仍报告 writeback: committed,并保留需恢复状态。recover 根据授权和会话匹配原生事务,再推进草稿基线;结果未知时不自动重试宿主写入。
  • 私有 Git 使用独立的项目/会话命名空间,与原有项目级快照 Git 分开。文件检查点和 Git 发布是两个步骤;Git 失败单独报告,不能声称两者为单个崩溃原子事务。失败命令和真实宿主进程死亡的用例已验证旧 Git 版本不被替换。

恢复支持进程中断,不承诺逐原生指令断电耐久性。原有宿主文件替换仍为禁止覆盖的两次重命名,有短暂缺名窗口,见原生写回事务。

若未确定的宿主提交同时遇到策略或宿主根身份变化,当前自动恢复会拒绝继续,丢弃也不会绕过该记录。此组合需要维护者核对原事务;尚无跨策略/换根自动迁移恢复入口。

源码与验证

文件 职责
native/sandbox/workspace-state.h、runner.cpp 原生宿主封存入口、目录句柄与 DACL
src/main/sandbox/workspace.ts 物理草稿、blob/版本、三方同步、锁、检查点与恢复
src/main/sandbox/workspace-service.ts 管理动作、审批、宿主提交意图与结果恢复
src/main/sandbox/workspace-files.ts 快照/变更扫描共用实现,由原 service 提取
src/main/sandbox/service.ts、git-repository.ts 命令模式路由、草稿生命周期、私有 Git 命名空间
src/main/agent/tools/sandbox-workspace.ts、tools/index.ts 模型工具与显式工作区参数
main/preload/shared IPC、scripts/sandbox-maintain.ts 所属会话只读状态与维护入口

npm run build 已通过,包含原生 /W4 /WX、TypeScript 和 main/preload/renderer 生产构建,日志 .tmp/sandbox-persistent-final-build.log。专项命令为 npm run test:sandbox:workspace;生产整应用为 npm run test:sandbox:app。测试期间不能重建正在使用的原生 exe;批量回归直接运行同一次构建对应的独立测试 bundle。

最终报告与摘要汇总见 .tmp/sandbox-persistent-validation.json。所有测试使用独立 .tmp 项目/状态和隔离 Electron userData;生产 OMP 使用实际已安装内核及本机回环模型,没有调用用户付费 API。

最终 11 组共 356 项通过:

专项 结果 最终报告
长期会话草稿 51/51 .tmp/sandbox-workspace-b84whI/report.json
真实生产 Electron/OMP 42/42 .tmp/sandbox-app-ZWTjR8/report.json
基础隔离/宿主工具 52/52 .tmp/sandbox-regression-XPTm0T/report.json
Git 本地工作流 43/43 .tmp/sandbox-git-mDlqPV/report.json
策略/授权 38/38 .tmp/sandbox-policy-zkcBxS/report.json
目录事务 13/13 .tmp/sandbox-directories-mKwa11/report.json
原生宿主写回 32/32 .tmp/sandbox-write-eZDjBV/report.json
内置 Git 分发 20/20 .tmp/sandbox-bundled-git-EmYmSY/report.json;本次未提供离线归档重建参数
只读文件桥 21/21 .tmp/sandbox-read-bridge-22EY7p/report.json
Node/Python 进程兼容 20/20 .tmp/sandbox-process-QOd5lW/report.json
工具链/依赖 24/24 .tmp/sandbox-toolchain-FUo7VU/report.json

组件 manifest 中全部原生源码摘要、适配器摘要和二进制摘要已与实物逐项核对;原生 --version 与 manifest 均为 0.6.0。汇总另保存 main/preload 产物和测试报告摘要。本批没有重新构建安装包,不能用之前的 0.4.0 目录包验收替代当前 0.6.0 发布验收。

专项包含真实独立 Node 宿主进程死亡及原生租约恢复、真实 AppContainer 跨会话/同会话私有内容拒绝、只读依赖注入/卸载、原生宿主提交、提交后元数据故障、策略撤销、中文/空格/^ 路径和 CLI 新进程重载。同步/检查点已发布但确认记录未移除的用例是可复现磁盘状态夹具;不把夹具当作每个写入指令位置强杀或断电测试。

尚未完成

长期草稿目前保留受过滤的项目文件和私有 Git。进程、home、TEMP、工具和盘符映射仍为每命令生命周期;实际执行绝对路径不稳定,原项目绝对路径不重定向,后台服务不会跨命令继续运行。

node_modules、.venv、venv、.tmp、__pycache__ 等不作为可写持久层保存。受控只读依赖可临时注入,Node 依赖在封存前移除;联网安装、可写依赖缓存和链接布局仍未完成。宿主 Git 历史/索引导入、元数据事务和远程 Git 尚未接通。

完整文件 shim、元数据/回收站、受控出站、逐程序/逐后代规则、MCP/交互终端系统隔离、安全中心页面、自动保留清理、磁盘硬限额、安装升级、标准用户/平台矩阵、断电耐久性及独立安全审查继续按完整计划推进。当前用户窗口未重启;主进程/preload 新入口在完整重启后加载。

下一步优先处理宿主 Git 的安全导入与元数据事务,然后完善可写依赖和受控联网;相应验收仍逐项记录,不将本批长期草稿通过扩大为完整沙盒完成。