完善Linux工作区命令沙箱

新增 bubblewrap 工作区写入、控制目录保护和默认断网沙箱
统一 command.exec、command.start 与 project.verify 的启动和审计边界
开放 Linux 通用项目命令并保留非 Linux 固定命令兼容边界
补齐持久进程元数据、真实进程测试、共享契约和发布依赖
同步真实 Provider 结论、已知竞态与项目长期文档
This commit is contained in:
AIGameCreator App
2026-07-14 05:54:02 +08:00
parent a9f7bda805
commit 143684011b
18 changed files with 2106 additions and 169 deletions
@@ -544,6 +544,39 @@ V1.10 为需要持续交互的前台开发进程增加 Runner-owned PTY 会话
2026-07-14 真实 `gpt-5.5` V1.10 验收已通过。`process-session` 在无工具配方任务中自行完成 1 次 start、3 次连续 cursor poll、1 次 stdin 和 1 次 terminate,形成 41 条 task、75 条 event、63 条 Agent DB、8 条 action receipt、4 套确认生命周期、唯一 completed / assistant audit / assistant;fixture launch 为 1,终态后 PID 与端口均消失,副作用重放、重复 action / message / receipt、PTY / stdin 公共正文、密钥和诱饵泄漏均为 0。独立 `process-session-runner-kill` 在 readiness 后真实 `SIGKILL` owning Runner,形成 21 条 task、34 条 event、36 条 Agent DB;新 boot 保持原 run / session 身份,只把旧会话转为 1 条 reconciliation,launch 仍为 1、PID reconnect 为 0、PID / 端口消失,completed / assistant / 副作用重放和公共正文泄漏均为 0。两套 disposable 项目均按 sentinel 清理。
## V1.11 OS 强制工作区沙箱与通用项目命令
V1.11 把命令安全边界从“固定 program + argv 规则 + 隔离环境变量”升级为 OS 强制 workspace sandbox。approval policy 仍决定动作是否需要确认,sandbox 独立决定确认后的真实进程能访问哪些文件和网络;确认不能扩大沙箱权限。首版只把 Linux 标记为通用命令已支持平台,Windows 继续保留 V1.10 受限命令与 Job Object,不伪装成等价隔离。
### Linux launch 契约
- `command.exec` 与 `command.start` 必须继续共用唯一 `ProjectCommandLaunchSpec`,`project.verify` 必须调用同一 sandbox launcher。真实 executable / argv 在该层包装为受信任系统 bubblewrap;一次性 Tokio child、PTY child wrapper、npm 验证脚本和全部后代不能有绕过该包装的生产 spawn 路径。
- bubblewrap 只允许从固定系统候选路径解析,文件必须是普通可执行文件且不能被当前普通用户写入。缺失、权限异常、namespace setup 失败或挂载失败都返回 `sandbox-unavailable` / preflight 失败;不得尝试裸 `unshare`、代理断网或无沙箱宿主执行作为 fallback。
- sandbox 使用独立 user / mount / pid / ipc / uts / cgroup / network namespace,禁用嵌套 user namespace,并启用 parent-death 收束。系统 executable / dynamic runtime 和明确工具链缓存只读挂载;规范项目根以原绝对路径读写挂载,cwd 仍必须是无 symlink / reparse point 的项目内目录。
- 项目根挂载后覆盖控制目录:`.git / .agents / .codex / .hermes` 存在时按原路径只读挂载;`.agent` 使用不可读写的空 mount 覆盖,命令不能看到 Runtime sidecar、会话、审计或配置。项目内指向外部的 symlink 因目标未挂载而不可访问。
- HOME / USERPROFILE / TMP / Cargo / npm cache 使用 sandbox 内私有临时目录。允许只读复用不含凭据的工具链 source cache,但外部工具链环境根必须 canonicalize 后再次校验为与变量类型匹配的窄叶目录;`RUSTUP_HOME=$HOME`、`.rustup -> $HOME` 和其它宽用户目录必须失败关闭。不得挂载整个用户 HOME、AppData、SSH、云凭据、Cookie 或 Runtime 配置目录。
- 网络 namespace 默认无外部网络,HTTP(S) / ALL proxy 与离线包管理器变量只作为纵深防御。`networkAccess` 首版固定 `disabled`,模型输入不能开启;需要联网必须作为未来独立 approval escalation 设计,不能复用普通 confirm 偷渡。
### 通用命令契约
- Linux sandbox 生效后,`program` 从固定 cargo / npm / node / git / rg 扩展为裸可执行名:1-64 个 ASCII 字母、数字、点、下划线、加号或连字符,不接受绝对路径、相对路径、路径分隔符、NUL 或控制字符。executable 必须从 Runtime 构造的受信任 PATH 解析,项目内同名文件不能劫持。
- `args` 继续结构化逐项传输,最多 64 项、单项 512 字符、总计 8 KiB、禁止 NUL 和控制字符;Linux 不再按工具子命令维护 cargo / npm / node / git / rg 白名单,也允许 `bash -lc` 在 OS sandbox 内承载管道、重定向和项目脚本。模型不能注入环境变量、sandbox mount、network policy 或宿主 executable path。
- `command.start` 只用于从仓库清单确认过的持续交互长进程;有限诊断、文件探测、构建和测试使用 `command.exec`。同一服务 start 成功后,后续必须沿返回的 processId 执行 poll / stdin / terminate,不能为了探测、试错、重试或停止另起 session;验收器发现第二条 process record 时立即失败,不能空等到总超时。
- 非 Linux 平台继续使用 V1.10 固定 program / argv 校验,直到对应平台具备等价的原生强制隔离。共享 capability 的 `os-workspace-sandbox` 必须携带 `platforms=[linux]`,prompt 和 UI 也必须按平台陈述能力,不能让 Windows 用户误以为任意命令已安全开放。
- Git 控制目录只读,因此 status / diff / log / show 等检查可运行,commit / checkout / reset 等写操作会由 OS 拒绝。源码与普通项目产物可写;`command.exec` 若改变源码,继续推进 revision 并使本次 verification 失效,不能用命令退出码冒充 passed gate。`command.start` 永远不签发验证凭证。
### 失败、审计与验收
- namespace canary 与项目 mount preflight 失败时,必须在 revision / processId 推进前返回稳定的 sandbox unavailable / setup 错误并保持项目命令未执行。当前 preflight 与随后真实 bwrap launch 是两次独立启动:真实 launch 若在目标 exec 前发生第二次 setup 失败,目标程序不会绕过沙箱执行,但尚无可信 exec-ready 握手证明失败阶段,revision 可能已经推进并按普通命令失败收束。这是 V1.11 已知残余,后续必须用 launcher 握手把“沙箱已建立且目标已 exec”与“仅准备采用沙箱”分开,不能把当前行为描述为原子保证。
- command log、terminal receipt、Agent DB 和 process record 至少记录固定 `sandboxMode=workspace-write / networkAccess=disabled / sandboxBackend=bubblewrap / sandboxProfileVersion=workspace-v1` 安全元数据,不记录 host mount source、用户 HOME、bwrap 完整 argv 或本地工具链路径。process record 使用 schema v2 持久化 launch 当时的四项元数据,poll / stdin / terminate 和旧 boot reconciliation 必须从 record / live session 读取,不能按当前平台静态猜测;旧 v1 record 只能迁移为 `legacy-unknown`。纯 preflight 失败记录 `unavailable / not-established`,不得谎报 bubblewrap 已建立。
- 确定性真实进程测试必须证明:项目内构建 / 测试 / Git 读取成功;项目外普通文件读取与写入失败;`.git / .agent / .agents / .codex / .hermes` 写入失败;网络默认不可达;shell 子进程继承同一边界;bwrap 不可用时项目命令零执行且失败关闭。`command.start` 还必须让 PTY 后代实际执行 `setsid + chdir` 后的项目外读取、控制目录写入和原始 socket 负例,并断言 process record 与每段专用审计的四项 sandbox metadata。
- deb / rpm 发布包声明 `bubblewrap` 宿主依赖;AppImage 不携带 bubblewrap sidecar,发布页和安装检查必须明确要求受支持版本的系统 `/usr/bin/bwrap` 或 `/bin/bwrap`。缺失时命令工具安全失败关闭,但该 AppImage 不算具备可用的通用开发能力。
- 真实 Provider disposable E2E 不给固定 program、文件名或工具顺序,要求模型自行发现项目技术栈,运行构建、测试和 Git 检查,并用结构化审计证明所有命令都在 workspace-write / network-disabled 下执行。上述门禁通过前不得宣称 V1.11 完成。
2026-07-14 最新真实 `gpt-5.5` `llm-runtime` 已按新增 metadata 门禁通过:123 条 task、208 条 event、220 条 Agent DB、15 次成功工具执行、2 次 `command.exec`(先失败后成功)、1 次 `project.verify`、3 个隔离实例、双视口浏览器验证、唯一 completed / assistant;Runner 强杀后 run / session 身份稳定恢复,重复、副作用重放、密钥和诱饵泄漏均为 0。保留现场独立核对 2 条 command.exec 和 1 条 project.verify 审计均为 `bubblewrap / workspace-write / disabled / workspace-v1` 后按 sentinel 清理。
同日追加的 `process-session` Provider 复验未计为通过:前三轮模型以不同 actionId / fingerprint 主动重复 start,现场同时存在大量把有限探测误用为 command.start 的失败动作;收紧策略后不再重复 start,但仍因没有形成 challenge 精确回显而以 `process-transcript-interaction-evidence-missing` 失败。13 项确定性 process session 测试和真实 PTY `setsid + chdir` 沙箱负例仍通过,process record / start / poll / stdin / terminate metadata 均正确;在新的 Provider 严格单 launch 交互套件 PASS 前,不更新 V1.10 的历史 process Provider PASS 结论,也不把本次失败描述成已验收。
## 验收命令
- `npm run ai-game-creator-shell:typecheck`
@@ -16,6 +16,8 @@
## Runtime 边界
V1.11 的受保护仓库控制目录同时包含 `.git / .agent / .agents / .codex / .hermes`;其中 `.agent` 对项目命令隐藏,其余控制目录只读。
2026-07-12 起,通用开发能力的 Runtime V1.1 增量以 [`【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md`](./【技术方案】AI游戏创作Agent%20Runtime%20V1.1-2026-07-12.md) 为编码级事实源。它补充仓库启动上下文、同一发布二进制独立 Runner、受限本地预览浏览器验证、动态隔离子 Agent 和真实 Provider 全链路验收;本文件中“进程内 tokio task”“首轮不预加载项目内容”和“不创建动态执行实例”的旧口径由 V1.1 明确替代,未涉及能力继续沿用本文件。
同一文档的“V1.2 对标 Codex CLI 增量”继续作为受控命令与推理档位的事实源。对一次性 `command.exec` 而言,只接受 Runtime 白名单内的固定 `program` 和逐项 `args` argv,默认 `confirm`,可执行文件解析为项目外绝对路径且子进程只使用安全 PATH;不解析 shell 字符串,不提供管道、重定向、PTY 或后台进程。这里对 PTY 和后台进程的排除仅适用于 `command.exec`,不能用来否定 V1.10 的独立持久进程工具,也不能把 `command.exec` 自身改成长驻入口。`command.exec` 的 action、stdout / stderr、退出码、超时与源码指纹结果统一进入现有 `action / observation`、project revision、verification gate 和 `needs-reconciliation` 链路;只有明确验证型命令且退出码、源码指纹、命令日志、manifest 与 Agent DB 审计全通过才签发 passed gate,Git / rg / cargo metadata / 普通 npm run 只作诊断。首版只请求终止受控进程组,安全等级与 `project.verify` 相同,不宣称已具备完整 OS sandbox 或 detached-process 隔离。
@@ -28,6 +30,8 @@
2026-07-14 V1.10 真实 `gpt-5.5` 验收:`process-session` 在无工具配方任务中完成 start / 3 次连续 cursor poll / stdin / terminate,41 条 task、75 条 event、63 条 Agent DB、8 条 receipt、4 套确认生命周期和唯一 completed / assistant,fixture launch 为 1,终态 PID / 端口、重放、重复与公共正文 / 密钥 / 诱饵泄漏均为 0。独立 Runner 强杀套件形成 21 条 task、34 条 event、36 条 Agent DB,新 boot 保持原 run / session,只产生 1 条 reconciliation,launch 仍为 1、PID reconnect / final / assistant / 重放 / 泄漏均为 0;两个 disposable 项目均已清理。
2026-07-14 起,同一文档的“V1.11 OS 强制工作区沙箱与通用项目命令”替代 V1.2 / V1.10 在 Linux 上的固定 program / 严格 argv 白名单边界。`command.exec / command.start` 继续接受结构化 `program + args + cwd`、沿用 confirm policy、durable action、revision、verification、输出和进程会话协议;`project.verify` 也必须复用同一 launcher,不能保留平行的宿主 npm spawn。Linux 只在受信任系统 bubblewrap 创建的 workspace-write sandbox 内启动真实命令:项目根可写,`.git / .agents / .codex / .hermes` 只读,`.agent` 不可见且不可写,项目外普通用户文件不挂载,网络 namespace 默认隔离,所有后代继承相同边界。program 只接受无路径分隔符的裸可执行名并从受信任 PATH 解析,argv 只保留数量、长度和控制字符硬限制;允许 `bash -lc`、Git、构建器、测试器和项目脚本在沙箱内自行工作。外部工具链环境根必须 canonicalize 后校验为窄工具链目录,禁止把整个 HOME 或其符号链接目标挂入沙箱。bubblewrap 缺失、不可执行或 setup 失败必须在项目命令执行前失败关闭,不允许退回宿主全权限。process record v2 与命令审计持久化真实 launch metadata,失败不能按平台静态冒充已建立沙箱。共享 `os-workspace-sandbox` capability 只标记 Linux;Windows 首版继续使用原固定白名单、隔离环境和 Job Object,不能宣称已达到同等 OS sandbox。deb / rpm 声明 bubblewrap 依赖,AppImage 依赖宿主预装且缺失时功能失败关闭;approval 与 sandbox 仍是两层独立门禁。
2026-07-12 真实验收:发布 AppData 中的真实 `gpt-5.5` 已通过最终安全收紧后的 `llm-runtime` 套件,覆盖 Runner 强杀恢复且 run/session 身份稳定、仓库上下文、checkpoint/精确修改、失败命令诊断与修复复验、6 套确认生命周期、项目验证、桌面与移动非空画布证据、3 个隔离实例并行和唯一 all-join;95 条 task、161 条 event、137 条 Agent DB、13 条合法工具协议、副作用判重、终态投影、assistant audit、消息、回执和密钥泄露均以结构化落盘事实验收。`full` 套件仍要求 External Editor API 配置,缺失时必须返回 `BLOCKED(editorApi)`,不得记为通过。
2026-07-13 V1.3 真实验收:同一真实 Provider 套件已改为先读取 SHA-256,再用唯一一次 `project.patchset` 同时更新和创建文件,并使用自动 checkpointId 读取 2 项内容 hunks;prepared / completed 审计各 1 条、patchset revision 增量为 1,Runner 强杀恢复、命令和项目验证、双视口浏览器验证、隔离 Agent join、重复副作用与密钥扫描继续全部通过。
@@ -501,7 +505,7 @@ game-project/
- 普通模式渲染聊天区、上传入口、Agent 状态列表和单 Agent 对话;Tauri 主窗口不承载工具台布局,也不承载游戏预览画面。
- 聊天生成草案后会尝试启动只读 `127.0.0.1:<port>` 静态 HTTP server,调用系统外部浏览器打开预览,并把预览地址回到聊天消息;外部浏览器打开失败时保留本地 URL 供用户手动复制。
- 开发模式仅在 Vite dev 环境响应 `?dev` 或 `#dev`,Tauri dev 可额外打开 `developer` 窗口显示专业组、本地项目、预览 iframe 和内置命令日志;正式构建忽略 dev 参数,release 配置只登记一个用户窗口,登录后同窗口进入首页并在项目组 / 项目开发占位之间切换。
- `check:native-shells` 会运行 `ai-game-creator-shell:check` 和 `ai-game-creator-shell:build -- --no-bundle`,并静态检查 release 只登记一个用户窗口、开发窗口只在 debug 下打开,开发面板必须挂在 `devMode` 分支内,正式用户 App 不能嵌入游戏预览 iframe,release CSP 也不能允许 `frame-src http://127.0.0.1:*`,用户侧预览命令必须调用 `open_local_game_preview` 交给系统外部浏览器,用户主流程不得调用旧工作区窗口切换 command。
- `check:native-shells` 会运行 `ai-game-creator-shell:check` 和 `ai-game-creator-shell:build -- --no-bundle`,并静态检查 release 只登记 `client / index.html` 这一个用户窗口、开发窗口只在 debug 下打开,开发面板必须挂在 `devMode` 分支内,正式用户 App 不能嵌入游戏预览 iframe,release CSP 也不能允许 `frame-src http://127.0.0.1:*`,用户侧预览命令必须调用 `open_local_game_preview` 交给系统外部浏览器,用户主流程不得调用旧工作区窗口切换 command。
- 共享契约提供 `GAME_CREATION_AGENT_CAPABILITIES` 和内置命令权限枚举;开发模式会展示能力列表。
- 共享契约提供 manifest task schema 和 ready-task 选择器,用于记录任务拆分、专业组、角色模板、依赖、产物、验收条件和当前可执行任务。
- 开发模式可读取、保存、删除短期记忆和长期记忆文件;普通用户通过聊天命令完成同类能力。