Files
Genarrative/docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md
T
AIGameCreator App 0fbb76fb94 补齐Agent Runtime工具计划强杀恢复门禁
新增真实 Provider 工具计划交接 checkpoint、Runner 强杀恢复与零重放验收。

收紧 Supervisor 首波协作、返工 runId 和持久 delivery 合同。

扩展敏感正文扫描、跨平台安全回归和 E2E 自测。

注册两级 npm 命令并同步 Runtime 验收文档与当前证据。
2026-07-20 15:48:07 +08:00

320 KiB
Raw Blame History

AI 游戏创作 Agent Runtime V1.1 技术方案

更新时间:2026-07-14

目标

在不引入第二套任务系统、不开放任意 shell、不复制现有 Runtime 的前提下,优先补齐五项通用开发能力:

  1. 仓库启动上下文与代码理解。
  2. 脱离 WebView / Tauri UI 生命周期的独立持久 Runner。
  3. 面向当前本地项目预览的真实浏览器验证。
  4. 动态创建、隔离运行、并行执行并统一回收结果的子 Agent。
  5. 使用真实 Provider 覆盖计划、工具、修改、确认、验证、持久化和重启恢复的自动验收。

本方案是现有 【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md 的 Runtime V1.1 扩展,不建立平行 App、平行队列或平行持久化真相。

不在本轮

  • 任意 shell、远程命令执行和通用进程管理。V1.1-V1.9 的 command.exec 不提供 PTY 或后台进程;V1.10 仅按本文件对应章节开放 Runner-owned 受控前台 PTY 会话,不开放 shell、用户指定可执行文件或 detached 子进程。
  • 完整 Git 分支、提交、合并和 worktree 工具。
  • 云端 Runner、跨机器任务迁移或无人值守开机自启。
  • RAG、CodeGraph、tree-sitter 或语言服务器作为发布依赖。
  • 允许 Agent 访问任意网址、执行任意 JavaScript 或复用用户浏览器 Profile。
  • 用动态子 Agent 绕过项目权限、项目写锁、revision 或验证门禁。

总体结构

WebView / CLI
  |
  | Tauri command + RunnerClient
  v
AppData runner endpoint (protocol + port + private token)
  |
  | 127.0.0.1 length-prefixed JSON
  v
同一发布二进制 --agent-runner
  |
  +-- .agent/runtime 任务、恢复、确认、终态账本
  +-- repository startup context
  +-- preview.validate / Chrome CDP
  +-- isolated child-agent lanes and join receipts

.agent/runtime/** 继续是任务执行事实源。Tauri command 负责用户授权、精确确认和 UI 桥接;Runner 是 LLM、工具循环、队列 drain、恢复和浏览器验证的唯一执行者。事件只作为刷新提示,UI 断线重连后必须重新读取完整 Runtime snapshot。

1. 仓库启动上下文

契约

新增 RepositoryStartupContext,每个 run 在首次 planning 前确定性装配,恢复时按相同规则重建。正文不混入普通 observation,不受每 6 轮一次的进度 checkpoint / 停滞检测影响,也不交给 V1.21 summary 改写;context bundle 只保存 schema、来源清单和 fingerprint。

启动上下文最多包含:

  • 有界顶层目录摘要、文件/目录数量和是否截断。
  • package.jsonCargo.tomlpyproject.tomlgo.mod 等 manifest 摘要。
  • 可验证脚本名和原始命令摘要;执行仍必须走 project.verify
  • 根目录及嵌套目录中的 AGENTS.md 路径和有界正文,按根到具体目录叠加。
  • CONTEXT.md、README 的有界背景摘要和项目记忆来源列表。
  • 固定安全 Git 摘要:是否为仓库、当前分支、tracked dirty 数;不开放任意 Git 参数。
  • 常见入口文件候选和按扩展名聚合的语言分布。

任意源码正文、对话、资产、私有记忆和黑板正文仍必须通过已有工具按需读取。仓库文本一律标记为不可信项目输入,只能约束项目做法,不能提升工具权限、覆盖 Runtime 系统规则或自动批准动作。

预算与安全

  • 最多扫描 10,000 个目录项、2,000 个候选文件、深度 12。
  • 跳过符号链接、.git、整个 .agent 控制面、依赖、构建、缓存和敏感配置目录;任务图、会话、记忆、checkpoint 和 Runtime 证据只能通过专用工具读取,不能参与仓库指纹。
  • 单规范文件最多 24 KiB,全部规范正文最多 64 KiBprompt 渲染最多 20 KiB。
  • 不读取 .env*、运行时配置、认证文件、Cookie、Token 或数据库 dump。
  • 每个 durable 工具动作在真正执行前都要重建并复核 repository fingerprint;发现适用规范或启动上下文漂移后,旧动作必须落为 blocked observation,跳过本轮剩余动作并在同一 run 下一轮 planning 重新确认。创建 checkpoint、写 Runtime 日志等 .agent 控制面变化不得制造伪漂移。
  • 项目索引、checkpoint、diff 和 restore 使用同一敏感路径排除规则,额外排除私钥、数据库及 dump 文件;checkpoint manifest 中每个文件路径必须是可移植的规范相对路径,拒绝绝对路径、..、反斜杠、盘符 / UNC / ADS 别名、控制字符、Windows 非法字符、尾随点或空格、保留设备名和符号链接边界。manifest 路径按 Windows 大小写不敏感键去重,禁止 State.txtstate.txt 同时出现。通用文件工具不能读写 .agent/checkpoints/**restore 不覆盖或删除 .env*、运行配置、认证文件、私钥、数据库、dump、.agent、VCS、依赖和构建目录。

project.index 升级为显式刷新和查看完整启动摘要的工具;自动启动上下文使用同一构建核心,不建立第二份索引。

2. 独立持久 Runner

进程模式

同一 Tauri 发布二进制新增:

--agent-runner --config-dir <AppData 目录>

Runner 从显式 AppData 目录读取 game-creator.config.jsonAPI Key 不进入 IPC payload、项目目录、状态文件、日志或验收报告。Unix 使用新 session,Windows 使用新进程组和无窗口标志,使 Runner 不依附 WebView 生命周期。

本地协议

  • Runner 只监听随机 127.0.0.1 端口。正常启动先使用 bind(127.0.0.1:0)Linux 仅在该调用因 AddrInUse 失败后,才读取并严格解析 /proc/sys/net/ipv4/ip_local_port_rangeip_unprivileged_port_startip_local_reserved_ports。候选限定在 61000-65535 高位段,排除当前临时范围、低于实际非特权起点和显式 reserved ranges,再按当前 boot 随机化起点并跳过已占用端口。任一 sysctl 缺失/非法、候选耗尽或出现非占用类错误必须失败关闭,不得停止现有服务、绑定非 loopback 地址或回退到无 token IPC。
  • AppData endpoint 文件权限收紧为当前用户,保存 protocolVersion / pid / bootId / port / token / heartbeatAt
  • 请求使用 u32 长度前缀加 UTF-8 JSON,单帧最多 1 MiB。
  • 每个请求必须携带私有 token、requestId 和协议版本。
  • 首版方法:runner.pingrunner.statusruntime.wake_pendingruntime.resumeruntime.continue_actionrunner.shutdown_if_idle
  • 只读失败可重试;写请求先按 requestId/runId 重读事实源,禁止网络重试制造重复任务。

执行所有权

  • App 写入精确用户输入、任务或确认账本后只通知 Runner;不再在 App 进程中 claim 后台任务。
  • Runner 复用现有恢复顺序:finalization -> pending action -> recoverable task -> delegate/join receipt reconciliation。
  • 同 Agent 继续持有 per-Agent OS 锁,不同 Agent/子 Agent lane 可并行。
  • Runner 崩溃后,现有 executing -> needs-reconciliation、finalization 幂等和 cancel tombstone 语义保持不变。
  • 整机重启后不自动执行;App/CLI 下次启动并经过 agent.resume 策略后恢复。

跨进程前置修复

  • .agent/agent.db、conversation、events、tasks、activity、output 和 Session catalog 的读改写临界区升级为进程内 Mutex + OS 文件锁。
  • App 配置写入改为同目录临时文件 + 原子替换,Runner 只读取完整版本。
  • Runner endpoint、项目 execution-owner 和协议主版本共同阻止 split-brain。
  • 所有会写 Runtime 的 CLI 命令必须显式传入项目外 AppData,不能回退到 CLI 进程内执行;--runner-status 只读已有 endpoint,不得为了查询状态启动 Runner。
  • AppData 在 Unix 上必须由当前用户持有且权限为 0700endpoint/lock 为 0600。Windows 下 AppData 目录、Runner endpoint、AppData Runner lock 和 execution-owner 诊断文件使用禁止继承的 protected DACL,只允许当前用户 SID;目录 ACE 带对象 / 容器继承,文件 ACE 不带继承。写入口可以收紧后复核,只读状态入口只能校验,不能创建、收紧或修复。
  • Runner lock、Agent lane lock 和项目 execution-owner 均拒绝符号链接、硬链接或 Windows reparse pointUnix 通过 openat 逐级无跟随打开,Windows 持有逐级目录句柄,取得稳定句柄和 OS 锁后才允许写诊断信息。
  • 项目 execution-owner 是项目级跨进程系统锁,不按 AppData 分叉;不同 AppData 启动的 Runner 不能同时接管同一项目。.agent/runtime/execution-owner.lock 只承载句柄级排他所有权,execution-owner.json 是可恢复诊断投影:诊断缺失、截断或损坏不能阻止合法锁持有者恢复,也不能作为接管依据;新诊断经临时文件写入、同步、原子替换和回读全等校验,仅在旧完整记录可信时写入 recoveredFromBootId

3. 浏览器验证

工具

新增 preview.validate,不新增通用 browser.open

输入只允许:

{
  "viewports": ["desktop", "mobile"],
  "expectedText": ["可选可见文本"],
  "settleMs": 800,
  "failOnConsoleError": true
}

工具不接受 URL、脚本、请求头、Cookie 或浏览器 Profile。Runtime 只验证当前项目 PreviewRegistry 中的精确 loopback URL;独立 Runner 未持有持久预览时,可启动同一项目的临时预览并在验证后关闭。

证据

通过系统 Chrome/Chromium/Edge 的 CDP 采集:

  • document.readyState、title、可见文本摘要和 DOM 字符数。
  • console error/warn、未捕获异常和失败网络请求。
  • canvas 尺寸、可见面积和非空像素抽样;每个视口至少存在一个可见 canvas,且抽样必须同时包含非透明像素和至少两种 RGBA 状态,全透明或均匀纯色画布不能通过。
  • desktop 1280x720mobile 390x844 PNG 截图。

viewports 必须且只能同时包含 desktopmobile;单视口、重复视口、空 body、无 canvas 或空白 canvas 都是失败,不允许用成功摘要掩盖缺失证据。

证据写入 .agent/runtime/browser-validations/<agentId>/<runId>/<revision>/。observation 和 LLM 只接收脱敏计数、诊断摘要和项目内相对路径,不接收截图二进制或完整 DOM。

安全

  • 只从操作系统固定安装位置发现 Chrome / Chromium / Edge,不搜索 PATH。仅允许精确 http://127.0.0.1:<port> 预览 origin;导航前开启覆盖全部资源的 CDP Fetch request-stage 拦截,网络只放行同 origin HTTP 和同 host / port WebSocket。其他端口、HTTP(S)、WSS、跨 origin redirect target 和 WebSocket 必须在连接或握手前阻断并记为致命策略失败;浏览器默认走不可达代理,只为精确 HTTP / WS origin 配置 bypass。
  • 使用全新临时 Profile;不添加 --no-sandbox
  • 验证前后重读 project revision 和预览身份,任一漂移都使结果失效。
  • preview.validate 是独立试玩证据,不替代修改后的 project.verifygame.static_smoke 完成门禁。

4. 动态隔离子 Agent

工具契约

保留 agent.delegate 的静态规范 Agent 语义,新增 agent.spawn_isolated

{
  "children": [
    {
      "templateAgentId": "code-prototype",
      "task": "完成一个边界清晰的子任务",
      "acceptanceCriteria": ["可验证条件"],
      "expectedArtifacts": ["game/feature-a/**"],
      "writeScopes": ["game/feature-a/**"]
    }
  ],
  "joinMode": "all"
}

模型不能指定执行实例 ID。Runtime 从父 actionId 稳定派生:

  • delegationGroupId = sha256(parentActionId)
  • delegationId = sha256(groupId + childIndex)
  • instanceId = child-<delegationId 前缀>
  • 每个实例使用独立 session、run、queue、state、event、lock 和私有临时记忆。

隔离与限制

  • 角色 prompt、LLM 配置和 Agent 策略继承 templateAgentId;执行和持久化 lane 使用 instanceId
  • 单次最多 3 个并行实例,最大深度 1。
  • sibling writeScopes 不得重叠;所有真实写入仍通过项目级写锁、revision 和 verification gate。
  • 子实例初版默认拒绝 agent.spawn_isolatedproject.restoreagent.schedule_ready;现行无条件拒绝集合以 V1.34 为准,模板、项目策略和用户确认都不得放宽。
  • 子实例的 memory.read/write(scope=agent) 只访问 .agent/runtime/isolated-agents/memory/<instanceId>.json 私有临时 lane;不能指定 sibling 或静态模板 Agent,也不能写 project / session / blackboard 共享记忆。普通静态 Agent 的私有记忆语义保持不变。
  • 父任务进入 failed / budget-exhausted / cancelled 时,向所有非终态子实例写取消 tombstone;重复收束和恢复必须幂等,已开始或完成的 join continuation 不得被重新认领。
  • 动态实例不写 manifest,不出现在普通用户 Agent 列表;开发 Runtime 状态页可读取其状态。

Join 与结构化结果

每个 child 终态生成结构化结果:

delegationId, instanceId, templateAgentId, runId, status,
summary, artifacts[path, sha256], evidence[], verifiedRevision, error

同一 group 全部终态后,Runtime 使用 .agent/runtime/isolated-agents/join-deliveries/<groupId>.json 持久记录交付状态。父 run 仍在 planning / action 时不创建 continuation,只能通过当前已持久化 agent.run_status 工具动作的 actionId 认领 ready all-join;交付记录保存 claimedByActionId,同一 action 崩溃重试可幂等重读,同一 run 的其他 action 不再看到该 join。若父 run 在 child 尚未终态时返回空 actions,则持久进入 waiting-for-isolated-join、保存原 context cursor 并释放自身 lane,不继续请求 LLM,也不消耗后续上下文窗口;重复 resume 只读取等待状态。最后一个 child 就绪后写 deliveryTarget=parent-wake 并唤醒同一父 run / session,由模型继续调用 agent.run_status 认领,不能创建 joinRunId continuation。旧 delivery 缺少 deliveryTarget 时按 continuation 兼容;只有非活跃父任务或旧记录的兜底路径才保留固定 continuation。dispatched -> claimed-by-parent / suppressed 单向不可逆,恢复、并发 child 终态和重复状态查询都不能重新开放交付、生成 -dup-* join run 或重复调用父 LLM。

5. 真实 Provider 验收

新增 opt-in 命令:

npm run ai-game-creator-shell:agent-runtime:real-e2e -- --config-dir <AppData> --suite full

验收在系统临时目录创建带 disposable sentinel 的项目,配置和凭据始终留在仓库外。通过条件只采信持久化事实,不采信模型自述。

完整套件至少证明:

  1. 首轮拿到 repository startup context,且没有泄露敏感文件。
  2. 真实 Provider 返回合法工具计划,协议记录为 native_function 或受支持的 text_json 回退。
  3. 执行 checkpoint、读取、精确 patch/write,并在确认策略下停到 waiting-for-confirmation
  4. 精确确认后由独立 Runner 继续,App/发起 CLI 退出不影响任务。
  5. 修改后通过 project.verify,再通过 preview.validate 生成桌面和移动证据。
  6. 两个相同模板实例和一个不同模板实例真实并行,最后只产生一个 join continuation。
  7. Runner 强制终止后按原 run/session 恢复,不重复工具、消息、receipt 或最终 assistant。
  8. task/event/agent.db、revision、verification、finalization、conversation 和浏览器报告一致。
  9. 对项目、stdout、报告和 Runtime 元数据执行已加载密钥扫描,secretLeakCount=0

full 套件缺少 LLM、受支持浏览器或 External Editor API 配置时必须报告 BLOCKED,不能以 skip 计为通过。默认 CI 继续运行本地假 Provider smoke;真实套件不进入无凭据 CI。

2026-07-12 真实验收结果

使用发布 AppData 中已配置的真实 gpt-5.5 运行 llm-runtime 套件,结果为 PASS:Runner 强制终止后恢复同一 run/session;共形成 85 条 task、143 条 event、127 条 Agent DB 审计、11 条合法工具协议记录和 9 次结构化成功工具执行;4 个确认动作的 waiting / required / approved / ok 生命周期各自唯一,5 个副作用动作的新 actionId 重放为 0。项目 revision 为 1,项目验证与 1 组桌面/移动浏览器验证通过;3 个隔离实例来自 2 个模板且只形成 1 个 joincompleted 投影、最终 assistant 及其 conversation audit 均仅 1 条,重复 action/message/receipt 均为 0;已加载密钥和项目诱饵泄露均为 0;保留项目核对完成后按 disposable sentinel 清理。

同一 AppData 的 full 套件返回 BLOCKED(editorApi),原因是未配置 External Editor API。该结果属于正确的外部前置条件阻断,不记为通过,也不复用其他环境凭据。

安全与负向验收

  • repository fingerprint 测试覆盖自动 file.write / file.patch / file.delete / project.restore 在 planning 后规范漂移时全部阻断,并覆盖 .agent checkpoint / 日志 / Runtime 控制面变化不产生伪漂移。
  • 隔离测试覆盖两个同模板 instance 的私有记忆互不可见、共享记忆写入拒绝、父任务三类终态取消 children、重复 reconcile 不重开 join,以及已开始 continuation 不可被父 run 迟到认领。
  • 浏览器纯逻辑测试覆盖单视口、重复视口、无 canvas、透明 canvas 和均匀纯色 canvas 失败;显式真实 Chrome 测试同时证明桌面/移动截图有效,跨 origin HTTP redirect 与 WebSocket 目标在发送前零连接。
  • Runner 测试覆盖只读状态无副作用、锁链接 / 硬链接拒绝、跨 AppData 唯一 owner,以及缺失、截断或损坏 owner 诊断在 OS 锁后原子恢复。

V1.2 对标 Codex CLI 增量

受控命令反馈循环

单 Agent 新增 command.exec,用于补齐“复现问题 -> 读取真实 stdout / stderr -> 修改 -> 再验证”的开发闭环。该工具不是任意 shell,也不提供 PTY、后台服务或通用进程管理。这里对 PTY 和后台进程的排除只约束一次性 command.exec;V1.10 的持久进程必须使用独立的 command.start / command.poll / command.stdin / command.terminate,不能把 command.exec 偷换成长驻入口:

  • 输入固定为 program / args / cwd / timeoutSecondsprogram 只接受 Runtime 内置白名单,args 是逐项 argv,不接受 shell 字符串、重定向、管道、命令替换、环境变量或用户指定 executable 路径。
  • 首批只允许 cargocheck / test / clippy / fmt / build / metadatanpmtest / run、精确 node --test <项目内普通测试文件...>、受限只读 Git 子命令和受限 rg。npm 转发 argv 拒绝 shell 元字符和空白;Node 拒绝额外选项、glob、符号链接和 reparse pointGit 拒绝 pager、外部 diff/textconv、grep -O、pathspec 文件和 .git / .env / key / config 等敏感对象路径;rg 拒绝 follow、hidden/no-ignore、zip、preprocessor、类型覆盖和用户 glob,并在用户选项之后注入不可覆盖的敏感路径排除。每种程序继续执行参数级拒绝规则,禁止安装、发布、联网、修改 Git、切换工作区、读取项目外路径或覆盖执行环境。
  • cwd 必须是项目内规范相对目录,拒绝符号链接、绝对路径、..、Windows 盘符 / UNC / ADS 和整个 .agent 控制面;超时固定在 1-300 秒,stdin 关闭,stdout / stderr 采用有界头尾保留并先做凭据清洗。
  • 默认权限为 confirm。确认摘要包含程序、argv 摘要、cwd 和超时;精确动作继续绑定 actionId、repository fingerprint、project revision 和 execution owner。Runner 在 executing 阶段退出时保持 needs-reconciliation,不得自动重放命令。
  • 子进程继承环境清空;可执行文件必须从项目外安全绝对目录解析为绝对路径,子进程 PATH 只保留这些已规范化目录,并注入隔离 HOME / TMP / cache、离线包管理配置和不可达代理。超时或读流失败时 Runtime 请求终止受控进程组并检查终止调用结果,但这不等同于完整 detached-process / 容器隔离。首版安全等级与现有 project.verify 相同:固定程序和参数策略加用户确认,不宣称已经具备 Codex CLI 的完整 OS sandbox;在完成平台沙箱前不得把 command.exec 默认改为 auto
  • Cargo / npm 缓存固定写入项目私有 .agent/runtime/command-env/cache,不复用或改写用户宿主缓存,也不允许联网补依赖。依赖未进入项目 vendor、现有 node_modules 或隔离缓存时,命令应以真实失败输出回到 Agent;首版不为“跑通命令”复制宿主的 Cargo registry、凭据或用户级配置。
  • command.exec 的执行前后源码指纹各自最多遍历 20,000 个目录项、10,000 个受保护文件和 512 MiB 正文;执行前超预算直接拒绝启动,执行后无法完成指纹则进入 needs-reconciliation,不得把截断扫描当成完整验证凭证。
  • 命令结束后重建安全项目文件指纹。若命令改写了受保护项目文件,则保持 verification gate 未通过并要求 Agent 重新检查;每次真正启动命令前已经保守推进一次 revision。可签发验证凭证的命令仅限 cargo check/test/clippy/fmt/buildnpm test、命名为 check/typecheck/test/lint/build/verify/validate 的 npm 验证脚本及精确 node --testgitrgcargo metadata 和普通 npm run 即使退出码为 0 也只作为诊断结果。只有验证型命令退出码为 0、未超时、未改写受保护文件,且命令日志、manifest 投影和 Agent DB 审计全部成功后,才允许绑定当前 revision 的 passed gate;任一审计失败必须先保持 failed gate,再进入 needs-reconciliation

command.exec 的最小真实验收必须给 Provider 一个未注明文件路径和脚本名的失败测试项目,证明 Agent 能自行定位、运行定向命令、根据失败输出修改、经历精确确认和 Runner 恢复,再形成唯一 completed / assistant 终态。现有按固定配方执行的 Runtime E2E 继续保留,但不能替代该诊断型验收。

2026-07-12 V1.2 真实验收:发布 AppData 中配置的真实 gpt-5.5 已通过最终安全收紧后的 llm-runtime 套件。Disposable 项目先由 command.exec 真实取得失败输出,精确修复后以不同 argv 再次执行通过;Runner 强杀后恢复同一 run / session 且身份稳定。最终形成 95 条 task、161 条 event、137 条 Agent DB、13 条合法工具协议、6 套完整确认生命周期、10 次结构化成功工具执行和 7 个副作用 action;两次 command.exec 审计只保留参数数量与 SHA-256。项目 revision 为 3,3 个隔离实例来自 2 个模板且只形成 1 个 joincompleted / assistant audit 各 1 条,副作用重放、重复 action / message / receipt、已加载密钥泄露和项目诱饵泄露均为 0;桌面 / 移动浏览器证据有效,临时项目按 sentinel 自动清理。

推理档位

  • AppData 配置新增全局 llm.reasoningEffort 和可继承的 agentLlm.<agentId>.reasoningEffort,值只允许 default / low / medium / high
  • default 表示不向 Provider 发送推理档位;其余值映射到统一 LLM 请求。工具规划、普通单 Agent 聊天和最终回复必须使用同一解析后的 Agent 配置,Runtime 不再硬编码 low
  • 发布默认值使用 high,旧配置缺少字段时由默认配置补齐;非 OpenAI Responses / Chat Provider 可以选择 default,避免发送不支持的参数。

V1.3 多文件变更集与内容审查

project.patchset

单 Agent 新增结构化 project.patchset,用于替代复杂代码任务中连续多次 file.write / file.patch / file.delete 形成的半完成中间态。该工具默认 confirm,一次最多 12 个互不重复的项目内文件变更,总输入正文不超过 256 KiB,单文件修改后仍受 2 MiB 文本上限约束:

{
  "changes": [
    {
      "operation": "create",
      "path": "game/new-file.js",
      "content": "..."
    },
    {
      "operation": "update",
      "path": "game/main.js",
      "expectedSha256": "读取文件时返回的 64 位摘要",
      "oldText": "唯一旧文本",
      "newText": "新文本",
      "expectedReplacements": 1
    },
    {
      "operation": "delete",
      "path": "game/obsolete.js",
      "expectedSha256": "读取文件时返回的 64 位摘要"
    }
  ]
}
  • create 要求目标不存在;update / delete 要求目标为项目内普通文本文件且完整 SHA-256 与最近读取一致;update 还要求 oldText 精确匹配声明次数。file.read observation 必须返回当前内容 SHA-256,供模型形成乐观并发条件。
  • 所有路径、文本大小、重复路径、NFKC + Unicode 小写后的可移植碰撞、符号链接 / reparse point、硬链接、Agent 控制面、checkpoint、敏感配置、密钥和数据库路径在任何源码写入前一次性校验。任一变更无效时整个 patchset 不写源码;自动 checkpoint 和内容 diff 同样拒绝多链接普通文件,不能借项目内 inode 别名读取或改写项目外文件。
  • 预检通过后,Runtime 在同一项目写锁内自动创建 checkpoint,并先把 actionId / actionFingerprint / checkpointId / 变更摘要 写入 Agent DB prepared 审计;prepared 审计失败时不得推进 revision 或写源码。
  • prepared 成功后只推进一次 project revision,再按计划应用全部变更。中途失败时用内存中的原始内容回滚已应用项;回滚完整则返回失败但保留已推进 revisionrevision / verification gate 持久化不完整、回滚不完整或完成审计不完整都进入 needs-reconciliation。Runner 在 executing 阶段退出仍不得自动重放,checkpoint 是人工核对和恢复依据。
  • patchset 取得项目锁后必须再次校验 policy、pending action 身份、revision / verification gate 和 repository fingerprint;等待锁期间外部修改 AGENTS.md 或启动上下文时,旧动作返回 drift blocker,不进入预检、checkpoint 或 revision。
  • 成功审计只保存路径、operation、前后 SHA-256、字节数和 checkpointId,不保存源码正文。一个 patchset 无论修改多少文件都只形成一个工具 action、一个 revision 和一个结构化审计记录。

有界内容 diff

现有 project.diff 增加 includeContentmaxFilesmaxChars

  • includeContent=false 保持原有路径级摘要;true 时从指定 checkpoint 与当前项目生成统一 diff hunks,默认最多 20 个文件、24,000 字符、每个 hunk 保留 3 行上下文。
  • 内容 diff 使用成熟文本 diff 库生成;二进制、非 UTF-8、单文件超预算或总预算耗尽时只返回路径、状态、SHA-256 和明确的 truncated / binary 标记,不把截断结果描述成完整 diff。
  • 内容 diff 在项目锁内读取,并在生成 hunks 后重新计算路径级差异;前后快照不一致时整个结果失败,不得把并发混合状态标成 truncated=false
  • 输出继续排除 Agent 控制面、checkpoint、敏感配置、密钥、数据库与构建产物,并在进入 LLM observation 前统一做路径和凭据清洗。
  • 为让下一轮 planning 真正看到 hunks,最新内容 diff 不走普通 observation detail 的 1,600 字符压缩,而是在 128 KiB context bundle 内最多保留 24,256 字符并作为窗口压缩保护项;maxChars 的公开上限固定为 24,000。
  • Runtime prompt 要求 project.patchset 成功后使用其 checkpointId 调用 project.diff(includeContent=true) 审查整体变更,再执行验证型命令。真实 Provider E2E 必须证明一次 patchset 同时更新和创建文件、内容 diff 同时看到两项变更、最终验证通过且没有重复 action 或半完成文件。

2026-07-13 真实验收结果

发布 AppData 中配置的真实 gpt-5.5 已通过 V1.3 llm-runtime 套件:同一 run 先用 file.read 取得完整 SHA-256,只执行 1 次 project.patchset,同时更新 game/index.html 和创建第二个文件;prepared / completed 审计各 1 条,patchset 只推进 1 次 revision,随后用返回的 checkpointId 读取 2 项未截断内容 hunks。Runner 强制终止后恢复原 run / session,最终项目验证、桌面 / 移动浏览器验证、3 个隔离实例和唯一 join 均通过;87 条 task、144 条 event、130 条 Agent DB 记录中副作用重放、重复 action / message / receipt、半完成文件、密钥和诱饵泄露均为 0,临时项目已按 sentinel 清理。

V1.4 Git 工作树安全审阅

git.inspect

单 Agent 新增一等只读 git.inspect,用于在修改前后读取当前工作树状态和有界 unified diff,不再要求模型为常规 Git 审阅申请一次通用 command.exec 确认:

{
  "includeDiff": true,
  "maxFiles": 20,
  "maxChars": 24000
}
  • 共享 command id 为 project.git_inspect,默认权限为 auto;项目或 per-Agent policy 仍可将它改为 confirmdeny。该工具只读,不推进 project revision,不改变 verification gate。
  • 项目目录必须精确等于 Git top-level;不向父目录探测仓库,不接受 nested root、bare repository 或不可用的 worktree。
  • Git 进程使用项目外受信可执行文件、清空环境和隔离 HOME;固定关闭 system/global config、hooks、fsmonitor、pager、external diff、textconv、optional locks、签名校验、交互 prompt 和网络代理。
  • status 使用 NUL 分隔格式解析,返回 HEAD / branch、staged / unstaged / untracked 的安全相对路径。所有路径必须通过可移植路径、项目边界、普通文件和敏感路径校验;.agent、VCS 控制面、.env*、密钥、凭据、数据库、dump、依赖、构建和缓存目录不得出现在返回值或 diff 中。
  • includeDiff=true 分别对安全 staged 和 unstaged tracked 路径生成内容 diffuntracked 只列路径,不读正文。默认 20 个文件、24,000 字符,公开上限固定为 50 个文件和 24,000 字符;超出上限必须显式返回 truncated=true
  • status 和 diff 前后的安全快照不一致时整次失败,不得把并发混合状态作为完整审阅结果。最新成功 Git diff 在 context bundle 中按内容 diff 保护项最多保留 24,256 字符。
  • 本轮不实现 git add/commit/push/pull/fetch、分支切换、merge/rebase/reset/stash/clean、tag、submodule 或 worktree 操作;本地提交需要独立的 HEAD / index / 文件快照、准确确认和崩溃不重放设计,不从只读 inspect 工具顺带放开。

真实 Provider E2E 必须在 disposable Git 仓库中证明:Agent 先读取初始工作树,patchset 后读取同时包含 changed / untracked 的安全状态和 tracked content hunk,敏感诱饵路径与正文不出现在 observation、context bundle、Agent DB 或报告中,且 Git 审阅不增加 project revision。

2026-07-13 真实验收结果

发布 AppData 中配置的真实 gpt-5.5 已通过加入 Git 工作树审阅后的 llm-runtime 套件。Disposable 项目初始化为真实 Git top-level,敏感未跟踪诱饵包含 .env、App 配置、.agent 私有文件和 SQLite;主 Agent 在修改前后各执行一次 git.inspect,后置 observation 与 context bundle 同时看到 game/index.html 的 unstaged hunk、game/e2e-patchset.txt 的安全 untracked 路径,敏感路径与正文均未出现。两次 Git 审阅没有增加 project revision。

最终形成 94 条 task、156 条 event、140 条 Agent DB 记录和 11 次合法工具计划协议;12 次成功工具执行中 git.inspect=2project.patchset=1agent.spawn_isolated=1project revision 仍为 3。Runner 强制终止后恢复同一 run/session,项目验证、桌面/移动浏览器验证、3 个隔离实例和唯一 join 均通过;副作用重放、重复 action/message/receipt、半完成文件、已加载密钥和 4 类项目诱饵泄露均为 0,临时项目按 sentinel 自动清理。

V1.5 长任务关键动作账本(历史方案)

真实 Git E2E 首轮回归曾暴露长任务跨 context window 的遗忘问题:早期 agent.spawn_isolated 成功 observation 被后续读取与验证挤出窗口后,真实模型再次请求 spawn,验收以 side-effect-action-replay-detected 正确失败。V1.5 当时增加固定 6 轮窗口与 runtime.milestones 安全摘要;V1.21 已删除这套伪压缩实现,以下仅保留历史决策背景:

  • 账本汇总最近已成功完成的 agent.spawn_isolatedagent.delegatecanvas.asset_generatepreview.validateproject.patchsetproject.restoretask.create,明确提示除非任务要求重试,否则不得重复高成本或有副作用动作。
  • runtime.milestones 只携带经过路径与凭据清洗的工具名、结果摘要和有界安全 detail;它不是新事实源。精确 actionId、输入、执行状态与恢复语义仍只以 pending-action、task/event、Agent DB 和 sidecar 为准。
  • 历史账本曾在下一固定窗口合并旧账本和新里程碑,并用 runtime.context / runtime.milestones 代替部分普通 observation。
  • checkpoint 内容 diff 与 Git 工作树 diff 使用两个独立保护槽。后续 git.inspect 不得再挤掉已完成 project.diff 的 checkpointId/hunk,反之亦然;两类大 detail 仍共同受 128 KiB context bundle 总上限约束。

当时修复后的真实 gpt-5.5 回归在 10 轮内完成并收束,唯一 spawn / patchset / join 均保持 1 次,两次 Git 审阅和两类 diff 同时留在最终 context bundle,重复副作用为 0。当前 Runtime 每 6 轮只做进度 checkpoint 与停滞检测,完整 observation 继续保留在私有 bundle;真正摘要只由 V1.21 token 阈值或显式 /compact 触发,副作用去重继续以规范 action receipt 与各类 durable barrier 为准。

V1.6 持久动作回执与模型回查

  • 复用 .agent/agent.db 作为唯一长期审计源,不新增数据库或平行事实源。每个带 actionId 的已落盘终态 observation 都必须在该审计源中追加或补齐 terminal receipt,身份固定包含 agentId / taskId / sessionId / runId / actionId / actionFingerprint / tool / executionMode / status / inputSummary / summary / safeDetail / updatedAt
  • safeDetail 必须按工具类型和字段名双重白名单抽取,不能把某类工具的整段 detail 直接复制到 receipt;不得写入 file.read 读取的源码、命令完整输出、diff 正文、消息 / 记忆 / 委派正文、密钥或绝对路径。首版只保留 project.patchsetcheckpointId / revision / changeCount / revisionAdvanced 等结构化字段;历史旧记录无法安全还原 detail 时允许显式标记 detailUnavailable,不得为补齐字段重新读取或扩散敏感正文。
  • agent.action_history 不能把 Agent DB 中已有 receipt 当成已经可信的展示 DTO。读取时必须再次验证终态 status、actionId、64 位 fingerprint、executionMode、tool,并把 receipt 的 task / session 与同 run 的 task ledger 绑定;safeDetail 还要按当前工具白名单重新解析,无法通过时只返回 detailUnavailable,不得回显伪造或旧版本遗留的原始 detail。
  • 新增只读模型工具 agent.action_history,只能查询当前 Agent 的持久终态动作。输入支持 runId / actionId / tool / status / limitlimit 默认 5、上限 10,省略 runId 时只查询当前 run。结果优先使用 terminal receipt,并兼容折叠历史 terminal observation;旧记录缺少安全结构化 detail 时显式返回 detailUnavailable
  • agent.action_history 自身默认不出现在未指定 tool 过滤条件的结果中,避免模型查询动作递归污染历史;只有显式传入 tool=agent.action_history 时才允许查询它自身的 receipt。
  • 权限复用 agent.audit,默认 auto,仍可由项目或 per-Agent policy 改为 confirmdeny。该工具只读,不推进 project revision、不改变 verification gate,也不认领 join。
  • terminal receipt 写入失败时,对应 durable action 必须进入 needs-reconciliation,不得出现动作已经完成但长期历史静默缺失。恢复只能按原 actionId 幂等补齐 receipt,不能重放动作。
  • receipt 幂等复用 recordType + agentId + runId + actionId 定位,但命中旧记录后必须继续全等复核 taskId / sessionId / actionFingerprint / tool / executionMode / status 和结果摘要,任何冲突都失败关闭。普通 Agent DB append 明确拒绝 agent.runtime.action_receipt;幂等动作入口只接受字段完整、身份合法且 status 终态的 receipt,不能被任意 recordType 或非终态记录借用。Agent DB 尾部因进程强杀形成不完整 JSONL 时,只允许在追加锁内修复最后一条不完整记录;中间损坏仍失败关闭。单条 JSONL 最大 1 MiB;receipt 幂等全量扫描在文件超过 256 MiB 或完整非空记录超过 100 万条时失败关闭,不能把该阈值误解成通用 append 自动轮转上限。普通审计在约 192 MiB 或 999,936 条的任一软上限停止,同时为字节容量和记录门槛预留 64 条最大 1 MiB terminal 记录;只有 terminal receipt、带 actionId 的终态 observation / observed 和 reconciliation 能使用预留区,command-failed / verification-failed 与通用 failed 同属终态,非终态记录不得消耗预留。普通和终态追加都在同一 DB 句柄锁内真实计数,连同字节容量一起失败关闭,不做静默轮转。
  • Agent DB 的跨进程安全以已验证文件句柄为边界,不再依赖可被路径替换的普通 lock 文件。Unix 从可信目录句柄以 openat + O_NOFOLLOW 打开并校验普通文件、nlink=1,随后直接 flock DB 句柄;Windows 使用相对 NtCreateFile,拒绝 reparse point / hardlink,并以独占 share 持有句柄。每次 append、尾部补换行或截断修复都执行 flush + sync_dataUnix 新建 .agent 后同步项目根目录,新建 agent.db 后同步 .agent 目录,写入完成后再复核路径身份。同 UID 恶意进程制造的 rename / hardlink ABA 不在 v1 绝对隔离承诺内。
  • 普通历史读取使用最近 32 MiB 的有界尾窗,最多保留 16,384 个完整 JSON object,超出时返回 truncated=true;尾窗恰好落在记录边界、UTF-8 半字符或精确 1 MiB 最后一条记录时都不能丢弃合法完整记录。
  • pending action 的精确 project revision / verification gate 复核继续约束写入、命令、验证、预览证据和会认领 join 的协调动作;memory.read / conversation.read / asset.list / project.index / project.search / project.diff / git.inspect / file.list / file.read / task.list / agent.action_history 等纯读取动作在其他 Agent 推进 revision 后允许读取最新事实,并把结果作为新 observation 返回。适用仓库规范的 fingerprint gate 仍独立生效,不能借只读分类绕过规范漂移。
  • 共享项目事实读取必须使用项目一致性锁;等待锁后重新读取 durable pending sidecar,并与调用方携带的完整 pending 对象逐字段一致,再重验 policy 和 repository fingerprint。pending 被替换、迁移或损坏时失败关闭,不能继续使用锁外旧对象。agent.run_status 的 all-join claim 在同一项目锁内完成 revision / verification gate 复核与认领,避免检查通过后项目状态又发生变化。
  • 父 run 创建 joinMode=all 的隔离组后,在所有子结果终态且 ready join 已由当前父 run 的 agent.run_status action 认领前,Runtime 必须阻止最终回复和 agent.action_history,并要求继续查询状态;认领成功后才解除门禁,避免模型绕过唯一 join 提前收束或先查询不完整动作历史。
  • all-join 门禁不能只在 planning 阶段检查。最终回复取得项目锁后、创建 finalization journal 前必须再次读取持久 join 交付并确认已由当前父 run 认领;未认领时按 Stale 回到同 run planning,不写 journal、assistant 或 completed,关闭 planning 到最终提交之间的竞态窗口。
  • all-join 等待不能占用父 Agent lane 或伪装成新的 continuation。waitingGroups > 0 时父 run 保存 task / state / context / audit 后直接释放 lane;最后一个 child 在父 lane 释放前后完成的竞态由持久 parent-wake delivery 和释放后有界复核共同关闭。父 run 已恢复 planning / running 时,重复 dispatch 只确认现状,不创建 join task。
  • policy denied 和未知工具也要先落 durable observed pending,再追加 terminal receipt。terminal observation 一旦持久化,就不能在 receipt 前响应取消;receipt 成功后再结束取消流程。receipt 写入失败统一进入 needs-reconciliation,恢复仅补回执,不重放工具。
  • action 关联的 task / event 投影按 runId + actionId + phase 幂等,同一动作允许从 waiting-for-confirmation 合法推进到终态 observation,但同阶段身份冲突继续失败关闭。Agent DB 终态 observation 扫描跳过同 action 的非终态前置记录,只对既有终态做全字段复核;recentToolCalls 按 actionId 原位更新,不能让 waiting 投影遮住后续 ok / failed
  • agent.action_history 结构化 detail 上限 7,200 字符;超预算时先移除可选字段,再删除完整最旧项,禁止用字符截断破坏 JSON,禁止清空 runId / actionFingerprint。上下文清洗覆盖 Unix、Windows 盘符、正反斜杠 UNC、file:/...file:///... 和百分号编码的 file: URI,绝对路径统一替换为 <absolute-path>,同时保留普通相对文本与 HTTP(S) URL。
  • 2026-07-15 收口:后台 planning 与最终回复的每个 Provider request lifecycle 只允许一次物理请求,专用 LlmClient 无条件强制 max_retries=0,不继承全局或 per-Agent maxRetriesTimeout / Connectivity / Transport / EmptyResponse / 408 / 429 / 5xx 等歧义错误只收束当前 lifecycle,禁止自动原样重放;只有显式 steer、Goal resume 或人工 reconciliation 后的新 request slot 才能建立新 lifecycle。工具协议解析失败后的格式修复使用独立 repair slot/lifecycle,不属于传输重试。
  • 本轮只提供模型工具,不新增前端动作历史弹窗。UI 继续显示最近动作投影;后续若增加历史查看能力,必须使用点击后打开的独立弹窗,不得在当前面板下方追加内容。

2026-07-13 真实验收结果

  • Rust 测试已覆盖 receipt 折叠、组合过滤、默认值与上限边界、跨 Agent 隔离、敏感信息清洗、历史旧记录 detailUnavailable、JSONL 尾部修复与中间损坏失败关闭,以及 needs-reconciliation 恢复按原 actionId 补齐。
  • 真实 Provider 已实际调用 agent.action_history,并证明返回的 agentId / taskId / sessionId / runId / actionId.agent/agent.db identity 对齐;Runner 强制终止后恢复保持动作零重放、敏感内容零泄漏。

发布 AppData 中配置的真实 gpt-5.5 已通过最终 V1.6 llm-runtime 套件。模型实际调用 1 次 agent.action_history 并返回 1 条当前 Agent、当前 run 的历史,递归结果为 0;返回 identity 与 .agent/agent.db 全字段对齐。最终形成 94 条 task、158 条 event、164 条 Agent DB 记录、11 条合法工具协议、13 次结构化成功工具执行和 24 条 terminal receipt;主 run 含 18 条 receipt,要求覆盖的 3 类工具均有回执,重复 receipt、重复 action、重复 message、receipt identity 冲突、密钥泄漏和项目诱饵泄漏均为 0。

Runner 强制终止后恢复原 run / session 且身份稳定,project revision 为 3;项目验证、桌面 / 移动浏览器验证、3 个隔离实例和唯一 all-join 认领均通过,本次真实竞态走“活跃父 run 直接认领”路径,未创建 continuation task,真实执行顺序证明 agent.action_history 只在隔离结果被父 run 认领后发生。确定性 Rust 集成用例另覆盖 parent-wake 等待路径、多次 resume 零 LLM 请求、同父 run 唤醒和无 continuation。pending file.read 在其他 Agent 推进 revision 后仍读取最新事实;写入、命令、验证、预览和 join 认领保持严格 gate。

V1.7 模型视觉检查

机械浏览器验证只能证明页面可加载、目标文本存在、控制台无致命错误和 canvas 非空,不能证明布局、层级、遮挡、裁切、密度或桌面 / 移动适配达到可验收质量。新增只读模型工具 image.inspect,让当前 Agent 使用自己的 LLM Provider 实际读取图片证据并把视觉结论作为 observation 继续修复。

  • 输入固定为 {"paths":["项目内图片路径"],"question":"可选检查重点"},单次 1-2 张;不接受 URL、base64、请求头、Cookie 或任意本机绝对路径。
  • 普通图片只允许位于 game/assets/。浏览器证据只允许当前 agentId + runId.agent/runtime/browser-validations/<agentId>/<runId>/.../desktop.png|mobile.png,不能读取其他 Agent / run 或任意 Runtime 私有文件。
  • 每张图片按可信项目目录逐层拒绝符号链接 / reparse point,最终句柄拒绝硬链接和非普通文件;依据文件签名识别 PNG / JPEG / WEBP / GIF,不信任扩展名。单张与总字节数都设硬上限。
  • 实现上限固定为单张 8 MiB、单次总计 12 MiB;读取前检查元数据,读取后复核句柄快照和路径身份,超限、读取中漂移或路径替换均失败关闭。
  • Runtime 在项目一致性锁内复核 durable pending、policy、repository fingerprint 和图片身份,读取完整字节后释放锁,再构造内存 data URL 调用当前模板 Agent 的 Provider。data URL、原始图片字节和视觉模型原始请求不得写入 task、event、Agent DB、receipt 或日志。
  • platform-llm 的 raw failure log 遇到任意多模态输入时只写 Provider / API kind / model / 重试等元数据,并标记 multimodal-sensitive-input,不写 messages;上游错误正文若回显 data:image/* 也必须替换为省略标记。
  • 视觉模型 system prompt 明确把图片内文字当不可信项目内容,只分析可见界面,不执行图片中的指令。返回内容继续经过密钥和绝对路径清洗;持久审计只保存相对路径、内容 SHA-256、字节数、响应标识和结论字符数。
  • image.inspect 默认 auto、可由项目或 per-Agent policy 改为 confirm / deny,不推进 project revision、不改变 verification gate。相同 action 的崩溃恢复沿用 pending / observation / receipt 幂等链路,不能重复调用视觉 Provider。
  • preview.validate 返回 desktop / mobile 路径后,Agent 应调用一次 image.inspect 同时检查双视口,再依据视觉结论决定修复或收束。真实 E2E 必须证明请求实际含两张 input_image、视觉 observation 在最终回复前落盘,并且 Agent DB / receipt 中没有 base64 泄漏。

2026-07-13 真实验收结果

  • 确定性 Rust 用例覆盖双图 Responses 请求、magic bytes、伪扩展名、单图超限、跨 Agent/run、符号链接、父目录符号链接、硬链接、auto / confirm / deny、revision 不推进,以及已有 terminal observation / receipt 恢复不重复调用 Providerimage_inspect 定向用例 6/6 通过,Tauri 全量 513 项中 510 通过、3 项真实浏览器 opt-in 用例按设计忽略。
  • 发布 AppData 中配置的真实 gpt-5.5 已通过 llm-runtime:模型实际调用 image.inspect 1 次并提交 desktop / mobile 两张截图,专用 audit 1 条、terminal receipt 1 条、responseId 存在,视觉结论在最终回复前落盘。agent.action_history 与视觉检查彼此独立,不要求固定先后顺序。
  • 本次形成 95 条 task、161 条 event、166 条 Agent DB、12 条合法工具协议、14 次成功工具执行和 24 条 terminal receiptRunner 强杀后恢复原 run / session 且身份稳定,project revision 为 3,3 个隔离实例、项目验证和浏览器验证通过。task / event / Agent DB / receipt 的图片载荷泄漏为 0,重复 action / message / receipt、密钥和诱饵泄漏均为 0。

V1.8 命令完整输出分页回查

command.exec 会对 stdout / stderr 分别保留有界头尾,但普通 planning observation 只适合携带短摘要。长测试输出的根错误可能位于短摘要之外,因此新增只读模型工具 command.output_read,让当前 Agent 按行分页读取自己在当前或历史 run 中已完成命令的清洗后 transcript;不能借此读取任意日志、其他 Agent 的命令或宿主文件。

  • 输入固定为 {"actionId":"action-...","startLine":1,"maxLines":160}actionId 必填;startLine 为从 1 开始的行号,默认 1maxLines 默认 160、最大 240。返回 lines / startLine / nextLine / totalLines / hasMore / captureTruncated / outputSha256 / exitCode / timedOut / sourceChangedlines 是带稳定行号的有界字符串,空 transcript 返回空字符串和 hasMore=false
  • 每次 terminal command.exec 在命令审计完成前写入 .agent/runtime/command-outputs/<identitySha256>.json;文件名由 agentId / taskId / sessionId / runId / actionId 的稳定哈希生成,不直接使用模型字符串。sidecar 固定绑定这些身份以及 actionFingerprint / commandId,保存已经过凭据与绝对路径清洗的有界 transcript、SHA-256、总行数、stdout / stderr capture 是否截断及命令终态元数据。JSON 单文件最大 256 KiB;输出正文继续受现有 stdout / stderr 各 24 KiB 捕获上限约束,sidecar 不能扩大宿主读取面。
  • sidecar 使用现有 Runtime 私有 JSON 原子写入与受限读取边界:父目录和目标拒绝符号链接、reparse point、硬链接、非普通文件、路径替换、身份漂移、损坏 JSON 和超限内容;actionId 必须先通过稳定格式校验,不能直接成为任意路径片段。通用文件工具、仓库索引、checkpoint、diff 和 startup context 继续排除整个 .agent/runtime/**
  • command.output_read 只允许当前精确 agentId 读取属于同一 Agent 的 terminal command.exec。Runtime 先按 agentId + actionId 在 terminal receipt 中定位唯一源 run,再把 sidecar 与该 run 的 task ledger、terminal receipt / observation identity 交叉绑定,并复核 task、session、action fingerprint、tool 和终态;缺失、跨 Agent、重复冲突、未终态、旧格式或身份冲突全部失败关闭,不通过扫描目录猜测历史。
  • 工具能力名为 command-output-read,模型工具与 command id 都固定为 command.output_read,权限默认 auto,可由项目或 per-Agent policy 改为 confirm / deny。它是 durable 只读 action,不推进 project revision、不改变 verification gate、不认领 join;适用仓库规范 fingerprint 仍要复核。confirm 指纹覆盖源 actionId 与分页参数。
  • transcript 正文只进入本轮模型可见 observation 与受限 context bundle,不写入 task/event 投影、Agent DB 普通审计、terminal receipt、agent.action_history、command log 之外的新日志或最终验收报告。上述长期记录只保存源 actionId、output ref、SHA-256、总行数、页范围、截断和命令终态元数据;写入 observation 前再次执行凭据和绝对路径清洗,避免旧 sidecar 或未来清洗规则变化重新扩散敏感内容。
  • command.exec 的 terminal receipt 和专用审计增加不含正文的 outputRef / outputSha256 / totalLines / captureTruncated。sidecar 必须在命令日志、manifest、Agent DB 专用审计和 terminal observation 宣告成功前持久化;命令一旦已经启动,sidecar、后续审计或 receipt 任一步失败,都先保持当前 revision 的 failed verification gate,再把原 action 置为 needs-reconciliation,不得重新执行命令。恢复只能按原 action identity 补齐可证明幂等的投影;无法证明 sidecar 完整时保持 reconciliation。
  • command.output_read 已有 terminal observation / receipt 时,恢复只把已持久化的 context observation 交给下一轮 planning并补齐缺失 receipt,不重复读取生成另一份 observation,不执行源命令,也不调用 Provider 以外的额外副作用。分页读取允许不同 actionId 对同一源 command 读取不同页;相同 actionId 的输入或结果身份冲突继续失败关闭。
  • Runtime prompt 明确要求:短命令摘要不足以定位失败时先调用 command.output_read,按 nextLine 继续分页,找到根错误后再修改;不得仅凭输出尾部猜测。真实 Provider E2E 必须把唯一根错误放在普通 900 字符 observation 之外,并且不提供文件名、脚本名、目标字符串或工具顺序,证明 Agent 自行执行命令、分页找到错误、修改、复验和唯一收束。
  • 无配方真实运行还要求 Agent 能自行构造隔离评审:Runtime prompt 必须列出合法静态模板 taskId,并明确 expectedArtifacts 只能填写完成时必须存在的项目内相对文件或 glob,只读评审填写被检查的现有文件;writeScopes 必须是互不重叠的项目内非私有目录 glob。相同父 Agent/run 下完全相同的 spawn request 只能创建一组实例,新 actionId 重复请求必须在创建前拒绝。
  • 隔离子 Agent 已进入终态但结果构造因 expected artifact、evidence 或其他结果契约失败时,必须落一条结构化 failed child result 并参与 all-join,不能只写失败审计后让父 run 永久等待。真实 Provider E2E 的验收器只把实际成功或确实启动过的动作计为副作用;预检失败不伪装成副作用重放。可重复只读审阅不限制固定次数,省略默认参数与显式默认值视为等价,独立证据只要求都早于最终回复,不强制无业务依赖的调用顺序。

确定性测试必须覆盖分页与 1-based 边界、Unicode 行、头中尾 marker、capture truncation、二次清洗、正文零进入 task/event/Agent DB/receipt、跨 Agent/run/actionId 拒绝、auto/confirm/deny、sidecar 符号链接/硬链接/损坏/超限、命令后 sidecar 写失败进入 needs-reconciliation 且执行计数仍为 1,以及强杀恢复不重复命令或 Provider。

2026-07-13 V1.8 真实验收结果

发布 AppData 中配置的真实 gpt-5.5 已通过无固定配方的 llm-runtime 套件。任务没有提供文件名、脚本名、目标字符串、marker、actionId 或工具顺序;模型自行运行失败命令,通过持久动作记录取得真实 actionId,用 2 次 command.output_read 覆盖 248 行 transcript 并命中普通短 observation 之外的唯一根错误,随后只执行 1 次 project.patchset 完成 2 项原子变更,再完成内容 diff、修改前后 Git 审阅、失败/成功各 1 次 command.execproject.verify、双视口浏览器验证、双图视觉检查、3 个隔离 reviewer 和 patchset 历史回查。

最终形成 122 条 task、210 条 event、213 条 Agent DB、13 条合法工具协议、15 次代表性成功工具执行、6 套确认生命周期、8 个实际副作用 action、32 条 terminal receipt(主 run 23 条),project revision 为 3。命令 sidecar 和私有 context 各命中根错误,task/event/Agent DB/receipt/report 中根错误正文泄漏均为 0;副作用重放、重复 action/message/receipt、半完成文件、图片载荷、已加载密钥和项目诱饵泄漏均为 0。Runner 强杀后恢复原 run/session 且身份稳定,3 个隔离实例来自 2 个模板并形成唯一 continuation delivery,最终 completed 投影、assistant audit 和 assistant 消息均仅 1 条;保留现场核对后已按 disposable sentinel 清理。

V1.9 命令观察直接引用

V1.8 已能按 actionId 分页读取完整命令输出,但模型可见的 command.exec observation 只返回 outputRef / outputSha256 / totalLines 等元数据,真实 actionId 只存在于 pending action、task/event、Agent DB 和 terminal receipt。模型因此必须先猜 ID 或额外调用 agent.action_history,才能使用 command.output_read,与工具结果应直接携带后续调用身份的目标不符。

  • 每个 durable command.exec 的 terminal observation 必须在短 detail 前部直接返回 sourceActionId=<当前 actionId>;成功、非零退出、超时和从 observed-approved 恢复后的同一 observation 使用相同身份。该字段来自已经过 pending identity 校验的真实 action,不允许模型提供或从 outputRef 反推。
  • sourceActionId 属于安全结构化元数据,不包含命令正文、argv、凭据或路径。command event 继续省略 detailAgent DB terminal observation 和 receipt 继续使用已有顶层 actionId,不在 safeDetail 重复保存;命令 transcript 的 task/event/Agent DB/receipt 零正文边界不变。
  • 不修改 AgentRuntimeToolObservation、pending action 或 context bundle schema。身份随既有 detail 一起进入私有 context bundle,旧 bundle 保持可读;恢复已有 terminal observation 时只重新交付相同 detail,不重跑命令。
  • Runtime prompt 明确要求直接把 sourceActionId 传给 command.output_read,不得为了取得刚完成命令的 ID 先查询 agent.action_history。动作历史仍用于跨窗口或历史 run 的独立回查,不再是读取当前命令输出的前置步骤。
  • 确定性测试必须证明下一轮 planning prompt 和 context bundle 都包含精确 sourceActionId。真实 Provider E2E 必须证明第一次成功 command.output_read 发生在唯一 agent.action_history 之前,并继续满足输出正文零泄漏、动作零重放和恢复身份稳定。
  • 真实 E2E 的项目验证与浏览器验证是最后一次源码修改后的两项独立证据,不强制彼此先后;浏览器验证仍必须发生在 patchset 之后,image.inspect 必须消费其生成的双视口截图。不得用无业务依赖的固定工具顺序把模型已完成的等价闭环误判为失败。
  • agent.run_status 首次返回的 readyIsolatedJoins 代表 all-join 已由当前父 run 的精确 action 认领,其结果摘要必须进入跨 context window 的安全里程碑;后续查询返回 claimedIsolatedJoins 和稳定认领摘要,明确同一组无需再查。scope=all 的静态 Agent 列表被短 observation 截断时,也不能因此丢失动态 reviewer 的认领结果或诱发无限状态轮询。
  • context compaction 额外保护最新成功的 agent.action_history 原始 observation,不能让后续状态轮询或普通只读观察把动作回查证据挤出最终 bundle;该保护只保留已有安全结构化结果,不扩大动作历史输出上限,也不替代 terminal receipt。

2026-07-14 V1.9 真实验收结果

发布 AppData 中配置的真实 gpt-5.5 已通过无固定配方的 llm-runtime。全新 disposable run 在失败 command.exec 后没有查询动作历史,直接使用 observation 的 sourceActionId 连续执行 2 次 command.output_read,随后完成唯一 patchset、失败/成功命令各 1 次、项目验证、双视口浏览器验证、两图视觉检查、3 个隔离实例和最终 patchset 历史回查。唯一 agent.action_history 晚于命令分页,返回 1 条结果且递归结果为 0。

真实验收先后暴露并修正了两个既有收束缺口:项目验证与浏览器验证被错误要求固定先后;scope=all 的短状态截断和 context compaction 会丢失已认领 reviewer 结果并诱发重复轮询。最终 PASS 形成 146 条 task、248 条 event、255 条 Agent DB、16 条工具协议、15 次代表性成功工具执行、7 套确认生命周期、8 个实际副作用 action 和 43 条 terminal receipt(主 run 28 条),project revision 为 3。Runner 强杀后恢复原 run/session 且身份稳定;副作用重放、重复 action/message/receipt、命令正文跨边界泄漏、图片载荷、密钥和诱饵泄漏均为 0,最终 completed、assistant audit 和 assistant 消息各 1 条。

V1.10 Runner-owned 持久进程会话

V1.10 为需要持续交互的前台开发进程增加 Runner-owned PTY 会话,例如受控开发服务器或交互式测试进程。它不把 command.exec 改成长驻命令,不开放 shell,也不允许进程自行 daemonize / detach。App、WebView 和发起 CLI 都只是持久动作入口;独立 Runner 持有 PTY master、child handle、输出泵和进程终态。

身份与状态机

  • command.start 在真正 launch 前为原 durable action create-once 一个 opaque processId。该 ID 必须绑定 projectId / agentId / taskId / sessionId / runId / startActionId / actionFingerprint / commandFingerprint / runnerBootId;模型不能指定,也不能用 OS PID、端口或 cwd 反推。相同 start action 的恢复只返回同一个 processId,不同 action 不得复用。
  • OS PID / process-group id 只允许作为 Runner 私有诊断字段,不能充当 API 身份、权限凭证或恢复索引。command.poll / command.stdin / command.terminate 虽然只接收 processId,执行前仍必须从 Runner registry 和 durable record 交叉复核完整身份;知道或猜中 ID 不等于取得权限。
  • 对外状态固定为 prepared / launching / running / terminating / exited / terminated / timed-out / output-limit-exceeded / needs-reconciliation / failed,并使用独立 needsReconciliation 标志表达终态证据不完整。durable start action 必须在调用 OS spawn 前同步进入不可重放的 launching / executing 阶段;一旦已经尝试 launch,后续无法证明“尚未启动”时就只能 reconciliation,不能再次 launch。
  • Runner 内存控制面是活进程的唯一事实:registry 保存 PTY master、唯一 stdin writer 和控制通道,supervisor thread 独占 child handle、输出泵和等待任务;.agent/runtime/** 保存可恢复身份、状态和私有 transcript 元数据。durable record 不能伪装成仍持有 OS handle。

四个模型工具

command.start 输入固定为:

{
  "program": "npm",
  "args": ["run", "dev"],
  "cwd": ".",
  "timeoutSeconds": 300
}
  • program / args / cwd 复用 command.exec 的固定程序、逐项 argv、项目内 cwd、可执行文件解析、安全 PATH、隔离 HOME / TMP / cache、离线配置和参数级拒绝规则。不得新增 shell 字符串、环境变量、用户 executable 路径、管道、重定向或后台符号;已知 daemonize / detach / background 参数必须在 spawn 前拒绝。
  • Runner 直接把已解析 executable 和 argv 接到固定 120 cols x 30 rows 的 PTY,子进程 stdout / stderr 合并为 PTY 输出。模型不能指定 shell、terminal device、PTY 尺寸、环境、process group 或宿主句柄。同一项目最多 4 个、同一 Agent instance 最多 2 个 unresolved process session;容量预检同时扫描当前 registry 与 durable active / reconciliation record,存在未解决旧 boot 会话时禁止新 start。容量、参数和 detach 拒绝必须发生在 revision 推进与 OS spawn 前,不能把普通拒绝误记为 reconciliation。
  • command.start 默认 confirm,确认继续绑定 actionId、完整动作指纹、repository fingerprint、project revision、execution owner 和精确 command fingerprinttimeoutSeconds 继续使用 Runtime 硬边界,超时必须终止并落 timed-out。成功 observation 只返回 processId / status / cursor 等安全元数据;进程输出必须通过 command.poll 读取。持久进程动作永远不能签发 verification passed gate。

command.poll 输入固定为:

{
  "processId": "proc-...",
  "cursor": "v1:proc-...:0",
  "maxChars": 8000,
  "waitMs": 1000
}
  • cursor 是包含版本、processId 和 UTF-8 字节偏移的 opaque token;首次 poll 可省略,后续必须原样传回上一页 nextCursor,模型不得自行拼接。maxChars 默认 8,000、最大 16,000waitMs 最大 30,000;相同 action 和相同 cursor 的恢复必须返回相同 chunk 或明确 reconciliation,不能移动一个隐式全局游标。返回至少包含 status / output / cursor / nextCursor / hasMore / stdinOpen / exitCode / signal / outputBytes / outputSha256 / sourceChanged / needsReconciliation;未终态时 exitCode / signal 为空。
  • PTY 原始字节先按稳定规则去除危险控制序列、做 UTF-8 有损解码、凭据和绝对路径清洗,并保留清洗后逻辑行边界,再进入当前 Agent 的私有 observation / context bundle。单会话清洗后输出上限固定为 256 KiB,达到上限时必须结束进程并落 output-limit-exceeded,不能静默覆盖未读正文。
  • command.poll 是同一 owning run 内的只读 durable action,默认 auto,不推进 project revision、不改变 verification gate、不认领 join。后台输出泵必须独立观察 child 终态并排空 PTY,不能要求模型轮询才把进程记为退出。

command.stdin 输入固定为:

{
  "processId": "proc-...",
  "data": "q",
  "appendNewline": true,
  "eof": false
}
  • data 只接受 UTF-8 文本,appendNewline=true 时在哈希和写入前追加一个换行,eof=true 时写入后关闭唯一 writer;NUL / 二进制正文拒绝,单次最终 bytes 最大 8 KiB。stdin action 默认 confirm 且是不可重放副作用;写入前必须落 durable executing 标记,写入后若 observation / audit / receipt 未能完成则进入 needs-reconciliation,不得因为重试再次发送。
  • stdin 正文只允许短暂存在于执行所需的私有 pending action 和当前私有 context,终态补齐后删除 pending 正文。task、event、Agent DB、terminal receipt、activity、output、普通日志、验收报告和确认摘要只能记录 processId / bytesWritten / contentSha256 / stdinOpen / eof,禁止保存 data、前后缀、首尾字符或可逆编码。

command.terminate 输入固定为:

{
  "processId": "proc-...",
  "cursor": "v1:proc-...:254"
}
  • cursor 必须传最后一次 command.poll.nextCursor。terminate 只返回同一 cursor 的零消费状态元数据,不读取、不跳过 PTY 字符;终止后继续从该 cursor poll 尾部与可信终态。
  • command.terminate 默认 confirm。Unix 终止固定为两阶段:先向 Runner-owned child / process group 发出 graceful request 并完整等待 800 ms;随后只对组内残留执行 force kill,并等待、reap、排空 PTY。直接 child 在宽限期内退出也不能立刻跳过剩余宽限并杀掉仍在执行 graceful handler 的同组子进程。Windows 首版没有等价的可靠 graceful console event,使用 Job Object force terminate 后 wait / reap;不能把它描述成已经覆盖 Windows graceful 阶段。
  • 只有 child 已确认终态、等待任务已回收且 PTY 尾部已排空,才能写 exited / terminated terminal record。graceful、force、wait、reap 或终态审计任一步无法确认时必须进入 needs-reconciliation,不能用“已发送信号”冒充“已终止”。重复 terminate 只能幂等返回同一终态,不得按 record 中的 PID 重新发送信号。

生命周期、恢复与收束

  • App / WebView / 发起 CLI 退出、断开 endpoint 或重开窗口都不关闭 PTY;只要 owning Runner 仍存活,进程、输出泵和终态观察继续运行。App 重连后只按 processId 和 durable snapshot 查询,不接管 child handle。
  • Linux 的 PTY child wrapper 保持为同一前台进程组 leader,并监测 owning Runner parent PIDRunner 被 SIGKILL 后 wrapper 对当前进程组执行 fail-closed SIGKILL。Windows 会话在 spawn 后立即纳入 kill-on-close Job Object。Unix 正常 terminate 由 Runner 两阶段回收,Windows 由 Job force terminate;两者都必须确认 direct child reap,任何 signal / Job / wait 结果不确定都落 reconciliation,不能写可信 terminal。
  • Runner 重启只做 reconciliation。旧 runnerBootId 下已经进入 prepared / launching / running / terminating 且没有可信 terminal record 的会话统一转为 needs-reconciliation:不得重放 command.start,不得重发 stdin / terminate,也不得根据持久化 PID 重新打开、探测或接管 PTY。当前首版对旧 boot 的 prepared 也采取保守核对,不用“理论上尚未 spawn”作为自动重试依据。
  • 已有可信 terminal record 时,恢复只补齐 observation、专用审计和 receipt;不能再调用 OS 进程 API。needs-reconciliation 会话保留原 run / session / process identity 和私有证据,等待显式人工核对,不自动改成 exited、failed 或 completed。
  • owning run 存在 launching / running / terminating-* 或未解决 needs-reconciliation 会话时,最终回复、finalization journal 和 completed 投影全部失败关闭。Runtime prompt 必须要求 Agent 在收束前 poll 到终态或调用 terminate,不能用一段“服务仍在后台运行”的文字绕过门禁。
  • runner.shutdown_if_idle 必须同时检查 Runner registry 与 durable process records。存在活 handle、等待终态的输出泵、两阶段终止任务或未解决 reconciliation 时返回 busy,不得关闭 Runner;取消 run 也必须先驱动同一两阶段终止,无法确认终态时保持 reconciliation。

隔离、隐私与真实安全边界

  • processId 只能由精确 owning project + agentId + taskId + sessionId + runId 使用;同模板不同动态 instance、不同静态 Agent、不同 run 或不同项目的 poll / stdin / terminate 全部失败关闭。动态 child-* 继续按模板 Agent 解析 policy,但进程身份仍绑定 instanceId,不能访问 sibling 或模板本体的会话。
  • 运行输出正文只存在于受保护的私有 transcript sidecar、当前 owning Agent 的私有 observation 和受限 context bundle。task/event、Agent DB 普通审计、terminal receipt、agent.action_history、activity/output JSONL、UI 公共 snapshot 和验收报告只保存 cursor、字节数、SHA-256、截断、状态和退出元数据;禁止保存正文。通用文件工具、仓库索引、checkpoint、diff 和 startup context 继续排除整个 .agent/runtime/**
  • PTY 只改变输入输出和生命周期所有权,不构成 OS sandbox。V1.10 仍没有容器、mount / user / network namespace、seccomp、macOS sandbox profile 或等价 Windows restricted token / AppContainerLinux owner watchdog 与 Windows Job Object 增强的是默认同组 / 同 Job 生命周期,不能阻止被允许程序主动 setsid、创建外部 service、直接读取当前 OS 用户可读文件或绕过代理联网。实现、UI 和验收报告不得宣称具备 Codex CLI 级沙箱或对主动逃逸的完整进程树隔离。

验收门禁

确定性测试必须覆盖:固定 program / argv 和 daemonize 参数拒绝;真实 PTY 启动、增量 poll、UTF-8 / 控制序列清洗、stdin 和自然退出;同 action 恢复不重复 launch / stdin / terminateApp 客户端退出后 Runner 继续;跨 Agent / run / project 的 processId 拒绝;活会话阻断 finalization 与 shutdown_if_idlegraceful 成功和超时后 force 两条终止路径;输出上限;task/event/Agent DB/receipt/report 输出正文零泄漏和 stdin 仅 bytesWritten / contentSha256;以及 Runner 在 launch、running、stdin、两阶段 terminate 各崩溃窗口重启后只进入 reconciliation、不重放、不按 PID 重连。

真实 Provider llm-runtime 必须使用无固定工具顺序、无预置 processId 的 disposable PTY fixture,证明模型能自行 command.start、poll 到 readiness、发送唯一 stdin challenge、poll 到对应输出、terminate 并在进程终态后唯一收束;发起 App / CLI 在 start 后退出,Runner 仍完成后续会话。另设 Runner 强杀场景,以 fixture launch count 和 durable action 身份证明启动次数仍为 1,重启后没有 PID reconnect、没有最终回复且 shutdown_if_idle 保持 busy / reconciliation。验收器还必须扫描 challenge、PTY 输出 sentinel 和 stdin 正文,证明公共持久面泄漏为 0。上述确定性与真实 Provider 门禁实际通过前,不得新增 V1.10 PASS、条数统计或“已验收”结论。

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 / assistantfixture 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 条 reconciliationlaunch 仍为 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.execcommand.start 必须继续共用唯一 ProjectCommandLaunchSpecproject.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 完成。

V1.11.1 可信 launch 握手

V1.11.1 必须把 prepared -> child-created -> sandbox-ready -> commit-persisted -> exec-established -> running/exited 做成 launcher 状态机,不能再把 bwrap 进程 spawn 或 --json-status-fdchild-pid 当作 sandbox-ready。实测 child-pid 会在 --block-fd 放行前出现,此时目标程序尚未执行;它只能证明 namespace child 已创建。关闭 block writer 也不能作为 abort,因为 bwrap 会把 EOF 当作可读并继续执行,失败关闭必须显式 kill + wait/reap。

  • Linux 最终 COMMAND 必须先进入受信任 trampoline,而不是直接进入用户目标。trampoline 通过与 PTY/transcript 分离的私有控制通道发送带随机 nonce 的 SANDBOX_READY,等待 Runtime 完成 revision / verification gate / process record 的 durable commit 后接收 COMMIT_EXEC,再用 exec-error pipe 启动目标并回报 EXEC_ESTABLISHEDTARGET_EXEC_FAILED。commit 前的 EOF、错 nonce、协议错误和持久化失败都必须杀死并回收整个 bwrap 树,目标零执行。
  • command.exec 只在 SANDBOX_READY 后推进 revision 和清除旧验证凭证,EXEC_ESTABLISHED 后才启动业务 timeouttarget exec 失败发生在 durable commit 后,revision 保守保留。command.start 只在 sandbox-ready 后写 process v3 commit recordexec-established 后才注册 running 和返回 processId;快速退出仍返回同一 processId 的 terminal poll。project.verify 必须走同一 launcher,只有 exec-established 且退出码为 0 才签发 passed gate。
  • process record v3 增加 sandboxEstablishment / targetExec / launchFailureKind / sandboxReadyAt / execEstablishedAt。v2 活跃记录迁移为 unknown + needs-reconciliationcommit 前可确认 kill/reap 的失败不重放,commit 后缺少 exec-ready 的窗口统一进入 launch-unknown + needs-reconciliation
  • portable-pty 会关闭额外 FD,不能把控制协议混入 PTY 输出。Linux process child wrapper 需要唯一专用控制通道,只经该通道接收私有 launch plan 和交换 ready/commit/exec 帧;目标只继承 PTY stdin/stdout/stderr,控制 FD、nonce、child-pid、宿主路径和完整 bwrap argv不得进入目标 argv/env、transcript、command log、record、receipt 或 Agent DB。
  • 门禁必须覆盖乱序/重复/错 nonce/EOF、block 未放行目标 marker 为零、sandbox-ready 后持久化失败、目标不存在或无权限、目标立即 exit 0/7、PTY 快速退出和 Runner 强杀窗口,并扫描 /proc/self/fd、argv、env 与全部公共持久面确认控制材料泄漏为零。Windows 继续按 CreateProcess + Job 语义单独建模,不能复用或宣称 Linux 握手。

2026-07-14 第一实现切片已接入一次性命令:Linux launcher 用 --json-status-fd 取得 child-created 后才写入 --block-fd 放行,运行中 App 可执行文件通过预打开 FD 和 --ro-bind-fd 固定挂入 sandboxtrampoline 的随机 nonce 控制帧只走一次性命令原本不用的 stdin socket,真实目标重新获得 /dev/null stdin。command.execproject.verify 共用 spawn -> child-created -> sandbox-ready -> durable callback -> commit-exec -> exec-established launcherrevision / 旧验证凭证只在 sandbox-ready 后提交,业务 timeout 只在 exec-established 后开始,无效 project.verify 输入和 commit 前失败保留既有凭证。durable commit 到 exec verdict 之间不再出现 async cancellation pointcommit 后协议未知、目标/输出等待异常和命令/Agent DB/gate 审计失败统一进入 needs-reconciliation,明确的 target exec failed 则记录 established / failed / target-exec-failed 并保留已提交状态。真实 bwrap marker、目标 argv 独立 --、EOF、错 nonce、target exec 失败、并发 FD 映射、工作区隔离、命令结果与验证门禁定向测试已通过。

2026-07-14 第二实现切片已把 command.start 接入可信握手。Runner 在 portable-pty spawn 前预留 pending launch,并通过 Linux abstract Unix socket、随机 nonce 与 SO_PEERCRED 校验后的 child wrapper交换私有 launch plan和 ready/commit/exec/terminal 帧;wrapper argv 不再携带 bwrap/target planbridge FD 显式 CLOEXEC。由于 portable-pty 会关闭 fd 3 以上描述符且 bubblewrap 不可靠透传未引用 fd 3process-session trampoline 仍以 fd 0承载私有 gate,再从已验证的 PTY fd 1复制 slave作为真实 target stdintarget stdout/stderr继续继承 PTY,一次性命令仍恢复 /dev/null stdin。

process record 已升级为 v3:只在 SANDBOX_READY 后执行 revision / verification durable mutation并最后写入 launching + established/not-attempted + sandboxReadyAtEXEC_ESTABLISHED 后才写 running、注册 live session、启动 timeout和返回同一 processId 的零消费 cursor。target 不存在或无权限形成 established/failed/target-exec-failed terminal recordfast exit 0/7 继续沿同一 processId收束;commit 后未知、exec 后持久化失败和 start Agent DB 审计失败进入 reconciliation。v1/v2 active record 无条件迁移为 unknown + reconciliationlegacy terminal 和 v1/v2 transcript继续可读;pending reservation参与 shutdown、capacity和 idle/final门禁。v3 读取使用封闭状态矩阵和完整时间顺序校验,launch-unknown / start-audit-failed 必须 fail-closed 为 reconciliation;旧 boot 的 prepared / launching 及同 action start replay统一降级 target exec 为 unknown,不能通过伪造 failed record 绕过 final / idle。active/capacity/final/idle 扫描先合并 live registry 与 durable recordrecord 缺失不能让仍运行的 session 失败开放,损坏 record 仍读取失败关闭。

process-session child 在 SANDBOX_READY 后阻塞等待父侧显式 COMMIT_EXEC / ABORT_LAUNCH,不设置独立短 commit timeoutdurable mutation 超过 3 秒仍保持 target 零执行,父侧失败时显式 abort 并回收 wrapper 树。target 在 child pre-exec 内暂时屏蔽 SIGTTOU,完成 setpgid + tcsetpgrp 并恢复信号掩码后才 exec,避免目标以后台组立即读取 PTY 而停在 SIGTTIN。command.terminate 经 Runtime bridge 和 trampoline 私有控制帧只向 target group 发 SIGTERM;即使 direct leader 先退出,trampoline 仍在 800ms 宽限内等待同组后代完成清理,wrapper / bwrap 继续承载 PTY 与控制链,超时后才强杀外层 containment group。正常 EOF 写入成功后即使可信 terminal 先于状态落盘,也按成功返回而不是误标 reconciliationWindows legacy start 的 durable callback 只在同 action首次创建时执行,ready/exec/started 使用同一时间点避免跨秒倒序。

本地确定性测试已覆盖真实 PTY stdin/echo/EOF/terminate、direct leader 先退出后同组后代完成 400ms SIGTERM 清理、3.2 秒慢 durable callback、workspace sandbox后代、commit callback失败目标零执行、target exec failure、fast exit 0/7、wrong nonce/peer/乱序、v1/v2 active/terminal迁移、v3 非法组合、旧 boot launching及同 action replay、live record 缺失门禁、start Agent DB 审计失败、start cursor零消费和控制材料不进入 transcript。真实 Provider 结果必须继续由下述独立 process-session 与 Runner kill 套件证明,不能用本地用例替代。

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 / assistantRunner 强杀后 run / session 身份稳定恢复,重复、副作用重放、密钥和诱饵泄漏均为 0。保留现场独立核对 2 条 command.exec 和 1 条 project.verify 审计均为 bubblewrap / workspace-write / disabled / workspace-v1 后按 sentinel 清理。

同日追加的 process-session Provider 复验未计为通过:前三轮模型以不同 actionId / fingerprint 主动重复 start;收紧策略后的旧 E2E 又暴露 V1.10 fixture 与 V1.11 sandbox 契约冲突,fixture 在 readiness 前写 .agent、启动 namespace 内 loopback 并把 namespace PID/端口当宿主事实,而 V1.11 正确隐藏 .agent 且隔离 pid/network namespace,因此 process-transcript-interaction-evidence-missing 不能直接归因于模型抄错 challenge。修复方向是纯 PTY fixture:不写 .agent、不启动 TCP、不跨 namespace 读取 PID/端口,以唯一 process record/start/readiness、连续 cursor、stdin hash、精确 echo、stopped 和宿主项目 cwd 进程清零作为事实。最新一次重跑在零工具计划阶段连续收到 Provider 502,只记外部瞬态失败,不用于判断 Runtime。新的纯 PTY Provider 套件 PASS 前,不更新 V1.10 历史结论,也不把本次失败描述成已验收。

2026-07-14 后续真实 gpt-5.5 已在纯 PTY 与 process record v3 门禁下完成最终复验。process-session 为 PASS41 条 task、75 条 event、63 条 Agent DB、8 条 receipt,唯一 start、3 次连续 poll、唯一 stdin / terminate、3 次 cursor 推进、唯一 terminal / completed / assistantside-effect replay、重复 action / message / receipt,以及 task / event / Agent DB / receipt / conversation / activity / output / report 的私有进程正文、Provider Key 和诱饵泄漏均为 0。process-session-runner-kill 为 PASS13 条 task、19 条 event、19 条 Agent DBreadiness 后真实 SIGKILL owning Runner,项目 cwd 进程归零,新 boot 恢复同一 run / session,只形成 1 条 reconciliationreconnect / stdin / terminate / completed / assistant / replay / 泄漏均为 0;两套 disposable 项目都按 sentinel 自动清理。

真实复验同时补齐两项独立 Runner 恢复能力。Linux 在 bind(127.0.0.1:0) 因临时端口池耗尽返回 AddrInUse 时,懒读取临时范围、实际非特权起点和 reserved ranges,只从剩余 61000-65535 高位 loopback 候选选择端口;当前 32768-60999 被约 2.8 万连接占满的主机上真实选到范围外端口并完成两套测试。

新 boot 执行 runtime.resume 时,先全局拒绝指向未知 Agent 的 reconciliation record,再在每个 Agent lane 锁内主动处理所属旧 boot active process record;恢复前逐条核对 record 与 task 的 Agent、run、task 和 conversation session 身份,不同 owning run 或任一身份冲突都失败关闭。命中后按 task / state+queue / event / Agent DB 四个持久步骤逐项补齐 needs-reconciliationtask 只追加一次,state 和 queue 每次从 ledger 重建,event 与 Agent DB 绑定原 start action identity。task/event 通用 JSONL 追加和 Agent DB 专用入口都先锁内修复截断尾行;同键记录必须核对 Agent/task/session/run/process/owner boot,冲突报错而不是当成完成。任何步骤后再次崩溃都不能阻止下次 resume 补齐其余投影;重复完整 resume 不产生第二条 task、event 或 audit。整个路径禁止恢复 LLM、按 PID 重连或重放 start。

Runner-kill E2E 不再以 latest task 或单个 process record 推断整体恢复成功,而是分别要求全量 task、event、Agent DB、runtime state 和 process record 中专用 reconciliation 精确一次,并保持 reconnect 为 0。runtime state 是必需证据并加入公共正文泄漏扫描;可选 activity / output 或证据目录仅在 ENOENT 时视为空,权限、I/O 或 JSON 损坏必须直接让验收失败。

command.poll 私有正文虽然必须进入 owning Agent context 供后续交互,但模型 prompt 不是持久化隔离边界。后台 finalization 在创建 assistant journal 前检查当前 run 的成功 poll observation;只要存在非空输出,就把模型最终回复整体收束为固定安全完成摘要,再计算 response fingerprint 并写 conversation/event/Agent DB。该边界不按长度猜测 token,因此 challenge、ready/echo/stopped 行和短 PIN 的局部回显都不能扩大到公共持久面;没有私有 poll 正文的普通回复保持原样。

V1.12 受控本地 Git 提交

V1.12 首个切片补齐“修改、验证、审阅、提交”的单 Agent 本地闭环,只新增 project.git_commit。它不是通用 Git 写权限:不开放 push / fetch / pull、分支创建或切换、merge / rebase、reset、stash、tag、submodule、worktree,也不能通过 command.exec 绕过 .git 只读沙箱。

  • git.inspect 新增稳定的 commitSnapshotFingerprint。该指纹绑定当前 HEAD、附着分支、规范化后的安全 staged / unstaged / untracked 状态以及所有安全变更路径的工作树对象摘要;.agent、凭据和其它被隔离路径不进入跨动作指纹,避免 observation、context 和 pending action 的正常控制面落盘制造虚假源码漂移,但单次快照读取期间仍用完整原始 porcelain 前后复核并拒绝并发漂移。输出不泄露敏感路径或文件正文;安全工作树在读取期间漂移、路径数量或对象摘要超过上限时,不签发可提交快照。
  • project.git_commit 输入固定为 message / paths / expectedHead / expectedSnapshotFingerprint。提交信息必须是有界 UTF-8 文本;paths 最多 12 个、去重后仍须与输入一致,只接受 git.inspect 已识别的安全 unstaged / untracked / deleted 普通路径。工具执行时真实 index 必须为空,已有 staged 内容一律拒绝,不能代替用户决定或夹带其它文件。
  • 工具只支持标准仓库根和附着的本地 refs/heads/*,首版拒绝 detached HEAD、unborn branch、Git worktree 的外置 gitdir、submodule 和符号链接 / 硬链接控制路径。当前 HEAD、分支、提交快照、项目 revision、当前 run verification gate 任一与待确认动作创建时不一致,均在写 Git 前失败关闭。
  • 当前 run 必须已在当前非零项目 revision 上取得 passed 验证凭证;只修改但未验证、验证后再次修改、只审阅了用户预存脏改动或 revision 0 的工作树都不能提交。project.git_commit 本身不推进源码 revision,也不签发验证凭证;成功后 Runtime 必须重新规划,并可用 git.inspect 核对新 HEAD 和剩余未提交变更。
  • Git 写入使用独立受控实现,不调用 shell、不复用 command.exec。Runtime 隔离 system/global config、hooks、pager、fsmonitor、凭据和网络,只读取仓库本地 user.name / user.email;缺失时明确失败。提交先在临时 index 中构造精确 tree,再以真实 .git/index.lock 阻止并发 index 写,使用 commit-tree + update-ref HEAD <new> <expected old> 原子保护附着分支前移,并以固定安全消息同时维护 HEAD / branch reflog;完整提交正文不进入 reflog。最后安装与新 HEAD 对齐的 indexUnix 使用同目录原子 renameWindows 使用 replace-existing + write-through 移动;提交路径之外的工作树改动保持未暂存。
  • project.git_commit 是强制 confirm 工具:项目策略和 legacy 空策略都不能把它降为 auto,但仍可显式 deny。确认摘要展示提交标题、路径数量、有限路径列表、expected HEAD 和快照指纹前缀,不保存完整提交正文。durable action 在 Git 写入前进入 executingRunner 崩溃、ref 已前移后 index / 审计 / 终态无法确认,或无法安全清理 index lock 时统一进入 needs-reconciliation,恢复绝不重放 commit。只有能证明 ref 未更新且 index 未改变的前置校验失败才允许普通失败后重试。
  • 动态隔离 child-* Agent 无条件禁止调用 project.git_commit,即使 paths 全部位于自己的 writeScopes;子实例只交付受控产物和验证证据,最终 Git 提交统一由拥有完整项目上下文的父 Agent 发起,避免 child 把其它 Agent 或用户预存脏改动纳入提交。
  • 成功 observation 和 terminal receipt 只保存 parent / commit SHA、分支、路径数量、有限安全路径、提交信息 SHA-256 和剩余变更计数;不得保存 Git 配置值、绝对 gitdir、完整 diff、提交正文或敏感路径。已知 commit 成功但专用 Agent DB 审计失败时,needs-reconciliation observation 和 fallback terminal receipt 仍保留同一组安全字段,确保人工核对能找到 commit SHA。update-ref 失败后只有 ref 已被明确推进到非 expected、非候选 commit 时按 expected-old 竞争普通失败;ref 仍为 expected、等于候选或无法读取时都视为不确定并进入 reconciliation。确定性测试必须覆盖精确多文件提交、未选路径保留、已有 staged 拒绝、HEAD / snapshot 漂移、未验证拒绝、detached / worktree 拒绝、hook 不执行、HEAD / branch reflog、update-ref 竞争与不确定失败、child 作用域拒绝、审计 fallback receipt 和执行中恢复不重放。

2026-07-14 真实 gpt-5.5 llm-runtime 已把 V1.12 纳入完整交付链路并通过。Agent 在无路径、脚本、旧值、新值、HEAD、snapshot fingerprint 或工具顺序配方的任务中,自行完成失败命令分页定位、唯一两文件 patchset、内容 diff、三个隔离 reviewer、复验、project.verify、双视口浏览器与图片检查、动作回查、唯一 project.git_commit 和提交后 Git 复核。最终收紧版形成 151 条 task、258 条 event、266 条 Agent DB、18 条合法工具协议、17 次代表性成功工具执行、7 套确认生命周期、9 个实际副作用 action 和 44 条 terminal receipt(主 run 31 条),project revision 为 3。

Git 专项证据证明:真实 Provider 只创建 1 个提交并精确包含 2 个目标路径;原始 commit object 的消息 SHA-256、提交 parent、HEAD、tree、空 staged index、提交后所选路径状态、封闭字段专用审计、terminal receipt、HEAD reflog 与 branch reflog 全部一致,预存 disposable sentinel 继续保持未跟踪且未被夹带。Runner 在主流程早期真实强杀后恢复原 run / session 且身份稳定;副作用重放、重复 action / message / receipt、提交正文或 Git identity 公共持久化、Provider Key、敏感诱饵和报告泄漏均为 0disposable 项目按 sentinel 自动清理。V1.12 不再仅有确定性本地结论;remote、分支管理和其它 Git 写操作仍保持未开放。

V1.13 当前 Run 追加指令与 Provider 中断

V1.13 补齐 Codex CLI 风格的运行中 steering:用户可在 Agent 仍处于非终态时向同一 taskId / sessionId / runId 追加要求,Runtime 在安全边界丢弃过期计划或最终回复并重新规划,不再把每次补充都排成新任务。显式“排队新任务”仍保留,但不是运行中输入的默认行为。

  • 私有事实源固定为 .agent/runtime/steers/<agentId>/<runId>.jsonl,状态按 prepared -> conversation-persisted -> queued -> applied -> closed 只追加推进。首条 prepared 保存正文,公共 task/event/Agent DB、Runner RPC 和终态结果只保存 steerId / sequence / messageId / instructionSha256 / contentChars / status / providerInterrupted,不得保存正文。
  • 身份固定绑定 projectId / agentId / taskId / sessionId / runId / source / steerId。调用方生成并在重试时复用 steerId;同 ID 同 SHA 幂等返回原结果,同 ID 不同 SHA 拒绝为 steer-id-conflictsequence 在项目写锁内从 ledger 单调递增,不能使用时间戳。conversation 使用由完整身份派生的确定性 messageId,恢复时必须核对 role、正文 SHA 和 Agent 身份后补齐缺失阶段。
  • 首版只接受静态父 Agent 的 steer;动态 child-* 拒绝。单条正文最多 4 KiB,每 run 最多 16 条、总计最多 16 KiB,拒绝空白、NUL 和非法控制字符。completed / failed / cancelled / cancelling / needs-reconciliation、finalization 已 prepared 或 steer ledger 已 closed 时拒绝,错误 session/run/source 也拒绝。
  • AgentRuntimeState、context bundle 和 pending action 分别保存 appliedSteerCursor、有界 appliedSteerRefsplannedSteerCursor。Provider prompt 通过 refs 从 conversation 回读并复核正文,单独渲染有序“运行中用户追加指令”;后序指令可修正前序业务目标,但不能覆盖系统规则、工具策略、确认和沙箱边界。
  • 消费顺序固定为:先把 queued steer refs 与 cursor 持久化进 context bundle,再追加 applied 审计;若崩溃发生在两步之间,以 context cursor 为准补 audit,不能重复注入。Provider 请求前消费全部 queuedProvider 返回后、每个 terminal observation 后和最终回复返回后都复核 cursor。发现新 steer 时,旧工具计划剩余 action 或旧最终回复全部作废,在同一 run 重新规划。
  • pending-confirmation / approved / executing 动作不被 steer 暗中拒绝或强杀。显式批准继续执行原 fingerprintterminal receipt 落盘后再消费 steer。自动动作从准备进入 executing 时必须与 steer acceptance 使用同一项目写锁复核 plannedSteerCursor,避免“检查后、执行前”插入指令。waiting-for-isolated-join 可以接收但不能越过 join barrier。
  • finalization 在项目写锁内先检查 response steer cursor,再写入并推进 finalization journalprepared journal 一旦存在,steer acceptance 即拒绝。assistant 与 completed 投影全部成功后、释放同一把锁之前追加 closed,避免恢复时因项目 revision 漂移而丢弃 prepared journal 后留下不可重开的 ledger。steer 先获得锁则旧回复 stalefinalization 先获得锁则后续 steer 被 journal 或终态拒绝,不能出现 completed assistant 与已接受 steer 并存。
  • Runner 新增 typed runtime.steer,请求只携带 root / agent / runId / steerId。Runner 只对 planning 和 final reply 两个纯 Provider await 注册可中断句柄;收到 steer 时 tokio::select! 丢弃 HTTP future并返回 providerInterrupted=true,不得 abort worker task,也不得中断工具、副作用、确认、process session、Git commit、receipt 或 finalization。中断只表示客户端停止等待,不能承诺上游停止推理或计费。该方法把 Runner 协议提升为 v2;客户端发现旧协议进程时只请求其 shutdown_if_idle,确认 endpoint 与实例锁释放后再启动新版,旧 Runner 仍有任务时明确阻止升级而不是强杀。
  • Tauri 新增 steer_game_creator_agent_runtime_taskCLI 新增 --agent-steer <project> <agentId> <sessionId> <runId> <steerId> --stdin,正文只能从 stdin 读取。开发窗口和项目内 Agent 面板都默认对匹配的非终态 run 调用 steer,并提供显式“排队新任务”入口;cancelling 只能显示“正在取消”。

确定性验收必须覆盖 steerId 幂等与正文冲突、并发 sequence、容量限制、错误身份和终态拒绝、conversation 恰好一次、四个 ledger/context 崩溃窗口、Provider in-flight 旧计划零 action、多 action 在 action 1 后停止、确认/approved/executing 延后消费、finalization 双向竞态、Runner requestId 防重、CLI stdin 和两个前端入口。真实 Provider E2E 还必须证明 task 队列未新增、run/session 不变、最终 assistant 唯一、副作用零重放、Runner 强杀恢复身份稳定,以及正文和已加载密钥在公共持久面泄漏为 0。

2026-07-14 agent-runtime:steer-real-e2e 使用仓库外真实 Provider 配置通过 same-run 专项:一次 steer 命中 planning Provider await 并返回 providerInterrupted=truetask 仅包含原 runledger 精确形成 prepared / conversation-persisted / queued / applied / closedconversation 为 2 条 user 和 1 条 assistant,追加正文与已加载密钥在公共持久面命中均为 0。专项同时实际完成旧 Runner v1 空闲退出与 v2 替换。该套件不包含 Runner 强杀恢复,因此 V1.13 的 kill 场景仍保留为独立复验项,不借用本次 PASS 扩大结论。

V1.14 Agent 会话分叉

V1.14 对标 codex fork,允许开发者从任意已有静态 Agent 会话创建一条独立后续。分叉不是新建空白会话,也不是复制运行中的 task:新 Session 只继承分叉瞬间已经持久化的 conversation,源 Session 保持原样,之后两边的消息、run 和最终回复互不写入对方。

  • Tauri 新增 fork_game_creator_agent_session(projectPath, agentId, sourceSessionId, title);开发 Agent 窗口在会话工具栏提供分叉按钮。源 Session 可以是 active、archived 或 legacy Session,成功后新 Session 立即成为 active 并加载复制后的历史;默认标题为 分支:<源标题>,仍受 80 字符上限约束。
  • catalog 的 Session 记录新增可选 forkedFromSessionId / forkedMessageCount,旧 v1 catalog 缺字段时按 None 读取,不批量迁移。分叉生成新的不可预测 sessionId,复制前完整解析源 JSONL,保留 role、content、agentId、messageId 和原时间;不复制 Runtime state、task/event、pending action、process session、finalization journal 或 run history,也不复制 / 分裂 Agent 私有长期记忆和项目黑板。
  • 分叉前必须确认当前 active Session 与源 Session 都没有 pending、running、waiting-for-confirmation、cancelling、needs-reconciliation 或未结束委派 child。Session 新建、切换、归档、分叉和 Runtime 入队 / 启动先获取同一条 per-Agent session lane gate,再按源 conversation append lock -> Session catalog lock -> task/event 持久化的顺序推进;未显式传 sessionId 的 Runtime 必须在线性化点内解析 active Session,不能在分叉提交后把任务或用户消息写回旧 active。
  • task journal 只把 completed / failed / cancelled 且 phase 非 needs-reconciliation 视为终态;未知状态、矛盾状态、损坏 JSONL 和不可读 child journal 一律失败关闭。新 conversation 文件先以 create_new 创建并完整写入,再更新 catalog;catalog 写入失败时删除新文件,进程在文件创建后崩溃则由现有 orphan JSONL 恢复逻辑发现为恢复会话。Session list 获取 catalog lock,因此不能在 catalog 提交前把临时 JSONL 暴露为恢复会话。分叉只修改 .agent 控制面,不推进项目 revision,不伪造复制消息的 conversation audit;后续新消息和新 run 使用新 Session 身份正常审计。
  • 前端在请求成功后直接使用返回的 activeSessionId 重载会话,并展示来源和分叉消息数。运行中或 reconciliation 状态禁用分叉;归档会话保持只读但允许在 Agent lane 空闲时作为分叉源。

确定性验收必须覆盖 active / archived / legacy 源、空会话、消息与 messageId 精确复制、源与分叉后续隔离、provenance 持久化、运行中父任务和委派 child 阻断、非 active 源任务阻断、损坏 task journal 失败关闭、默认 Session Runtime 入队与分叉线性化、未提交分叉文件不可见、非法源 ID、catalog 写入失败清理以及重复点击创建不同 Session。前端测试必须证明按钮调用精确源 Session、成功后加载复制历史并切换 active、后续消息写入新 Session 且源会话不变、归档源可分叉、Runtime 忙时按钮禁用。

V1.15 Agent Swarm 纯聊天验证入口

V1.15 新增不依赖 Tauri WebView 或正常客户端 GUI 的终端聊天入口,用于开发阶段直接验证多 Agent 协作。入口固定为 --swarm-chat [--init] <本地项目绝对路径> [parentAgentId];省略 parentAgentId 时固定使用 project-supervisor,推荐通过 npm run agc:chat -- --config-dir <项目外 AppData 绝对路径> [--init] <project> 启动总控聊天。需要直接调试其他父 Agent 时仍可使用 npm run agc:swarm -- --config-dir <项目外 AppData 绝对路径> [--init] <project> <parentAgentId>。它不是新的 Agent 实现:每条普通输入都投递给现有父 Agent background Runtime,继续由同一发布二进制的 External Runner 执行;不得退化到一次性 --agent-chat,也不得新建本地 HTTP 服务、旁路 Provider 客户端或第二套持久化。

  • 首版复用父 Agent 当前 active SessionRuntime 继续把 user / assistant 写入 .agent/conversations/agents/<agentId>/sessions/<sessionId>.jsonl,静态委派、动态 child-*、私有记忆、项目黑板、durable action、verification gate 和 all-join 均沿用现有身份与恢复语义。--init 只复用现有项目初始化函数;Runtime 写命令仍强制显式传项目外 --config-dir。入口启动和一轮准备收束前都执行现有 resume / reconciliation 扫描,不能只凭 idle 快照跳过尚未发布的 receipt 或 join 修复。
  • 终端只提供聊天所需的轻量控制命令:/help/agents/status/history/quit。空闲时普通文本创建父 Agent 新 run;父 Agent run 仍处于 pending / running 时普通文本追加为同一 run steer,只有 child 忙而父 Agent 已终态时拒绝吞掉输入并要求稍后重发。确认动作在终端显示 Agent、run、action、tool 和安全摘要,并接受 approve / reject,分别调用现有 confirm / reject Runtime 路径,不能要求回到开发窗口。stdin 由独立读取线程投递,因此活跃 run 中 /quit、EOF、状态命令和 steer 仍可响应;退出只结束观察客户端。
  • 每轮轮询 read_game_creator_agent_runtimes_at,按 Agent / run / event 去重输出状态、phase、委派来源、父 Agent、delegationId、动态 child 和 join / receipt 事件。Provider token delta 当前没有经过 Runner RPC 暴露,首版只承诺 Runtime 状态与事件的持续输出以及持久化后的最终父 Agent 回复,禁止用拆字或延时打印伪装 token streaming。
  • 一轮只有在所有已发现 Runtime 都不处于 pending / running / waiting-for-confirmation / cancelling / needs-reconciliation,全部任务队列为空,并持续经过稳定观察窗口后才能收束。父 run 暂时 idle 但 delegated child 尚未终态、receipt 尚未入队或 all-join 尚未认领时不得提前返回。失败、取消和 reconciliation 要明确显示并保留项目现场,不自动重试副作用。
  • 每轮进入 settledneeds-reconciliation 终态后,终端必须额外输出且只输出一条 [turn.report] <单行 JSON>schema 固定为 game-creator-swarm-turn-report.v1。报告只从本轮 authoritative conversation 与 Runtime snapshot 计算,白名单字段至少包含 outcome、父 Agent/Session/run 身份、Runtime 忙闲数量、四类任务队列计数、新增 assistant 数量、最终回复字符数和 reconciliation Agent 数量;不得包含项目路径、对话/任务/回复正文、observation、prompt、event detail、隐藏 thinking、Provider payload、凭据或本地存储路径。该行用于开发终端和真实 E2E 定位一轮边界,不替代 task/event/delivery/claim/receipt/conversation 等持久事实;/quit 不伪造 turn report。
  • 终端退出只结束观察客户端,不终止 External Runner、已投递 run 或 Runner-owned process session;下次启动先调用现有 resume,再从 conversation 与 Runtime journal 恢复。首版只允许一个前台输入流,不承诺多个终端并发编辑同一 active Session。

确定性验收必须覆盖 CLI parse、项目绝对路径与 --config-dir 门禁、--init、空输入和 EOF、命令分流、历史恢复、连续两轮写入同一 Session、状态与事件去重、两个静态 Agent 并行委派、多个隔离 child 并行与唯一 all-join、confirm / reject、父 Agent receipt 汇总、稳定窗口不早退、Runner / 终端重启恢复以及失败与 reconciliation 显示。真实 Provider 验收必须保存一份脱敏 transcript,并以 task / event / Agent DB / receipt / conversation 的结构化事实证明并行、最终父回复唯一、副作用无重放和密钥零泄漏;未实际运行时只能标记未验收,不能凭确定性测试宣称 swarm 可用。

2026-07-14 首轮真实 gpt-5.5 验证已证明终端入口能够启动真实 External Runner、持久化父 Session、实时展示状态 / event / parent / delegation、并行运行 design-foundationbalance-seed,并在终端完成两次 agent.delegate approve、一次重复委派 reject、重启恢复、receipt 续跑、file.write reject 和活跃 run 中 /quit。独立收束复验在同一 code-prototype Session 连续完成 4 轮固定回复,重启后 /history 读取 8 条 user / assistant 消息,最后一轮按 idle -> 安静窗口 -> receipt/join 恢复扫描 -> 安静窗口 -> 最终回复 返回 FOURTH_OK。但端到端 swarm 汇总未通过:第一轮父 Agent 反复调用全量 agent.run_status,因输出截断无法看到目标 Agent,18 轮后 budget-exhausted 并压掉两条排队 receipt;第二轮按 receipt 模式续跑时,父 Agent 没有恢复原始“只读汇总”目标,转而读取项目并请求写 game/balance.json,已由终端拒绝。当前结论只能是“V1.15 验证入口可用、现有静态委派的父回执汇总策略未验收”,不得标记完整 Agent Swarm 通过;后续需修复定向状态查询或 receipt continuation 原目标恢复后再跑唯一最终父回复验收。动态 isolated child / all-join 也仍待通过该入口真实复验。

V1.16 Project Supervisor 总控 Agent

V1.16 把正式用户主聊天从一次性自然语言问答升级为现有 External Runner 中的根协调 Agent。规范 Runtime ID 固定为 project-supervisor,显示名为“项目总控 Agent”;它不是 manifest 任务、专业组角色或 isolated spawn 模板,不加入 GAME_CREATOR_AGENT_GROUP_DEFINITIONS。恢复扫描必须固定包含该 ID。LLM 首选 agentLlm.project-supervisor,发布 AppData 仍只有旧 agentLlm.chat 时把它作为兼容回退并继续继承全局配置,不复制或暴露 API Key。

  • Supervisor 使用自己的 active Agent Session 和 .agent/conversations/agents/project-supervisor/ 会话事实源,普通用户界面不提供 Session 新建、切换、归档或分叉控件。历史 .agent/conversations/project.jsonl 保持只读兼容背景,不复制成新消息、不伪造 messageId,也不作为新 Runtime 消息的第二写入目标。项目初始化、旧 slash 命令和历史生成链路仍可读取 legacy project conversationSupervisor prompt 同时读取有界 legacy 项目历史、当前 Supervisor Session、项目记忆、黑板、资产与仓库启动上下文。
  • 普通文本在 Supervisor 空闲时创建新 run;存在匹配 Session 的非终态 run 时默认走 V1.13 same-run steer。用户消息由 Runtime 入队路径在返回前写入 Supervisor Sessionassistant 只由 finalization journal 恰好一次写入;React 不再把同一轮 user / assistant 追加到 project JSONL。后台任务的 durable 入队必须在持有 Agent Session lane 时完成,但 External Runner 通知必须在释放该 lane 后发送,禁止入队方持锁等待 Runner 反向取得同一 lane。断线、刷新和 App 重启后通过 Session conversation、完整 Runtime snapshot 和 resume 恢复,Tauri event 只作刷新提示。
  • Supervisor planning prompt 必须持续携带当前用户原始目标、已委派目标、待回执集合、已认领结果和当前完成条件;它负责澄清、直接回复、读取、行动或委派,并优先把边界清晰的专业工作交给静态专业 Agent,把互不重叠的临时并行检查交给 agent.spawn_isolated。同一 Supervisor 父 run 同时处于 dispatched / ready 的静态专业 Agent 最多 3 个;第 4 个新委派在创建 child 前拒绝,但崩溃后重放同一 action 的已预留 delivery 必须复用原 target Session/run,不能被容量门禁误伤或重复计数。稳定跨 Agent 结论写项目黑板,Supervisor 私有长期协调经验写自己的 Agent memory;专业 Agent 默认不直接抢占用户主会话。
  • agent.delegate 新增 durable static delivery。delivery journal 固定绑定 parentAgentId / parentSessionId / parentRunId / parentActionId / delegationId / targetAgentId / targetSessionId / targetRunId,状态单向推进 dispatched -> ready -> claimed-by-parent / suppressed。同一工具计划中的委派动作全部提交后,只要还有 running child 或 ready 未认领回执,Runtime 必须在下一次 Provider planning 前进入 waiting-for-delegate-receipts、持久化 context cursor 并释放 lane,不能依赖模型反复调用 agent.run_status 轮询。子终态写 ready 后唤醒同一父 run;agent.run_status 只把当前父 run 的 ready receipts 放在 detail 首部,并用当前 actionId 幂等认领。该工具的 claim 身份由 delivery/claim journal 约束,不受专业 Agent 写黑板或项目文件导致的全局 project revision / repository fingerprint 漂移误伤。旧 delegate-receipt-* continuation 仅处理历史任务,V1.16 Supervisor 正常路径不得创建第二个 receipt run。
  • ready receipts 的认领使用独立 claim journal,状态为 Prepared -> Committed -> Observed。Runtime 先取得当前 parentAgentId + parentRunId + actionId 的 claim 锁,再对全部 delegationId 排序、去重并按固定顺序取得 delivery 锁;任一后续锁不可得时必须保持全部 delivery 为 ready 且不创建 claim。全部锁就绪后先写 Prepared,再把对应 delivery 绑定到当前 actionId 并写 Committed;只有 terminal observation 已持久化到 pending action 后才写 Observed。恢复扫描会补交未完成的 Prepared,未 Observed 的 claim 继续阻断 finalization。delivery / claim journal 和 pending observation 是协议事实源;.agent/agent.db 只是 best-effort 诊断投影,其追加失败不得撤销已持久化的认领或让父 run 重复消费回执。
  • executing 恢复不做通用工具重放;只有 project-supervisoragent.delegate / agent.run_status 可进入专用恢复门禁。Runtime 必须先取得项目锁,重新核对 durable pending 全对象、Session/run/action fingerprint、Runtime 状态与已有 delivery/claim/child 的全部身份;尚无 durable 副作用时还要重跑当前 policy/确认门禁,已有副作用时只按原身份补全 observation。其他 executing 动作、身份冲突或 child 存在但 delivery 缺失时进入 needs-reconciliation,不自动重放。
  • static parent-wake 以 project root + parentAgentId + parentRunId 做进程内 coalescing singleflight,最多进行 40 次有界等待;已有 worker 执行期间到达的新 wake 必须设置 rerun 标记,worker 退出与标记消费在同一 registry 锁内完成,不能丢掉最后一个 child 的 ready 信号。只有 lane 忙、暂时连接、连接中止、broken pipe、unexpected EOF、资源暂不可用或超时类错误可重试,损坏 journal、身份冲突等结构性错误立即投影为 needs-reconciliation;Runner 重启扫描遇到损坏 static barrier 也必须投影 reconciliation,不能静默保持 waiting。通知 External Runner 时,runtime.wake_pending 的 requestId 由规范项目根、method、Agent、runId 和 loop iteration 派生,同一唤醒重试必须使用稳定 requestId;只有精确目标 run 已推进或已不再需要 wake 才返回并缓存成功,目标 lane 忙、未观察到目标或仍处于 waiting 时返回不缓存的可重试错误。
  • 子终态发布前必须完整核对 parent Agent/Session/run/action、delegationId 派生、target Agent/Session/run、child source 和 child 反向 parent/delegation 链接。父任务写入 completed / failed / cancelled / budget-exhausted 终态后必须枚举并 suppress 尚未认领的匹配 delivery;这样无论 parent 与 child 谁先取得 delivery 锁,合法迟到回执都只能停在 suppressed。错配 child 不得改写或 suppress 原 delivery。executing 恢复若只有精确 delivery 预留而尚无 child,当前 policy 仍可退回确认;用户拒绝时必须在 delivery 锁内复核无 child 并把该预留 CAS 为 suppressed,不能留下永久 dispatched 屏障。finalization 在项目锁内同时复核 process session、isolated join、waiting / ready-unclaimed / unobserved-claim 三类 static delivery 障碍和 verification gate;全部清零后才由原 Supervisor Session/run 的 finalization journal 幂等写入唯一 assistant。agent.run_status(scope=all) 的有界文本列表不能作为静态回执完成协议。
  • 正式用户界面只展示 Supervisor 的紧凑状态、当前阶段、等待对象、专业 Agent 协作数量和安全待确认动作;确认/拒绝继续调用现有 Runtime action 路径。专业 Agent 的工具计划、原始 observation、内部 task/event/Agent DB、动态 child ID 和开发调试面板不进入普通用户面。External Runner 暂未向 App 传递 Provider token delta 时,只展示真实 Runtime 状态和持久化后的最终回复,不做拆字延时等伪流式输出。

确定性验收必须覆盖:Supervisor ID/config fallback/恢复扫描、独立 Session 与 legacy project history 背景、普通消息不双写、same-run steer、入队通知锁序、静态 delegate 单个与最多 3 个专业 Agent 并行/第 4 个拒绝、Provider planning 前 durable 等待、已预留委派重放与拒绝 suppression、delivery/claim 状态机、排序锁失败时零部分认领、Agent DB 失败后 journal 仍可重放、Prepared / Committed / Observed 恢复与完成门禁、executing 专用恢复与 policy 重验、parent-wake coalescing/结构性错误投影/稳定且按目标确认的 Runner requestId、父终态与迟到 child suppression、与 isolated all-join 混合、确认动作、黑板共享、同一父 run 与最终唯一 assistant,以及 Supervisor 不能作为 isolated template。Rust 定向回归使用 project_supervisor_ 前缀,并额外覆盖 agent_background_enqueue_notifies_only_after_session_lane_release;回执事实源、原子认领、未观察门禁、parent-wake、重启损坏屏障、迟到 child、Agent DB 旁路、executing 恢复与拒绝预留分别由 project_supervisor_run_status_uses_durable_claim_when_agent_db_audit_failsproject_supervisor_ready_claim_is_atomic_when_later_delivery_lock_is_busyproject_supervisor_unobserved_claim_blocks_finalization_until_observedproject_supervisor_parent_wake_is_singleflight_and_projects_structural_errorsproject_supervisor_parent_wake_singleflight_coalesces_late_signalproject_supervisor_restart_recovery_projects_delegate_barrier_errorsproject_supervisor_terminal_parent_suppresses_late_matching_child_deliveryproject_supervisor_waiting_state_survives_agent_db_audit_failureproject_supervisor_resume_replays_executing_run_status_observationproject_supervisor_resume_rechecks_delegate_policy_after_delivery_reservation 取证;Runner 定向 wake 的目标推进与不缓存重试由 runner::tests::project_supervisor_* 取证。前端定向回归覆盖主 Session 路由、same-run steer、唯一终态 assistant 与确认/拒绝。真实 Provider 验收必须从 task/event/delivery/claim/conversation 等 journal 事实与 Agent DB 诊断投影交叉证明至少两个专业 Agent 并行、原始用户目标在回执后仍存在、父 run/session 不变、只有一个面向用户最终回复、重复 action/message/receipt 为 0 且密钥零泄漏。

2026-07-14 修复后真实 Provider 验收已通过。一次性项目 /tmp/gameagent-supervisor-parallel-e2e-pass-* 中,父 run swarm-project-supervisor-1784044475952 同时创建 design-directorart-director 两个静态委派;两者均在时间戳 1784044486 进入 running,分别于 17840445061784044536 completed,存在 20 秒真实重叠。父 run 只写入 1 条 waiting-for-delegate-receipts task 记录,期间没有继续 Provider 轮询;随后同一 actionId 认领两份 delivery,两个 delivery 均为 claimed-by-parent,唯一 claim 为 Observed 且 receiptCount=2,父 run 无 reconciliation 并 completed。首轮 Supervisor Session 恰好写入 1 条 user 与 1 条 assistant;同一 Session 的第二轮“基于上文、不要重新委派”请求直接使用历史完成三句回复,delivery 总数仍为 2。项目范围精确 secret 扫描无 API Key、Bearer token 或 sk-* 命中。

V1.17 单 Agent 持久计划

V1.17 把后台单 Agent 每轮临时生成的短 plan 升级为同一 run 内可恢复、可单调更新并参与完成门禁的结构化计划。它不新增模型工具、任务系统或项目权限;计划更新仍通过既有 submit_agent_tool_plan function arguments 提交,Runtime state 与 context bundle 是持久事实源。

工具计划契约

OpenAI Chat / Responses 的 strict function schema 顶层固定为 thinkingSummary / planUpdate / plan / actions / response,其中 planUpdate 是必填但可为 null 的字段:

{
  "thinkingSummary": "已完成项目读取,开始实现",
  "planUpdate": {
    "explanation": "根据真实项目观察推进实现步骤",
    "steps": [
      { "step": "读取项目上下文", "status": "completed" },
      { "step": "实现核心玩法", "status": "in_progress" },
      { "step": "运行定向验证", "status": "pending" }
    ]
  },
  "plan": [],
  "actions": [],
  "response": ""
}
  • planUpdate.explanation 必须是非空有界文本;steps 必须包含 1 到 8 个标题互不重复的步骤,每个步骤标题也是有界文本。
  • Provider 只允许提交 pending / in_progress / completed,同一更新至多一个 in_progress。持久快照仍可读取历史已有的内部 failed 终态以兼容恢复,但它不是 Provider 可提交状态,也不能由外层 run 失败临时生成。
  • 复杂任务在首次拆解、真实进度变化、same-run steer 后重审顺序和最终收束时提交 planUpdate;没有变化时传 null。提交结构化更新时 plan 传空数组。
  • native function 的 arguments 即使本轮没有计划变化也必须显式包含 planUpdate: null;省略字段属于协议错误并进入既有格式修复或失败路径。只有兼容旧实现的文本 JSON 可以省略该字段并继续走 legacy plan fallback。
  • plan 只保留给文本 JSON 兼容协议或旧 Provider 作为 fallback。只要当前 run 已有 planRevision > 0,后续 legacy plan 不得覆盖结构化计划;同一响应同时带有两者时以 planUpdate 为准。

单调状态与完成门禁

  • AgentRuntimeState 持久化 planRevision / planExplanation / plan / planSteps / activePlanStepIndex。第一次有效结构化更新把 revision 推到 1;内容或状态真实变化时单调加一,完全相同的幂等更新不增加 revision,拒绝的更新也不改变现有快照。
  • 已进入 completed 或历史快照中已有 failed 的终态步骤必须保留。后续更新即使省略它们,Runtime 也会把终态步骤并回快照;completed 不得回退,已有 failed 不得由 Provider 改写。合并后仍受 8 步上限约束,超限整次拒绝。
  • activePlanStepIndex 只对应唯一 in_progress 步骤。结构化计划建立后,旧的“按 actions 数组下标激活、完成或重试步骤”辅助逻辑全部失效;工具成功、失败或 action 序号都不能替模型改写结构化进度,Agent 必须根据真实 observation 显式提交下一版 planUpdate
  • 只要结构化计划中仍有非 completed 步骤,空 actions、非空 response 或恢复中的 prepared finalization 都不能写 assistant、completed 或成功 final。Runtime 返回 runtime.plan_update blocker 并在同一 run 继续 planning;普通失败、取消和 reconciliation 仍可按既有失败路径收束,不能伪装成计划成功完成。
  • 外层 run 进入 failedbudget-exhausted 时,就结构化计划字段而言,必须原样保留最后一次可信的 planRevision / planExplanation / plan / planSteps / activePlanStepIndex。不得把当时的 pending / in_progress 机械改写为 failed,也不得把 run 失败反推成步骤进度事实。
  • planUpdate 是 Runtime 控制面元数据,不是白名单工具 action。更新计划不读取或改写 .agent/policy.json,不触发 confirm/deny,不推进 project revision,不改变 verification gate,也不改变 pending action fingerprint;真正的文件、命令、验证、委派和提交仍独立经过原有门禁。

恢复与 steer

  • .agent/runtime/context-bundles/<agentId>/<runId>.json schema 升级为 game-creator-runtime-context-bundle.v3,新增结构化计划 revision、说明、步骤和 active index 快照。读取 v3 时必须与当前 Runtime state 的完整计划快照一致;revision、步骤、索引或状态不匹配时失败关闭,损坏 Runtime state 投影为 needs-reconciliation,不得猜测进度或自动完成。
  • game-creator-runtime-context-bundle.v2 保持读取兼容:先完成原有身份、task、revision 和 verification gate 校验,再从当前 Runtime state 补入结构化计划字段并按 v3 继续;后续 checkpoint 写 v3。v1 以及缺失既有安全关联的旧记录仍按原规则失败关闭。
  • 最终回复 journal 升级为 game-creator-runtime-finalization.v2。它在 prepared 时绑定最终可完成的完整计划快照与 planSnapshotFingerprint,并把该指纹纳入 finalizationId;读取 v2 时还必须重新确认结构化步骤全部为 completed 且不存在 active index,不能让内部一致但未完成的篡改快照越过完成门禁。恢复不能只凭回复、task record 或 context bundle 猜测最终计划。
  • assistant 已按稳定 messageId 落入 conversation、但 Runtime state 随后缺失或不可读时,恢复可从唯一 task record 重建同一 run,再用可信的 v2 journal 恢复原 planRevision / planExplanation / plan / planSteps / activePlanStepIndex 并补齐 completed 投影,不重新请求 Provider 或重放工具。若 assistant 尚未落盘而 Runtime state 已丢失,则保留 journal 并进入 needs-reconciliation,不得仅凭 prepared journal 新写 assistant;已有 state 与 journal 计划快照冲突时同样失败关闭或丢弃过期 prepared 回复回到同 run 重规划。
  • Runner 重启、确认续跑和 stale finalization 重规划必须保持同一 Agent/task/Session/run、原 planRevision、全部终态步骤和未完成步骤;恢复不能重新从 legacy plan 派生进度,也不能因为工具回执已经存在而自动勾选步骤。
  • 同一 Provider planning 返回的所有 actions 必须绑定该请求实际渲染的 repository startup fingerprint。pending action schema 升级为 game-creator-pending-action.v4 并持久化 plannedRepositoryContextFingerprint;后续 action、用户确认和恢复都只用这份 planning 快照做 drift gate,不能从每个 action / observation 后持续刷新的 context bundle 回读。旧 v1-v3 记录缺少该身份,统一失败关闭进入核对。
  • same-run steer 继续由 V1.13 丢弃过期 Provider 计划、剩余 actions 或旧最终回复;结构化计划本身不清空。steer observation 明确要求重审未完成步骤,下一版可以调整未完成步骤的标题和顺序,但已完成或失败步骤继续保留,planRevision 继续单调递增。

展示边界

  • 开发 Agent UI、项目内开发面板和 CLI Runtime 状态输出展示有界的完整计划:revision、说明、最多 8 个步骤、每步状态、当前步骤及已有安全 detail。刷新或事件合并只可沿用同一 Agent/Session/run 的上一个快照,切换 run 时不得把旧计划带入新 run。
  • 正式用户的 Project Supervisor 聊天只展示紧凑摘要:已完成数/总数、当前步骤、等待对象、下一步和当前专业 Agent 协作数量。不得展示 planRevision、内部 explanation、完整步骤列表、原始 observation、内部 currentAction 或动态 child 身份。

公共审计与私有修复上下文

  • thinking_summary 公共 Runtime event 只写固定语义摘要以及 thinkingSummarySha256 / chars,不写模型摘要正文;legacy plan event 只写 planStepCount,不写步骤标题。结构化 plan_update 的 Agent DB 投影同样只保存 explanation 的 SHA-256 与字符数,以及步骤标题的 SHA-256、状态和数量。
  • agent.runtime.tool_plan.repair 只保存尝试次数、协议类型,以及协议错误、经过过滤的模型输出或 function call 预览的 SHA-256 与字符数;repair 中的 callId / functionName 也只写哈希。原始模型正文、解析错误、function arguments 或调用体不得进入 event、task 或 Agent DB 公共审计。
  • 为了让 Provider 修正格式,同一次 planning 的私有、瞬时 repair 请求可以携带经过统一敏感信息过滤和长度限制的上一条输出预览与协议错误。该上下文只服务当前 Provider 请求,不得反向复制到公共审计或用户可见状态。

验收口径

确定性验收至少覆盖:native function 显式 planUpdate 与文本 JSON omission 兼容;空说明、重复步骤、未知状态、超过 8 步和多个 in_progress 拒绝;幂等更新不增 revision、真实更新单调递增、终态步骤保留和 completed 回退拒绝;工具 action 下标零推进;外层 failed / budget-exhausted 保留最后可信计划;未完成计划阻止 response 与恢复 finalization;损坏 state 进入 reconciliationcontext bundle v3 快照一致性、v2 兼容和 v3 mismatch 失败关闭;finalization v2 计划指纹及 assistant 已落盘后的 state 丢失恢复;thinking / legacy plan / repair 公共审计零正文;计划元数据不推进 project revision、verification gate 或权限确认;开发 UI 刷新后仍显示完整 8 步,以及 Supervisor 只显示紧凑摘要。

恢复与 steer 专项必须在同一 run 中先完成至少一个步骤,再分别覆盖 context checkpoint 后强杀 Runner、恢复继续、Provider planning 中接受 steer、旧 actions 零执行和重排未完成步骤。恢复前后 taskId / sessionId / runId 必须不变,planRevision 不回退,终态步骤不丢失,已有副作用不重放;最后一版所有必要步骤均为 completed 后才允许唯一 assistant。

真实 Provider 验收必须使用不提供计划内容、工具顺序或状态迁移配方的 disposable 项目,让模型自行建立至少三步计划、依据真实 observation 更新至少两次、经历一次 same-run steer 和一次 Runner 重启后完成。验收器从 function call arguments、Runtime state、v3 context bundle、task/event/Agent DB、conversation 和副作用计数交叉证明 revision 单调、终态保留、未完成时零 final、最终唯一 assistant、零动作重放、计划元数据零 project revision / policy 变化以及密钥和项目绝对路径零泄漏;开发 UI/CLI 与 Supervisor 摘要另做展示断言。未实际完成这套真实 Provider 门禁前,只能记录“未验收”或外部阻塞,不能把确定性测试外推为 V1.17 PASS。

截至 2026-07-15,确定性门禁已通过:Tauri 单线程全量 690 项中 686 passed / 4 ignored,结构化计划、finalization 恢复和前端竞态定向回归全部通过。真实 gpt-5.5 llm-runtime 连续三轮均在首个 Provider planning POST 返回前因 TLS record-layer failure 进入 failed,尚未产生 function plan、工具动作、Runner kill 或 steer,因此仍未记录 V1.17 真实 Provider PASS。首轮验收器同时发现 CLI runtimeJson 暴露 sessionPath / eventPath / taskPath;CLI 输出视图移除这三个绝对存储路径后,第三轮项目绝对路径 transcript/report 泄漏计数均为 0。外部请求失败不能替代完整真实门禁,后续 Provider 恢复后必须重跑本节命令。

V1.18 单 Agent 持久 Goal mode

V1.18 对标 Codex CLI /goal 的长任务语义:目标文本既是首轮任务,也是后续完成判断的上层标准。Goal 不是 currentGoal 的展示别名,也不建立第二套 Runner;它绑定一个 Agent active Session 和同一 run,复用现有持久计划、steer、工具策略、确认、verification gate、context bundle、finalization 与 External Runner。

Goal 身份与持久化

  • 当前 Session 同时最多有一个非终态 Goal。规范记录为 game-creator-agent-goal.v1current 保存在 .agent/runtime/goals/current/<agentHash>/<sessionHash>.json,旧终态 Goal 在新建前归档到 .agent/runtime/goals/history/<agentHash>/<goalHash>.json;三个 hash 均取对应稳定身份 SHA-256 十六进制的前 32 位,路径不直接暴露 Agent、Session 或 Goal 原始标识。记录固定绑定 projectId / goalId / agentId / sessionId / runId / revision,并保存 outcome、最多 8 条 constraints、最多 8 条 verification、状态、时间和最终有界系统证据。
  • 生命周期单向为 active -> pause-requested -> paused -> active,以及 active|pause-requested|paused -> clearing -> clearedactive -> completed;身份或持久文件损坏进入 needs-reconciliation。暂停/恢复不增加 revision;只有 outcome、constraints 或 verification 真实变化时 revision 单调增加。相同 expectedRevision 与相同正文幂等,旧 revision 或不同正文冲突失败关闭。
  • AgentRuntimeState 保存 Goal 身份、revision 与状态;task journal 继续用既有 Agent/Session/run 身份与规范 Goal sidecar 交叉校验,不复制 Goal 正文或建立第二份生命周期投影。状态读取再从 Goal sidecar 补齐 outcome/constraints/verification。普通历史 Runtime 没有 Goal 字段时按非 Goal run 兼容,不能凭 currentTask 自动迁移成 Goal。

启动、编辑与运行隔离

  • /goal <文本>、Tauri start command 或 --agent-goal-start [--init] <project> <agent> <session> <run> --stdin 创建 Goal 并用同一 outcome 启动首个 background runCLI 的 --init 只在 manifest 缺失时初始化一次性/新项目,不借道其它 Agent task。未显式提供 verification 时,outcome 自身作为完成标准。Goal 活跃或暂停期间,当前 Session 禁止另起不相关 run;后续普通输入默认继续走同 run steer,独立任务应使用另一 Session。
  • 编辑 Goal 先在项目写锁内提交 revision,再把规范化的新目标作为同 run steer 持久化。Provider 正在 planning 时允许中断;确认中或工具执行中只排队,旧动作在下一安全边界前必须校验 Goal revision,不能在目标已变更后继续执行。旧自动动作或待确认动作若绑定旧 Goal 快照,统一转成 blocked observation 并在同一 run 重规划,不执行旧副作用,也不创建 retry run。编辑失败不得回退已提交 revisionRuntime 会以 sidecar 为事实源重规划并拒绝旧 finalization。
  • Goal 内容进入每轮 planning/final reply 的显式“持久目标”上下文。模型仍通过 V1.17 planUpdate 维护可观察步骤;Goal revision 不推进 project revision、不改变权限或 verification gate,也不能放宽 sandbox/approval。

暂停、恢复与清理

  • pause 写 durable request,并通过 typed Runner runtime.pause 中断当前 planning/final Provider;已进入工具的动作允许返回后再停。Provider 注册、durable Goal control/cancel 二次复核与 started 审计使用同一项目写锁形成线性化边界:锁内同时核对 cancel tombstone、queued steer、Goal 状态和 task 绑定的 Goal revisionedit 已提交新 revision 但 steer 尚未落盘时也不得轮询旧 Provider 或写伪 started;请求先提交时才属于可中断或等待安全边界的在途调用。Provider 中断或返回边界先把可恢复 continuation 写入当前 v5 context bundleV1.18 初版为 v4,V1.21 增加压缩状态后升级),其中恢复快照按 active Goal 语义保存,随后 Runtime 才在 LLM/工具/observation/finalization 安全边界把同一 run 收束为 paused。Runner 重启时先处理 cancel / Goal control,再进入 process reconciliation、finalization 和 pending actionpause-requested 会先收束成 pausedpaused 直接保持休眠,不生成 assistant、不创建新 run、不调用 Provider。
  • 暂停父 Agent 不撤销已经 durable 投递的专业 childchild 可以把结果写成 ready,但父 run 在显式 resume 前不能认领或继续 Provider。Runner-owned process session 在暂停提交前终止,恢复后由 Agent 根据 observation 重规划,禁止按 PID 重连或重放未知 start。
  • resume 的有效状态迁移只接受 paused -> active,先清理同一 run 遗留的 cancel tombstone,再把原 Agent/Session/run 重新投影为 pending 并唤醒 External Runner;不创建 retry run。若进程在 Goal sidecar 已写成 active、Runtime 投影或 Runner 唤醒尚未完成时失败,重复 resume 必须识别同一 run 的半提交并继续补齐,不能把 active 单独当成恢复成功或直接返回。pending confirmation 仍回到确认态,普通 planning 从当前 v5 context bundle 继续。clear 对活跃 Goal 复用取消 tombstone,待安全取消后把 Goal 写为 clearedpaused/completed Goal 可直接清理。clear 不删除历史 conversation、task、event 或 Goal history。

恢复与完成门禁

  • V1.18 首次把 context bundle 升级为 v4 并绑定 goalId / goalRevision / goalStatus / goalSnapshotFingerprint;当前生产 schema 已由 V1.21 扩展为 game-creator-runtime-context-bundle.v5。v4 在原 Goal/计划/verification 身份通过后补入当前压缩字段并写回 v5,v3 先补 Goal,v2 继续先按 V1.17 迁移计划再补 Goal;任一当前 Goal 身份、revision 或快照不一致都失败关闭。当前 Agent/Session/run 的 Goal sidecar 无法读取、损坏或身份冲突时,即使 legacy/半写 Runtime 尚无 goalId 投影也必须进入 needs-reconciliation,不得退化成无 Goal run 或绕过完成门禁。
  • pending action 升级为 game-creator-pending-action.v5,在既有 project revision、verification gate、repository context fingerprint 和 steer cursor 外,固定绑定 goalId / goalRevision / goalSnapshotFingerprint。旧 v1-v4 一律失败关闭,不能从当前 Goal 猜回缺失绑定;Goal edit 后,无论动作原为自动还是待确认,都把旧记录收束成稳定 blocked observation 并在同一 run 重规划。
  • finalization journal 升级为 game-creator-runtime-finalization.v3,把 Goal 快照指纹纳入 finalizationId。prepared 回复必须绑定当前 active Goal、同一 run/revision、全部完成的结构化计划、清空的 process/join/delegate 屏障和现有 verification gate。Goal 编辑、暂停、清理或 revision 漂移会让未提交 assistant 的旧 finalization 失效并回到同 runassistant 已提交后只允许按 journal 原快照补齐 Runtime 与 Goal completed,不能重新请求 Provider。
  • assistant 持久化后,finalization 先写 Runtime completed task/state,再把规范 Goal 写为 completed,并补写携带 completed Goal 状态的 task/state projection;两层投影均可靠后,journal 才推进 runtime-completed 并删除。完成证据由系统从最终结构化计划、verification gate、run/session 身份和 response fingerprint 生成,不保存模型 thinking 或原始私有 observation。Goal 未完成、paused、clearing、sidecar 缺失或 revision 不匹配时,response 不能绕过完成门禁。
  • finalization 以同一 finalizationId / messageId 在 Agent DB 追加四条 agent.runtime.finalization.lifecycleprepared 在 prepared journal 后,assistant-persisted 在会话及其审计和 journal 状态后,runtime-completed 在首个 Runtime completed task/state 后且 Goal 完成前,goal-completed 在规范 Goal 与第二个 completed task/state 均可靠后。四阶段字段闭集固定为 recordType / auditSchemaVersion / journalSchemaVersion / agentId / taskId / sessionId / runId / source / finalizationId / messageId / stage / stageOrdinal / previousStage / goalId / goalRevision / goalSnapshotFingerprint / planRevision / planSnapshotFingerprint / responseFingerprint / responseChars / conversationPath / stageAt,持久层只可再添加统一 schemaVersion / updatedAt envelope;不得携带 task、response、Goal、observation、error 或其它额外字段。
  • finalization-critical 物理顺序严格固定为七槽:lifecycle/prepared -> conversation.message assistant 审计 -> lifecycle/assistant-persisted -> lifecycle/runtime-completed -> lifecycle/goal-completed -> agent.runtime.completed -> agent.runtime.background_task.completed。assistant 审计字段闭集只允许 recordType / agentId / sessionId / role / path / messageId / finalizationId,两条 completed 审计只允许 recordType / agentId / taskId / sessionId / runId / source / finalizationId / messageId / responseFingerprint / responseChars,并只允许同一持久 envelope。prepared 成功时必须在独立的 128 条 lifecycle/finalization reserve 中同时预留后六条的记录数和最大字节容量,七条都不得占用 64 条 action receipt/reconciliation reserve;容量不足时 prepared 自身失败关闭。容量扫描和幂等检查都在 Agent DB 追加锁内读取完整受支持文件,不依赖 32 MiB recent tail,并对 finalizationId / messageId / Agent / task / Session / run / source / Goal/plan 快照 / responseFingerprint / responseChars / conversationPath、stage ordinal/previousStage 和 JSONL 物理顺序做精确匹配。缺前序、倒序、重复、身份冲突、额外生产字段或 reservation 无法兑现都失败关闭;严格七槽未全部齐全时不得删除 journal。prepared journal 已写入但首条 lifecycle 暂时失败时,run 保持可恢复 finalizing,不得被外层改判普通 failed;恢复只补同一七槽,不重放 Provider 或 assistant。

控制面与验收

  • 纯聊天入口支持 /goal <文本>/goal status/goal pause/goal resume/goal edit <文本>/goal clear;开发 Agent UI 使用 执行 / 聊天 / 目标 三段模式,Goal 创建/编辑通过独立弹层提交,并在状态行显示 outcome、revision、状态与完成标准,提供暂停/恢复/清理。普通用户 Supervisor 首页不暴露开发 Goal 管理控件。
  • background planning / final reply 的专用 Provider 客户端强制 max_retries=0;每个 agent.runtime.provider_request.lifecyclestarted 到唯一 completed / failed / interrupted 最多对应一次物理请求。Timeout / Connectivity / Transport / EmptyResponse / 408 / 429 / 5xx 以及无法证明请求未被上游接收的其它错误,不得在同一 lifecycle 内自动原样重放;只记录 error kind、SHA-256、字符数或脱敏摘要。显式 steer、Goal resume 或人工 reconciliation 决定再次调用时,必须使用新的 request slot/lifecycle;格式修复同样使用 loop-<n>-repair-<m> 新 slot,不能伪装成底层 retry。
  • 每次 request snapshot 固定绑定 projectId / agentId / taskId / sessionId / runId / source / goalId / goalRevision / goalSnapshotFingerprint / appliedSteerCursor / requestKind / requestSlot,requestId 从该闭集稳定派生。真正进入 Provider future 前,Runtime 在同一项目写锁内重读 task/Runtime 身份、queued steer、cancel tombstone、规范 Goal 状态与快照;已生效控制只返回未启动,不得写伪 started。Provider lifecycle 的生产字段闭集只允许 recordType / auditSchemaVersion / agentId / taskId / sessionId / runId / source / requestId / requestKind / requestSlot / status,持久层只可再添加统一 schemaVersion / updatedAt envelope;不包含 prompt、工具输入、URL、模型、回复或错误正文。
  • 启动新请求前必须在 Agent DB 锁内全量扫描同 Agent/run 的 Provider lifecycle,不依赖 recent tail。只要发现 started 后没有可信唯一终态,就把原 run/task/state 收束到 needs-reconciliation orphan barrier,阻断后续 Provider、工具和 finalization;同 request 多终态、缺 started、物理顺序倒置、重复阶段、身份/字段冲突或额外生产字段同样失败关闭,禁止自动补发。paused Runner 重启窗口必须以 started 数量零增长证明没有暗中请求,不能只看 plan/action 是否落盘。
  • 确定性验收覆盖:单 Session 单 Goal、跨 Agent/Session 隔离、expectedRevision 幂等/冲突、活跃 Goal 阻止新 run、Provider in-flight pause、工具返回后 pause、paused 重启不自启、同 run resume、pending confirmation 恢复、编辑触发 steer 与旧动作失效、clear/cancel 竞态、v5/v4/v3/v2 恢复、v3 finalization、assistant 后崩溃补齐 completed,以及 Goal 元数据零 project revision/policy 变化。
  • 真实 Provider 使用现有 agent-runtime-real-e2e.mjs 的独立 goal-runtime suite 和一次性项目证明,不新增平行验收器。suite 只要求 AppData 中 code-prototype 的真实 LLM 配置,不要求 Chrome 或 External Editor API。revision 1 必须先形成至少三步、已有 completed 且仍有未完成步骤的计划,并停在一个绑定 Goal revision 1 的 game-creator-pending-action.v5 写动作;编辑到 revision 2 后,该旧动作必须形成 runtime.goal / blocked observation 且旧标记从未落盘,同一 run 再形成绑定 revision 2 的 v5 写动作。
  • goal-runtime 不复用正在运行的正式 AppData Runner。验收器在用户提供的 AppData 下创建 0700 专用子目录和带随机 owner token/PID/时间的 sentinel;主配置与可选 local 配置只以普通文件 hardlink 复用,结束时复核 source/link 的 device、inode 与 SHA-256,全程不复制或输出 API Key。所有 Goal/Runner CLI 统一附加该专用 runtimeConfigDir。SIGKILL 前必须同时核对 sentinel、endpoint、Runner boot/PID/port、实际 CLI 路径、--agent-runner --config-dir argv 和 OS 启动指纹;endpoint 在已认领后异常消失时,只允许按先前同一启动指纹回收。成功或失败都先停止自有 Runner,再按 sentinel 和受限目录前缀删除专用 AppData;身份不一致时保留现场并失败,禁止猜测或清理其它 Runner。
  • revision 2 验证 fixture 只在 revision 1 待确认动作与隔离证明完成后注入,并先由宿主真实执行一次失败命令形成不可伪造的失败边界。失败报告对 task、event、Agent DB 和 conversation 分面容错读取,截断尾行保留已完成 JSONL 记录并单独报告读取错误;不得把某一分面损坏折算成其它分面全为零。
  • revision 2 写动作待确认时执行 pause;命令返回、Goal status 与 Runtime state 都必须是 durable paused。随后记录 Goal、game-creator-runtime-context-bundle.v5、pending v5、计划、task/event/Agent DB、conversation 和副作用计数,SIGKILL Runner 并使用全局 --agent-resume 启动新 boot;至少两个稳定采样窗口内上述运行证据不得推进,不得新增 Provider plan、工具执行、assistant 或主 run。只有显式 --agent-goal-resume 后才允许确认 revision 2 动作并继续。
  • 最终 Goal、Runtime 和最新 task 必须在原 Agent/Session/run 上 completed,结构化计划全部完成,Goal completion evidence 必须精确匹配当前 Goal/plan/verification/run/session;同一 finalizationId 必须按严格七槽物理顺序形成完整记录,finalization sidecar 最终不残留,目标 Session 只允许一个 assistant。Goal sidecar、task JSONL、Runtime state、v5 context 和 conversation 属于本地私有执行事实,可包含完成目标所需正文;event、Agent DB、receipt、activity、output 与最终报告不得保存 task、Goal/steer、委派任务、verify 命令或 error 正文,只允许身份/状态、SHA-256、字符/字节/条目计数和经 URL、项目根、其它绝对路径及凭据清洗的有界摘要。公共 task 统一不保留正文;委派只保留 taskSha256 / taskCharsverify 只保留脚本安全标识、expectedCommandSha256 / expectedCommandChars、timeout 和结果计数,error 只保留 kind/fingerprint/chars 或脱敏摘要,禁止任何正文、preview、head 或 tail。验收必须扫描完整 Goal/编辑/委派/verify/error canary、已加载密钥和一次性项目绝对路径在全部公共持久面泄漏为 0,并确认动作、消息、receipt 和 Provider lifecycle 均无重复。
  • 2026-07-16 使用正式 AppData 的 openai_chat / gpt-5.5 路由执行隔离 goal-runtime suiteV1.18 真实 Provider 门禁 PASS。同一 Agent/Session/run 从 Goal revision 1 编辑到 revision 2,保留 1 个已完成计划步骤;旧写动作形成 1 条 runtime.goal / blocked receipt,执行与重放均为 0。Agent 先取得真实退出码 1,再用 1 个 patchset 修复并通过 revision 2 verification;暂停前后、Runner pidfd 强杀换 boot 后的稳定窗口中 task/plan/conversation/Provider/action 均零推进,显式 resume 后恢复原 execution owner 和原 run。最终代码快照复跑的计划 revision 11 的 8 步全部完成,11 组 Provider lifecycle 均唯一闭合,finalization v3 四阶段和两层 completed projection 完整,Session 只有 1 条 assistant3 个副作用无重放,重复 action/message/receipt、Goal 正文、失败证据 canary、API Key、诱饵和项目绝对路径公共泄漏均为 0。验收过程同时修正 file.write 静默裁剪末尾换行、旧 Goal action receipt 的合法 tool/摘要转换、file/project diff 正文进入公共 event、file/memory 审计保存绝对路径,以及旧 event detail 在新脱敏投影下被误判幂等冲突五类真实缺陷;隔离 Runner、AppData 和 disposable 项目均已按 sentinel 清理。

2026-07-16 在 V1.26 Provider 原生工具目录落地后再次执行加强版 goal-runtime,正式 openai_chat / gpt-5.5 路由 PASS。验收器现在强制成功计划与格式 repair 全部使用 native_runtime_tools,拒绝 wrapper/text fallback,逐条校验 function call 数量、call id 唯一性、函数名数组,并拒绝协议审计携带 arguments、response 或 toolArguments 正文;失败报告也输出同一组协议计数。最终复跑的成功计划 21/21、repair 17/17 均为原生目录,fallback 与协议审计 payload 为 0;同一 Goal revision 1 -> 2、旧动作 blocked、真实退出码 1、单 patchset 修复、pause、Runner pidfd 强杀、paused 零推进、显式同 run resume、计划 revision 11 的 6 步完成、verification、finalization v3 四阶段、两层 completed projection 和唯一 assistant 全部成立,3 个副作用无重放,重复与正文/Key/诱饵/路径泄漏为 0,隔离资源完整清理。另一次独立复跑在 revision 2 repair lifecycle 遇到上游 transport failureRuntime 正确失败且 6/6 成功计划、5/5 repair 仍全为原生目录;Goal 专用长等待现会同步检查 task/runtime 终态,在 failed 或 needs-reconciliation 时立即返回结构化失败,不再空等 30 分钟总超时。

V1.19 后台 Agent 真流式最终回复

V1.19 对标 Codex 富客户端的增量 turn 事件:工具开始、完成和等待继续沿用现有 Runtime state/event;只有已经进入 phase=response 的用户可见最终回复允许输出 Provider 文本 delta。后台工具 planning、function arguments、thinkingSummary、原始 observation 和修复上下文不得进入流。禁止前端拆字、定时补字或先生成完整正文再伪装流式。

流身份与私有快照

  • 新增 game-creator-runtime-response-stream.v1 私有快照,路径固定为 .agent/runtime/response-streams/<agentHash>/<runHash>.json,两个 hash 都取稳定身份 SHA-256 十六进制前 32 位。记录绑定 agentId / taskId / sessionId / runId / requestKind=final-reply / requestSlot / appliedSteerCursor / responseRevision,并保存单调 sequencestatus=streaming|ready|committed|discarded|failedaccumulatedText、可选 finishReason 和时间。正文最多 32000 字符;路径、标识、schema、状态、sequence 和正文限制任一不合法时只关闭该展示流,不能把不可信内容显示给用户或据此恢复 Runtime。
  • 流快照是可丢失的本地展示缓存,不是 assistant、Provider lifecycle、任务完成或 finalization 的事实源。写入采用同路径原子替换并允许节流;Tauri 关闭、CLI 断线或单次快照写失败不能让已经可靠完成的 Provider 请求失败。AgentRuntimeResult.responseStream 只在快照与当前 Runtime 的 Agent/Session/run、phase=response|finalizing|completed、steer cursor 和请求身份一致时返回。
  • 开始新的 final-reply request slot 时先写空 streaming 快照。SSE delta 只在经过增量 <think>...</think> 过滤后追加;标记可跨 chunk,未闭合 thinking 永不外显。sequence 只随公开 accumulated text 或 finish reason 的真实变化增加。Provider 完整返回后用最终 strip_llm_thinking_blocks 结果校准为 ready,确保草稿与最终候选一致。

Provider、控制与 finalization 边界

  • 后台 Agent 继续严格服从 agentLlm.<agent>.stream:为 true 时即使 planning 已带候选 response,也必须进入独立 final-reply lifecycle,并由该 lifecycle 的唯一物理请求使用 LlmClient::stream_run;planning 候选只在这次请求失败时作为 fallback。为 false 时可直接采用完整 planning response;只有 planning 未带 response 而确需独立 final-reply lifecycle 时才使用一次 run,并在完整结果后写一次 ready。流式协议失败不得在同一 Provider lifecycle 内静默补发普通请求;V1.18 的单物理请求、request slot、orphan barrier、pause/steer interrupt 和显式恢复新 lifecycle 约束保持不变。
  • same-run steer、Goal edit/pause、取消、stale revision、Provider 失败或 reconciliation 都必须让旧快照进入 discarded|failed,或因 steer cursor/phase 不匹配而立即不可见。旧草稿不能成为 observation、fallback response、conversation message、Goal completion evidence 或下一轮模型上下文。
  • 完整候选仍必须通过 verification、plan、Goal、process/join/delegate 和项目 revision 门禁。finish_game_creator_agent_background_runtime_turn_at 仍是唯一 finalization 入口;只有 assistant 已按稳定 messageId 恰好一次写入并完成 Runtime 投影后,快照才可标记 committed。失败消息和 plan.response fallback 必须覆盖为其实际候选,不能保留不同 Provider 草稿。
  • 公共 event、Agent DB、receipt、activity/output 和报告不得复制 delta 或 accumulated text,只记录流身份、状态、sequence、字符数和 SHA-256。conversation、finalization、Runtime task/state 和 response-stream 都是本地私有事实面,可保存 canonical 最终正文;其中 response-stream 只是可丢失候选缓存,且不得保存 API Key、请求头、URL、模型 thinking、工具计划或原始 Provider error。

客户端与 CLI

  • 普通 Project Supervisor 聊天把匹配的 streaming|ready 快照渲染成一条 runtimeOwned 临时 assistant 消息;刷新、窗口重开和 Tauri event 丢失时由现有 750ms Runtime 轮询恢复。committed 后以 conversation 中的规范 assistant 替换草稿,不把临时消息写回 legacy project conversation 或 Agent Session。
  • agc:chat / agc:swarm 按 accumulated text 前缀增量打印 UTF-8 suffix;新 request slot、非前缀校准或 reconnect 要明确重置。已经完整流出的父回复在 settle 时只补完成换行/状态,不再整段重复打印。/status 只显示流状态、sequence 和字符数,不显示隐藏 planning 或 thinking。

验收口径

  • 确定性测试覆盖 Chat / Responses SSE 至少两个真实 delta、chunk 边界 thinking 过滤、sequence 单调、32K 上限、损坏/错身份快照不显示、Tauri 轮询恢复、CLI suffix/reconnect/非前缀重置、steer/取消/失败旧流失效、非流配置单次 ready、finalization 后唯一 assistant 与 committed 精确一致,以及公共持久面零正文。
  • 真实 Provider 使用一次性项目和独立 AppData,把目标 Agent 的 stream=true,证明首次公开 delta 发生在 Provider/finalization 终态之前、至少两个非空增量可观察、最终 conversation assistant 与 ready/committed 全文一致、同一 lifecycle 不发生应用层重试,并扫描密钥、thinking canary、项目绝对路径和 delta 正文在 event、Agent DB、receipt、activity/output 与报告等公共面泄漏为 0。上游物理请求数无法直接观测时,必须明确记录证明模式,不能把 lifecycle 计数冒充网络请求计数。
  • 2026-07-15 真实 gpt-5.5 response-stream suite 已 PASS:隔离 AppData 只以 hardlink 读取正式配置并使用无密钥 stream=true overlay,正式配置 CLI 调用为 0、源 Runner endpoint 未变化。39 个不同非空 streaming 快照先于终态,sequence 从 1 单调推进到 418,最终以 425 committedcanonical 正文 883 字,conversation 恰好 1 条 user 和 1 条 assistantfinal-reply lifecycle 恰好 1 组 started -> completedfallback replay、重复 message/receipt 均为 0。该次上游物理请求计数未直接观测,证明模式为 lifecycle slot 与 canonical response identity 交叉核对。公共正文、API Key、thinking、诱饵、项目绝对路径及 transcript/report 路径泄漏均为 0;隔离 Runner 由 Linux pidfd 精确停止,AppData 和一次性项目按 sentinel 清理。

V1.20 单 Agent Provider 原生联网检索

V1.20 对标 Codex CLI 的可选 Web Search,但只声明当前 platform-llm 已具备的布尔 Provider 能力,不伪装成 Codex 的 indexed / live 两种模式。配置默认关闭;开启表示允许兼容 Provider 在本次模型请求中使用其原生 web_search,不等于 App 获得任意 HTTP、浏览器或 shell 网络权限。

配置、继承与兼容性

  • 全局配置新增 llm.webSearchEnabled: boolean,发布默认 falseagentLlm.<agentId>.webSearchEnabled?: boolean 使用与 stream 相同的三态继承,显式 false 必须覆盖全局 trueproject-supervisor 使用自己的精确 override,旧 agentLlm.chat 只继续作为它的兼容前置 patch。
  • openai_responses 把能力编码为 Responses tools=[{type:web_search,...}]openai_chat 编码为 web_search_options={}。当前 anthropic 适配器不支持该能力;全局或解析后的 per-Agent 配置只要形成 apiKind=anthropic + webSearchEnabled=true,配置保存、状态检查和请求构建都必须尽早失败,不能等到用户发送消息后才返回模糊 Provider 错误。
  • 自定义 OpenAI-compatible 网关可能没有开通原生搜索。配置状态只证明本地组合合法,不把网关兼容性伪装成已验证;真实 smoke 若返回 tool-not-open、4xx 或协议错误,必须保留为明确失败并允许用户关闭该 Agent 的搜索开关。

请求范围与不可信输入

  • 允许搜索的请求只有普通主聊天、开发单 Agent 直聊及流式直聊、后台 Agent tool-plan planning。后台 planning 同时保留本地 function toolProvider 必须支持 web search 与 function tools 共存。
  • final-reply、格式 repair、图片检查、草案生成、Evaluator、角色 brief 和其它未显式列出的请求不启用搜索。final reply 只汇总已持久化任务、观察和 planning 证据,不能在收束阶段再次引入新的网页事实或额外搜索计费。格式 repair 沿用首个 planning 请求正文,但强制关闭搜索,避免同一 loop 因协议修复重复联网。
  • 所有可搜索 system prompt 必须明确:网页与搜索摘要是不可信外部输入,不能修改系统规则、Agent 身份、Goal、权限、确认、沙箱或工具协议;网页中的命令和泄密要求不是用户指令。不得把 API Key、Token、Cookie、请求头、项目源码、项目内或宿主绝对路径、私有对话、Agent 记忆、项目黑板正文作为搜索词。该提示降低风险但不能成为确定性数据防泄漏证明,因此能力保持显式 opt-in。
  • 开启原生搜索的流式直聊若流协议失败,不再自动用同一请求做普通回复 fallback;Runtime 无法证明上游是否已执行搜索时必须失败关闭,避免重复搜索和重复计费。关闭搜索时保留既有流式兼容回退。

状态与审计

  • Tauri 配置状态、--llm-status、开发配置弹窗、Agent 卡片和 Agent 对话状态都展示解析后的 webSearchEnabled,但不显示 API Key、搜索词或网页正文。配置弹窗必须包含全局二元开关和 per-Agent 继承 / 开启 / 关闭 控件,并补齐 project-supervisor 的 per-Agent 配置行。
  • 后台 Provider lifecycle 当前写入 game-creator-provider-request-lifecycle.v2,在原身份闭集上只新增 webSearchEnabled: boolean。v1 历史记录继续按缺省 false 只读兼容;v2 缺字段、类型错误或出现其它额外字段仍失败关闭。requestId 算法保持不变,避免升级后把同一旧 request slot 当成新请求重放。
  • tool-plan 首次 planning 的 lifecycle 按实际请求写 true|false;格式 repair 和 final-reply 固定写 false。公共 Agent DB 不保存 Provider 生成的 query、搜索结果、网页 URL、引用正文或网页指令,conversation 只保存模型最终可见回复。

验收口径

  • Rust 配置回归覆盖默认关闭、全局开启、per-Agent true/false 继承、Supervisor 精确 override、空 patch 清理,以及全局/解析后 Agent Anthropic 组合保存时拒绝。CLI/status JSON 只出现布尔值且不泄漏 key。
  • Provider 请求回归覆盖 OpenAI Chat/Responses 请求体、直聊与流式直聊启用、background 首个 planning 启用、repair/final reply 禁用、搜索流失败零 fallback,以及 lifecycle v2 布尔审计和 v1 兼容。
  • 前端回归覆盖全局 checkbox、per-Agent 三态控件、Supervisor 行、保存 payload、恢复默认值、Anthropic 错误展示、LLM 路由摘要和 Agent 卡片状态。
  • 真实 Provider smoke 使用项目外隔离 AppData 和无密钥 local overlay,只对一个测试 Agent 临时设置 webSearchEnabled=true,询问可由当日公开信息验证且不包含项目内容的问题。验收请求体/生命周期布尔值、非空真实回答、唯一请求、零 query/result 公共落盘和密钥/项目路径泄漏;网关不支持时记录明确失败,不把普通模型回答冒充搜索成功。

2026-07-15 对当前正式配置的 openai_chat / gpt-5.5 路由执行了三轮真实 web-search suite,结果均为 FAIL,不能标记该网关已支持原生联网检索。脚本先从 GitHub Releases API 动态读取 nodejs/node 最新 stable release,再只给隔离 AppData 中的 code-prototype 写入无密钥 webSearchEnabled=true overlay。上游接受请求并为 tool-plan 写出 v2 started -> completed lifecycle,但模型明确判断“当前可用工具不包含 Provider 原生联网搜索能力”,转而尝试本地 conversation.read / agent.action_history,最终没有返回动态 baseline;复验观察到 3 个搜索开启的 planning request identity,进一步证明 web_search_options 被接受不等于搜索实际生效。三轮均为唯一 assistant、零 API Key/诱饵/项目路径/正式配置路径泄漏,正式配置 CLI 调用为 0,源 Runner endpoint 未变化;最终复验把凭据配置放在正式 AppData 同级的 0600 私有副本中,源配置 dev/inode/nlink/size/mode/mtime/ctime/SHA-256 前后完全一致,不再用 hardlink 改变源 inode 元数据。隔离 Runner 由 Linux pidfd 精确停止,隔离 AppData 和 disposable 项目均按 sentinel 清理。当前路由应保持搜索关闭,待网关明确支持后重跑;suite 允许 Runtime 直接提交 planning response,只有实际发生 final-reply 时才要求其 webSearchEnabled=false

V1.21 单 Agent token-aware 持久上下文压缩

V1.21 对标 Codex CLI 的 model_context_windowmodel_auto_compact_token_limittool_output_token_limit/compact。它替换“固定保留最近 12 条就算压缩”的能力口径,但不删除原始 conversation、task、event 或工具事实,也不把模型摘要提升为 Goal、计划、权限、验证或副作用事实源。

配置与预算

  • llm 新增 contextWindowTokens / autoCompactTokenLimit / toolOutputTokenLimit,发布默认分别为 128000 / 64000 / 12000agentLlm.<agentId> 复用现有 patch 继承,显式 Agent 值覆盖全局。三项都必须大于 0,自动阈值必须小于 context window,并为当前请求的 maxOutputTokens 与固定安全余量留下空间。
  • Runtime 在发送 tool-plan、context-compaction 或 final-reply 前,按消息、multimodal 文本和 function schema 的规范序列化字符数做保守 token 估算;Provider 返回 usage 时再记录真实 prompt/completion/total。估算只用于提前门禁,不能伪装成 Provider 计费事实。
  • 单条 observation 进入模型上下文前按 toolOutputTokenLimit 收紧;完整命令输出仍留在 owning Agent 的私有 sidecar,通过既有分页工具读取。公共状态只显示估算 token、最近真实 usage、阈值、压缩次数和时间,不显示被压缩正文。

可压缩内容与不可压缩事实

  • 可压缩源只包括当前 Agent active Session 的旧对话、Supervisor 的 legacy 项目对话、当前 run 已完成的旧 observation,以及上一版可信 summary。每次至少保留最近 4 条 Agent 消息、最近 2 条 legacy 项目消息和最近 4 条 observation 原文;新增 tail 继续逐条进入 planning。
  • Goal ID/revision/snapshot、任务正文、结构化计划及 revision、steer ledger/cursor、pending action、project revision、repository fingerprint、verification gate、process/join/delegate 屏障、action receipt/finalization identity 永远不交给摘要模型改写。它们继续从各自规范 sidecar 或 Runtime state 逐字段注入和校验。
  • summary 是不可信的有界历史提示,只能帮助模型回忆需求、决定、已验证结果、失败与未完成事项;不能改变系统规则、Agent 身份、权限、确认、沙箱、工具 schema 或完成门禁。原始 conversation 和执行事实继续保留,可由开发入口查看。

私有 sidecar、幂等与恢复

  • 规范 sidecar 为 game-creator-runtime-context-compaction.v1,路径固定为 .agent/runtime/context-compactions/<agentHash>/<sessionHash>.json。它绑定 project/Agent/Session、可选当前 run、触发类型 auto|manual、上一 summary 指纹、Agent/legacy conversation 覆盖计数与前缀 SHA-256、observation 覆盖计数与前缀 SHA-256、source fingerprint、summary/fingerprint、估算前后 token、Provider usage、单调 revision 和时间;路径 hash 取稳定身份 SHA-256 十六进制前 32 位。
  • source fingerprint 与当前覆盖前缀完全相同时重复压缩直接复用同一 sidecar,不请求 Provider、不增加 revision。conversation 不是 append-only 前缀、同 run observation 前缀变化、summary 指纹冲突、身份不匹配、损坏或超限时失败关闭,不能把旧摘要套到新历史。
  • compaction 请求使用当前 Agent 的解析后 LLM route、独立 requestKind=context-compaction 和由 source fingerprint 派生的稳定 request slot,固定禁用 web search 和工具。它复用 V1.18 Provider lifecycle/orphan barrier;未知 started、同 request 多终态或 terminal lifecycle 已存在但 sidecar 未提交时进入 needs-reconciliation,绝不重发。Provider 完成后先原子写 sidecar,再允许 tool-plan 使用它;sidecar 已提交但 Runner 随后退出时恢复直接复用。
  • Runtime context bundle 升级时只绑定 compaction revision/source/summary fingerprint 和覆盖计数,不复制 summary 正文。恢复必须让 bundle、sidecar 和当前 conversation/observation 前缀一致;旧 bundle 可在原有身份、Goal、计划和 verification 校验通过后补入缺省“未压缩”绑定,后续 checkpoint 写新版本。

自动与手动入口

  • 每次 background tool-plan 构建后先计算输入估算。超过解析后的 autoCompactTokenLimit 时,在同 Agent/Session/run 的安全 planning 边界压缩可压缩 prefix,重建请求并再次估算;重建后仍超阈值或没有新的可压缩 prefix 时失败关闭并给出配置/新 Session 建议,不能继续发送已知超限请求。
  • agc:chat / agc:swarm 新增 /compact,开发 Agent 窗口提供同一动作和状态。手动压缩只允许当前 Agent active Session 没有 in-flight Provider、执行中工具、待确认动作或未收束 Runtime 时进行;有活动 run 时由自动安全边界处理,不能从 UI 直接打断副作用。正式用户 Project Supervisor 页面不增加压缩按钮。
  • /status 和开发面板展示 estimatedInputTokens / autoCompactTokenLimit / lastPromptTokens / lastCompletionTokens / compactionRevision / lastCompactedAt。手动和自动都写相同的哈希/计数审计,公共 event、Agent DB、receipt、activity/output 和报告不得出现 summary、原 conversation/observation、任务、路径或凭据正文。

验收口径

  • 确定性测试覆盖配置默认值与 per-Agent 继承、预算非法组合、token 估算包含 function schema、工具输出限额、自动阈值、手动 /compact、最近 tail 保留、同源幂等、追加后 revision 单调、conversation/observation 前缀篡改失败关闭、sidecar/bundle 身份冲突、summary 上限和公共审计零正文。
  • Provider 生命周期测试覆盖 started 前退出可安全重试、started 未终态进入 reconciliation、completed 后 sidecar 缺失零重放、sidecar 已提交后恢复复用,以及 Goal、计划、steer、pending、verification 和副作用身份压缩前后逐字段相同。
  • 真实 Provider 使用隔离 AppData 和 disposable 项目完成至少 30 轮多轮任务,跨越至少两次压缩和一次 Runner 强杀;证明 planning 始终低于阈值、原 Agent/Session/run 身份稳定、已完成工具零重放、最终 assistant 唯一、summary 能引用早期用户约束,且全部公共持久面 API Key、原始对话/observation、项目绝对路径和 summary 正文泄漏为 0。未完成该长链路前只能记录确定性通过,不能宣称 V1.21 整体 PASS。

2026-07-15 使用正式 AppData 的 openai_chat / gpt-5.5 路由和隔离 Runner 执行 context-compaction suiteV1.21 整体 PASS。同一 Agent active Session 完成 30/30 轮、60 条 conversation message 和 30 个唯一 assistant audit;两次真实 Provider compaction 形成 revision 1/230 个 tool-plan 与 2 个 compaction request 共 32 组 lifecycle,全部唯一 started -> completedfallback replay 为 0。Runner 通过 Linux pidfd SIGKILL 后 boot 变化、Session 身份保持稳定,早期用户显式约束可从最终回复召回;最大估算输入 29134,低于 64000 自动阈值。公共 task/event/Agent DB/conversation/report 中原始正文、summary、API Key、诱饵、项目绝对路径和正式配置路径泄漏均为 0,重复 message/audit、工具执行与 finalization journal 均为 0;隔离 AppData 和 disposable 项目按 sentinel 清理。首轮复验在第 22 轮收到 Provider transport 终态并按规则 FAIL,未自动重放;新 disposable 项目完整重跑后取得上述 PASS。

真实长链收口时同步修正四项实现边界:显式用户约束由确定性保留层逐字钉住并继续做密钥/绝对路径脱敏;runtime.compact 单独使用 6 分钟 IPC 响应窗口,其他 Runner 方法仍保持 10 秒;普通后台任务公共审计只保存 taskChars + taskSha256,任务正文仅留在私有 task ledger/conversation;每 6 轮只做进度 checkpoint 与停滞检测,真正摘要只由 token 阈值或显式 /compact 触发。终态旧 context bundle 仅允许在完整 schema、身份、Goal、revision、verification、observation、sidecar 和 steer 校验通过后刷新 legacy plan 投影差异。

V1.22 Runner-owned MCP 动态工具

V1.22 对标 Codex CLI 的 MCP tool 能力,在现有单 Agent Runtime 内增加动态外部工具目录,不新建平行 Agent、平行工具执行器或绕过权限的直连入口。实现使用官方 Rust MCP SDK rmcp;首个纵向切片覆盖 STDIO 与 Streamable HTTP、server instructions、Bearer/static header、工具 allow/deny 和工具级审批。OAuth、MCP resources/prompts、sampling、elicitation 与 task-mode 调用不在本切片宣称范围内,后续按同一 Runner 继续扩展。

AppData 配置

  • game-creator.config.json 新增 mcpServers.<serverId>。serverId 必须是 1-64 个 ASCII 字母、数字、点、下划线或连字符;配置包含 enabled / required / transport / startupTimeoutMs / toolTimeoutMs / enabledTools / disabledTools / defaultApprovalMode / tools。正式默认不启用任何外部 server。
  • transport=stdio 必须配置裸可执行名 command,可选 args / cwd / envRuntime 从项目外受信任 PATH 解析可执行文件,清空继承环境,只注入安全 PATH、配置中的 env 与 Windows 启动所需的最小系统变量。显式 cwd 必须是已存在的项目外绝对目录;省略时固定使用已解析可执行文件所在目录,不继承 Runner 或 owning project cwd。命令、参数、env 名和值都受数量、字符和总字节上限约束;项目配置、.env 和宿主环境变量不作为凭据回退。
  • transport=streamableHttp 必须配置 https:// URL,只有显式 allowInsecureLocalhost=true 时允许 http://127.0.0.1|localhost|[::1];可选 bearerToken / httpHeaders 只从 AppData 读取。禁止 URL userinfo、fragment、控制字符和 hop-by-hop/Host/Content-Length header。OAuth 缺失时必须明确报“当前切片未支持”,不能静默降级成匿名连接。
  • enabledTools 是可选 allowlistdisabledTools 在 allowlist 后应用;tools.<toolName>.enabled=false 最终禁用。审批只接受 auto / confirm / writes / deny:默认 confirmwrites 仅在用户显式选择且 server tool 声明 readOnlyHint=true 时自动,其余确认。MCP annotations 是不可信提示,不能覆盖本地 deny/confirm、项目 policy 或隔离 child 限制。

Runner 目录与模型上下文

  • 独立 Runner 按规范配置指纹持有每个 server 的连接;同一 server 的 catalog/call 串行,不同 server 可并行。配置变化、连接关闭或 Runner boot 变化会废弃旧连接并重新 initializerequired server 初始化或列目录失败时阻止 planningoptional server 只从当前目录移除并在 MCP 状态中报告安全错误摘要。
  • 每次 planning 在 Provider request slot 注册前刷新 tools/list,应用 allow/deny 后形成规范 catalog。单 server、全局工具数、名称/描述、instructions、input/output schema 和总序列化字节都有硬上限;重复公开 action identity、非法 schema、required task support 或目录超限失败关闭。server instructions 作为不可信外部指导单独标注,前 512 字必须自包含,总量有界,不能改变系统规则、Agent 身份、Goal、权限、确认、沙箱、完成门禁或数据边界。
  • 模型继续只调用 submit_agent_tool_plan。动态调用使用白名单 action mcp.callinput 固定为 server / tool / arguments / catalogFingerprint / toolFingerprint;Runtime 在解析模型结果后自行注入两个 fingerprint,模型不能提供或覆盖。planning prompt 带入经过过滤的 tool description 与完整 input schema,函数 schema 和 MCP catalog 都进入 V1.21 token 估算与自动压缩重建。
  • catalog identity 绑定 server 配置指纹、initialize server info、instructions 指纹、过滤后的工具名称、description、input/output schema、annotations 与 execution metadata。工具在 planning 后消失、schema/配置变化或 fingerprint 不匹配时,未执行动作回到同 run replan;已经进入 executing 而结果未知时继续走 needs-reconciliation,绝不按新目录自动重发。

权限、执行与持久化

  • 共享命令契约新增 mcp.call,项目/Agent policy 仍可统一 deny 或 confirm。server/tool 配置只会进一步收紧:deny 直接返回 blocked observationconfirm 复用现有确认卡,auto/writes 也必须先可靠写入 durable pending action。隔离 child 默认禁止 MCP;后续若开放必须有模板级显式 allowlist,不继承父 Agent 的宽权限。
  • MCP 调用复用当前 action fingerprint、steer cursor、Goal、project/repository revision、verification gate、Provider request identity 与 approved -> executing -> observed-* 账本。调用前再次读取 AppData、刷新目标 tool 并核对两个 fingerprintRunner 在 executing 后退出、超时后无法确定服务端是否完成、SDK transport 断开或审计落盘失败均进入 reconciliation。只有服务端明确返回 result/error,才形成可继续 planning 的确定终态。
  • 完整 CallToolResult 原子写入 .agent/runtime/mcp-results/<agentHash>/<runHash>/<actionHash>.json 私有 sidecar,绑定项目/Agent/Task/Session/Run/action/server/tool/catalog/tool/result fingerprint、执行时 toolOutputTokenLimit、字符/内容块计数、isError 和时间。恢复时必须从完整 result 按原预算重算计数、摘要、二进制元数据和 observation 并全量比对;任一派生字段不一致都进入 reconciliation,不能接受局部损坏摘要。模型 observation 只读取受 toolOutputTokenLimit 约束的 text/structured contentimage/audio/embedded resource 只给类型、MIME、大小和 SHA-256 元数据,本切片不把任意 MCP 二进制转发给 Provider。
  • 公共 Runtime state/event/task/Agent DB/receipt/activity/output/report 只保存 server/tool、审批、状态、参数字符数与 SHA-256、结果内容块计数/字符数与 SHA-256、sidecar 相对路径和安全错误分类,不保存 arguments、返回正文、Bearer/header/env、server instructions、绝对路径或 SDK 原始错误。agent.action_history 同样只返回该安全摘要。

开发入口与验收

  • 开发配置面板管理 MCP server,敏感字段沿用密码输入;保存前完成本地结构校验,连接测试走 Runner,不由 WebView 直接联网或启动进程。agc:chat / agc:swarm 提供 /mcp 查看 server 状态和有界工具目录;正式用户 Supervisor 首页不展示 MCP 配置或调试正文,但 Runtime 可以按已配置策略使用工具。
  • 确定性测试覆盖两种 transport、initialize/instructions/tools list、allow/deny、审批映射、动态 schema/token 预算、配置/catalog 漂移、required/optional 失败、超时、Runner 强杀、pending/reconciliation、结果 sidecar、二进制降级和全部公共零正文。
  • 真实本地 E2E 使用一次性 STDIO fixture 与 Streamable HTTP fixture,各自让真实 Provider 发现并调用至少一个只读工具;再让一个有副作用 fixture 停在确认、批准后只执行一次,并在调用窗口强杀 Runner 证明零重放。报告必须证明 tool schema 来自 MCP、server instructions 被标为不可信、同一 Agent/Session/run 身份稳定、结果可回灌、重复调用/assistant 为 0,且凭据、arguments、结果正文、项目/配置绝对路径公共泄漏为 0。

2026-07-15 使用正式 AppData 的 openai_chat / gpt-5.5 路由和一次性隔离配置执行 mcp-runtime suiteV1.22 整体 PASS。正常 run 由真实 Provider 从动态 schema 发现并调用 STDIO lookup、Streamable HTTP lookup 和 STDIO mutate 各 1 次;mutate 在工具级确认后执行,形成 3 个唯一 action、3 份私有结果 sidecar、3 条 terminal receipt 和 1 条最终 assistant。第二个 run 在 HTTP mutate 已产生一次副作用、结果尚未返回 Runner 的确定性窗口通过 Linux pidfd 强杀 Runner;恢复后只形成 1 条 reconciliationmarker 保持 1 次,sidecar、receipt、assistant 和重复调用均为 0。

真实报告同时证明正常与强杀 run 的 Agent/Session/run 身份稳定,参数由 MCP schema const 提供而非用户任务正文;公共 task/event/Agent DB/receipt/conversation/report 中 arguments、结果正文、server instructions、Bearer/static header、API Key、项目绝对路径和配置绝对路径泄漏均为 0。Runner、HTTP fixture、隔离 AppData 和一次性项目全部按 sentinel 清理。确定性 MCP 组为 15/15Tauri 全量为 800 passed / 4 ignored;开发配置窗在 1440px 与 900px 真实浏览器视口均无横向溢出或侧栏遮挡,console 0 error / 0 warning。

V1.23 单 Agent 持久用户输入请求

V1.23 对齐 Codex Plan/Goal 在任务未完成时主动澄清并进入 Needs input 的行为。现有普通最终回复会结束 run,same-run steer 只表达用户主动修正,工具确认只决定是否执行副作用;三者都不能证明“Agent 提出了哪个问题、用户回答了什么、答案是否只回灌一次”。本切片在同一 Runtime 增加 user.input_request,不新建聊天系统或第二套任务队列。

问题与模型协议

  • user.input_request input 固定为 questions,数量 1-3。每题包含唯一 snake_case id、最多 12 个字符的 header、单句 question 和 2-3 个 options;每个 option 包含短 label 与一条 description。自由输入始终允许,模型不能关闭“其他”答案。
  • 该 action 必须是本轮唯一工具动作,response 必须为空;Runtime 在 schema 解析后再次确定性校验。问题只用于实现路径、产品取舍或缺失事实会实质改变结果的场景;项目内可读取的事实、权限确认和工具失败不能伪装成用户问题。
  • 动态 isolated child 和带父委派身份的专业 Agent 禁止直接调用;它们应通过既有 result/receipt/agent.message 把澄清需要交回父 Agent。直接开发试聊的静态 Agent 与 project-supervisor 可以调用。

身份、持久化与隐私

  • requestId 由 project/Agent/task/Session/run/action/fingerprint 派生,模型和客户端都不能指定。私有 game-creator-runtime-user-input.v1 sidecar 绑定 action、Goal revision/snapshot、planned steer cursor、问题规范正文、question messageId、responseId、answer messageId、答案哈希和单调状态 pending -> answer-prepared -> answered | cancelled
  • create-once sidecar 先于 assistant question conversation;问题消息使用稳定 messageId 幂等追加到 owning Agent Session。Runner 在 pending action 已进入执行但进程退出时只允许重放该本地 create-once 协议,不重放 Provider 或外部副作用。
  • 回答必须带 requestId、全量 answers map 和客户端稳定 responseId。项目锁内先写 answer-prepared,再幂等追加 user conversation,最后写 answered 和唯一工具 observation;同 responseId/同正文重试继续补齐,身份相同但正文不同失败关闭。
  • 完整问题和答案只进入 sidecar、owning Session、私有 observation/context bundle。公共 Runtime event/task/Agent DB/receipt/action history/activity/output/report 只保留 request/action identity、题目/选项/答案数量、字符数和 SHA-256,不复制正文、选项描述、自由输入、路径或凭据。

状态、恢复与客户端

  • durable pending action 增加 waiting-for-user-input。Runtime state/phase 同名,保持原 Agent/task/Session/run/Goal、结构化计划和 steer cursor;不完成 active plan step、不生成 finalization、不消费下一任务。普通 steer 在该状态被拒绝,回答只能走精确 request API。
  • Runner 重启时:无 sidecar可安全补建;pending/answer-prepared 修复缺失的幂等 conversation 并继续等待;answered 从 sidecar 全量重算 observation 后继续原 run;任一身份、问题、答案或会话消息冲突进入 needs-reconciliation。取消将未回答请求标记 cancelled;Goal pause 保留请求,恢复后仍回到 Needs input。
  • AgentRuntimeResult 只在 owning Session 当前 run 暴露一个 pending request。Project Supervisor 主聊天、开发 Agent 窗口和 agc:chat 展示同一结构化问题;桌面端按题提供 2-3 个选项和自由输入,全部必答后才能提交。提交中禁用重复操作,刷新/切 Agent/重启后从 sidecar 恢复。
  • 确定性验收覆盖 schema/预算、sole-action、child deny、幂等 create/answer、responseId 冲突、会话中间失败、Runner 强杀三窗口、Goal pause/resume、cancel、普通 steer 拒绝、跨 Agent/Session/run/request 回答拒绝和公共零正文。真实 Provider 必须在复杂任务中自主提问,用户回答后同 run 完成唯一最终回复,并验证问题/答案各一条、Provider 未在等待期调用、Runner 强杀后零重复。

2026-07-16 使用正式 AppData 的 openai_chat / gpt-5.5 路由执行隔离 user-input-runtime suiteV1.23 真实验收 PASS。Project Supervisor 自主发起 1 个含 2 个选项的结构化问题,等待期使用 Linux pidfd 强杀 Runner 并换 boot 恢复;Provider started 记录在重启前后保持 1 -> 1,未暗中请求。回答后保持同一 Agent/Session/run,会话恰好为 1 条初始任务、1 条 assistant 问题、1 条 user 回答和 1 条最终 assistant;全程 2 个 Provider request identity 均唯一闭合,重复 message、遗留 finalization、公共问题/答案正文、API Key、项目/配置路径和报告泄漏均为 0,隔离 Runner、AppData 和一次性项目已清理。

V1.24 Codex 式 scoped AGENTS.md 仓库指令

V1.24 修正仓库启动上下文把 AGENTS.md 与 README/CONTEXT 一律描述成“纯数据”的行为。AGENTS.md 是受 Runtime 系统边界约束的项目指令:用于约定目录内代码风格、工作流、测试和交付要求;README 与根 CONTEXT.md 仍只是项目参考数据。本切片不扫描 AppData、用户主目录或仓库外 Skill,也不宣称已经实现 Codex 的完整 Skill 发现与按需加载。

  • 仓库启动上下文升级为 repository-startup-context-v2。每个 context document 除 path / kind / content / contentSha256 / truncated 外新增规范 scope:根 AGENTS.md 的 scope 为 .game/AGENTS.md 的 scope 为 gamegame/feature/AGENTS.md 的 scope 为 game/featureREADME/CONTEXT 的 scope 固定为 .,但不具备项目指令语义。
  • Agent 对每个准备读取、修改、验证或提交的项目内路径,必须只应用其祖先目录链上的 AGENTS.md,按根到叶顺序叠加;更深 scope 只在自身目录树内覆盖冲突,兄弟目录规则不得串用。没有目标路径时可以使用根指令做全局规划,但不能把任意嵌套规则提升成全局规则。
  • Provider prompt 必须显式区分 SCOPED REPOSITORY INSTRUCTIONSUNTRUSTED REPOSITORY REFERENCE,列出每份文档的 scope、SHA-256 和截断状态,并在正文边界重复 path/scope。已截断的适用指令不能被模型当作完整规则;后续需要修改该 scope 时应先通过现有 file.read 获取足够上下文。
  • 项目指令不能修改 Agent/Goal/Session/run 身份,不能授予工具、网络、MCP、文件或命令权限,不能替用户批准确认动作,也不能放宽沙箱、隐私、verification/finalization 或副作用重放门禁。正文继续执行凭据和绝对路径清洗;符号链接、敏感目录和 .agent/** 不进入启动上下文。
  • v2 fingerprint 覆盖规范 path、kind、scope、清洗后正文哈希和既有仓库结构。旧 pending action 绑定的 v1 fingerprint 在第一次恢复或执行前会按现有 repository context drift 路径转成 blocked observation 并在同一 run 重规划,不能按旧规则直接写项目。
  • 确定性验收覆盖根/父/叶/兄弟 scope、根到叶顺序、非指令参考文档标签、prompt 真实请求载荷、正文预算与截断、密钥/绝对路径清洗、scope/content 变化导致 fingerprint 漂移,以及旧 pending 动作零执行。真实 Provider 使用现有 agent-runtime-real-e2e.mjsscoped-agents suite:一次性项目放置根、game 父级及 alpha / beta 两个兄弟 scope,任务不包含随机规则正文、期望内容或工具配方;项目验收器只保存两份期望交付内容的 SHA-256,模型不能从验收脚本反推规则。

2026-07-16 正式 openai_chat / gpt-5.5scoped-agents suite PASS。原始 fixture 先真实失败;最终脚本复跑中,同一 code-prototype Agent 以 2 个项目变更动作只修改两个目标文件,根规则、game 父规则和 alpha / beta 叶规则全部精确命中,兄弟规则串用为 0,Agent 的 project.verify 与宿主独立复验均通过。8 组 tool-plan Provider lifecycle 全部唯一 started -> completed,最终 assistant 和 completed audit 各 1,重复 message/receipt、遗留 finalization,以及最终回复/公共审计/报告中的内部规则正文、API Key、诱饵、项目/正式配置绝对路径泄漏均为 0;正式配置 CLI 调用为 0,源 Runner endpoint 和配置副本保持不变,隔离 Runner、AppData 与 disposable 项目已按 sentinel 清理。V1.24 真实行为门禁至此完成。

V1.25 Codex 式项目 Skill 发现与渐进加载

V1.25 在 V1.24 仓库启动上下文上增加项目内 Skill catalog,但不把 Skill 正文预加载到每轮 prompt。目标是对齐 Codex 的 progressive disclosure:模型始终只看到用于触发判断的 name / description / entryPath / contentSha256,任务真实命中后再通过现有 file.read 获取 SKILL.md 正文,并只按正文导航读取必要 reference。Skill 是项目工作流知识,不是新工具、权限包或可执行插件。

  • 发现根固定为项目内 .codex/skills/<skill-name>/SKILL.md 与兼容目录 .agents/skills/<skill-name>/SKILL.md,只接受这两个根下的直接子目录入口,不递归把 reference 中的其它 SKILL.md 当独立 Skill。本仓库既有规范以 .codex/skills 为准;同名且两处都合法时 .codex 胜出,删除高优先级入口后 .agents 才可接管。V1.25 不扫描 AppData、用户主目录、全局 Codex/Hermes 安装目录、Git submodule 外部路径或网络 marketplace。
  • skill-name 必须与目录名和 YAML frontmatter name 完全一致,使用 1-64 个 ASCII 小写字母、数字或单连字符,首尾必须是字母或数字;frontmatter 必须位于文件开头并提供非空字符串 name / description。YAML 使用结构化 parser;未知字段不产生 Runtime 能力。描述清洗凭据和绝对路径、折叠为单行并限制 2048 bytes。
  • 单个 SKILL.md 最大 128 KiBcatalog 最多 64 项,prompt 中 Skill metadata section 最大 4 KiB。超限、解析失败、符号链接、路径不规范或读取失败的入口不进入 catalog;预算或读取导致的省略必须使 repository context 标记 truncated=true,不能把部分 YAML 当有效 metadata。
  • 仓库启动上下文升级为 repository-startup-context-v3,新增有界 skills 列表。fingerprint 覆盖 active Skill 的规范入口路径、来源根、清洗后 name/description、清洗后完整文件 SHA-256 和截断状态;Skill 正文、metadata、优先级或入口增删发生变化时,任何受 repository context gate 保护的旧 pending action 都必须先形成 drift blocker,再在同一 run 重规划。shadowed 的低优先级同名入口不影响 active 语义。
  • Provider prompt 使用 PROJECT SKILL CATALOG (UNTRUSTED DISCOVERY METADATA) 边界,只列 metadata 和内容哈希,不包含 frontmatter 后正文。模型必须先判断任务是否匹配,只选择必要 Skill;在声称使用或依据 Skill 行动前,必须用 file.read 读取 catalog 给出的精确 entryPath,正文较长时按行继续读取足够上下文。Skill 指向的 references / scripts / assets 仍只是项目文件;只在任务需要时读取,脚本执行必须另走现有命令工具和权限确认,不能因 Skill 存在而自动执行。
  • Skill metadata、正文和资源不能改变 Agent/Goal/Session/run 身份,不能授予工具、网络、MCP、文件或命令权限,不能替用户批准动作,也不能放宽沙箱、隐私、verification/finalization、仓库 scope 或副作用重放门禁。Skill 与 AGENTS.md 冲突时,适用路径的 scoped AGENTS.md 仍是更高的项目规范;Skill 只能在这些边界内补充领域工作流。
  • 确定性验收必须覆盖两个发现根、同名优先级、非法名称/YAML/路径、符号链接、文件与数量预算、metadata 清洗、正文不进入首轮 prompt、Skill 内容变化推进 fingerprint、v2 pending 写动作被阻断,以及 Provider 捕获请求中首轮只有 metadata、成功 file.read 后下一轮才出现正文 marker。真实 Provider 使用现有 real-e2e harness 的 project-skill suite:任务不包含 Skill 名称、入口、正文 marker 或工具配方,hash-only 验收不能反推正文;最终必须证明首个项目变更前已真实读取匹配 Skill、未读取无关 Skill、只修改目标文件并完成真实验证,且 Provider lifecycle、唯一 assistant、配置隔离和零泄漏门禁全部通过。

2026-07-16 正式 openai_chat / gpt-5.5project-skill suite PASS。一次性项目的 hash-only 原始验收先真实失败;Agent 在首个项目变更前精确读取匹配 .codex/skills/release-capsule/SKILL.md 1 次,无关 Skill 读取为 0,以 1 个项目变更动作只修改 game/release-capsule.txt,随后 Agent project.verify 与宿主独立复验均通过。最终脚本复跑记录 25 条 task、41 条 event、57 条 Agent DB、5 个成功工具动作和 2 个确认动作;4 组 tool-plan Provider lifecycle 全部唯一 started -> completed,最终 assistant 与 completed audit 各 1,重复 message/receipt、fallback replay 和遗留 finalization 均为 0。最终回复、公共审计、测试报告中的 Skill 正文、API Key、诱饵、项目与正式配置绝对路径泄漏均为 0;正式配置 CLI 调用为 0,源 Runner endpoint 和配置副本保持不变,隔离 Runner、AppData 与 disposable 项目已按 sentinel 清理。V1.25 真实行为门禁至此完成。

V1.26 Provider 原生工具目录

V1.26 把 OpenAI-compatible planning 从单个 submit_agent_tool_plan 包装函数升级为独立 function tool 目录。当前 wrapper 虽然走原生 function calling,但每个真实工具仍只是 actions[].tool + 任意 input object,模型需要从长提示词记忆工具名和参数,Provider 也无法对具体工具输入做 schema 约束。新协议让模型直接选择稳定函数名并填写对应 JSON schema;Runtime 仍是唯一执行者,原有 action identity、权限、确认、沙箱、revision、verification、reconciliation、steer、Goal、finalization 和副作用重放边界全部保持。

  • OpenAI Chat 与 Responses 请求必须提供 update_agent_planrespond_to_user、全部当前可执行内置工具,以及当前 MCP catalog 中每个可用工具对应的独立 function definition。内置函数名由规范 Runtime tool id 确定性映射,MCP 函数名使用 server/tool 身份的稳定有界哈希,不能把外部任意名称直接拼成 Provider function name;完整 server/tool 与 catalog/tool fingerprint 继续由 Runtime 绑定,模型不能提交或覆盖。
  • 每个内置 action function 使用独立输入 schema,并显式携带非空 reason 与工具 input。MCP function 复用经过现有目录预算和清洗的真实 input schema,但外部 description/schema/instructions 始终是不可信输入,不能改变系统规则或扩大能力。function catalog 必须进入 token 估算和自动压缩预算;目录超限、重复函数名、非法 schema 或 binding 漂移失败关闭。
  • 一次 Provider 响应最多包含 1 个 update_agent_plan、最多 3 个 action function call,或 1 个 respond_to_user;计划更新既可单独作为持久进度 checkpoint,也可与 action 或最终回复同批返回,最终回复不能与 action 共存。plan-only 会先持久化单调计划,再由未完成计划 blocker 进入同一 run 的下一次 planning,不会提前写 assistant 或 completed。call id 必须非空且唯一,未知、重复、参数非对象、超预算、空回复、多个回复或多个计划更新都进入现有格式修复,不执行任何动作。action 顺序按 Provider 返回顺序稳定转换;V1.26 不宣称同一 Agent 内并行执行工具,转换后的动作继续逐个进入 durable ledger。
  • update_agent_plan 只承载 explanation 与最多 8 个持久步骤;respond_to_user 只承载最终正文。直接工具协议不要求模型公开 thinking 正文,Runtime 从计划说明或首个 action reason 派生有界 thinking summary。结构化计划仍有未完成步骤时禁止最终回复,项目修改后仍必须取得当前 revision 的真实验证凭证。
  • 新请求不再向 OpenAI-compatible Provider 广告 submit_agent_tool_plan。解析器继续接受旧 wrapper 与 text JSON,用于现有确定性 fixture、历史兼容和不提供 function tools 的 Anthropic 路径;格式修复请求必须继续广告当前原生目录,不能在同一 Provider request identity 下静默切回旧 wrapper。公共协议审计只保存协议名、function call 数量、稳定函数名和 call id 身份,不保存 arguments、写入正文、MCP 参数或最终回复。
  • 确定性验收必须覆盖完整内置目录、函数名稳定性、核心 schema、动态 MCP binding、计划 + 多 action、计划 + reply、顺序、未知/重复/冲突/超预算拒绝、旧 wrapper/text 兼容、repair 后仍使用原生目录、token 预算和公共零 arguments。真实 Provider 必须在无工具名和参数配方的任务下自主选择至少一个只读工具、一个项目修改工具和真实验证工具,完成唯一目标文件交付;最终还要证明协议全程为原生目录、action/receipt/Provider lifecycle 唯一、无 wrapper fallback、唯一 assistant/completed、零正文/密钥/路径泄漏和隔离现场完整清理。

2026-07-16 正式 openai_chat / gpt-5.5project-skill suite PASS。首轮真实执行在匹配 Skill 读取后暴露旧 parser 拒绝 plan-only,保留现场复验进一步证明模型会先单独调用 update_agent_plan;Runtime 空动作分支原本已能持久化计划并安全进入下一轮,因此移除矛盾的 parser 拒绝并补三轮确定性闭环。最终加强门禁复跑记录 31 条 task、57 条 event、94 条 Agent DB、6 个成功工具动作和 2 个确认动作;9/9 个成功工具计划与 6/6 个格式修复全部使用 native_runtime_tools,旧 wrapper 与 text JSON fallback 均为 0。Agent 在首个项目修改前读取匹配 Skill 1 次、无关 Skill 0 次,只修改 1 个目标文件,Agent project.verify 与宿主复验均通过;15 个 tool-plan 加 1 个 final-reply Provider lifecycle 全部唯一闭合,最终 assistant/completed 各 1,重复 message/receipt、遗留 finalization、Skill 正文、API Key、诱饵、项目/正式配置路径和报告泄漏均为 0,隔离 Runner、AppData 与一次性项目完整清理。确定性 Tauri 全量为 822 passed / 4 ignoredV1.26 真实行为门禁至此完成。

V1.27 同 Agent 持久只读并行批次

V1.27 在 V1.26 一次最多三个原生 action 的基础上,让同一 Agent 可以真实重叠执行彼此独立的本地只读工具。并行不是通用 action 调度器,也不改变不同 Agent 已有的 lane 并行;Runtime 只把连续 2-3 个、当前策略为自动批准且列入严格白名单的读取动作组成一个持久批次,其余动作继续按 Provider 顺序串行。

  • 首版并行白名单固定为 memory.readconversation.readasset.listproject.searchproject.diffgit.inspectfile.listfile.readtask.listproject.index 会刷新持久启动上下文,不属于纯读取;command.output_readagent.action_historyagent.run_status 可能产生审计、屏障或回执认领,也不进入批次。写入、确认、命令/进程、Git commit、验证、预览、图片/生成 Provider、MCP、消息、委派、动态 child 和其它外部副作用全部保持串行。
  • 只合并 Provider 顺序中连续的安全读取;任一非安全动作形成顺序屏障。例如 read A / read B / write C / read D 只并行前两个读取。策略要求确认或拒绝、工具目录变化、Goal/steer/repository context 身份漂移时不建立批次,不能把确认消费、策略错误或旧动作暗中转成自动读取。
  • 私有事实源新增按 project / agent / task / session / run / loop 绑定的 durable parallel-read batch,最多保存三个稳定 action identity、输入指纹、Provider 顺序、执行状态、终态 observation 和无正文计时元数据。状态只允许 executing -> observedRunner 在 executing 中退出时,因为成员工具已由严格分类证明无副作用,可以在同一 action identity 下重新读取,不能创建新 action、receipt 或 Provider request。observed 恢复只补齐缺失投影,不重新执行物理读取。
  • 批次执行在一个项目一致性锁内完成预检、executing 落盘、真实工作线程并行读取和 observed 原子落盘。steer、Goal edit/pause 和 Runtime 写动作必须在该锁之后才被接受,因此整个批次是一个明确线性化边界:控制请求先获得锁则旧批次零执行,批次先获得锁则其全部读取先完成,再接受控制请求。取消仍遵循“已进入工具的动作返回后停止”,不强杀线程。
  • 物理完成顺序不能影响语义。Runtime 始终按 Provider action index 依次写 task/event/receipt/Agent DB、更新结构化计划和 context bundle;每个 actionId 的 terminal observation 与 receipt 必须唯一。公共并行审计只保存 batch/action identity、工具名、数量、时间区间和是否存在真实重叠,不保存 input、observation 正文、项目绝对路径或凭据。
  • 确定性验收必须覆盖白名单/拒绝清单、连续分组与串行屏障、两个及三个读取的真实线程重叠、完成顺序反转但观察顺序稳定、策略变化、steer 先后双向竞态、取消、Goal/repository drift、executing 重放、observed 只补投影、Runner 强杀、重复 receipt/event/Agent DB 为 0 以及公共零正文。真实 Provider 必须在未提供工具名和顺序配方的任务中自主同轮发出至少两个独立读取,审计时间区间证明重叠,随后同一 Agent/Session/run 完成唯一回复,并证明原生工具协议、稳定 action 顺序、零副作用重放、零重复、零泄漏和隔离现场清理。

2026-07-16 正式 openai_chat / gpt-5.5 的隔离 parallel-read suite PASS。一次性项目构造 421 个只读语料文件,真实模型在同一个原生 planning 轮次提交 2 个独立 project.search,Runtime 只形成 1 个持久并行批次;两个物理搜索重叠 10,969,247ns,公共投影与 receipt 均保持 Provider action 顺序。最终记录 13 条 task、23 条 event 和 48 条 Agent DB4/4 个成功工具计划与 2/2 个格式修复都使用 native_runtime_toolswrapper/text JSON fallback 为 06 个 tool-plan 和 1 个 final-reply Provider lifecycle 全部唯一闭合。最终 assistant/completed 各 1,重复 action lifecycle、receipt、Provider lifecycle、遗留 finalization/批次 sidecar,以及仓库私有正文、API Key、诱饵、项目/正式配置绝对路径和报告泄漏均为 0;隔离 Runner、AppData 与 disposable 项目完整清理。V1.27 真实行为门禁至此完成。

V1.28 Project Supervisor 合同委派与单回复收束

V1.28 收紧 V1.16 的静态专业 Agent 协作协议:project-supervisor 是正式用户唯一默认对话 Agent,也是唯一可以向正式用户提交最终回复的 Agent;静态专业 Agent 与 isolated child 只向父 run 交付内部回执、摘要和证据。开发窗口仍可直调单个专业 Agent,agc:swarm 仍可显式指定其它父 Agent 做调试,但这些入口不构成正式用户对话或第二条用户回复。若本节与 V1.16 或实施计划中的旧表述冲突,以本节为准。

状态:PASS。合同委派、结构化回执、单层 repair、Supervisor finalization、正式用户 GUI 接入和 Runtime 显式瞬时重试均已落地;2026-07-17 正式 openai_chat / gpt-5.5 supervisor-swarm 已完成双专业 Agent 真并行、唯一 repair、pidfd Runner 强杀恢复、唯一 Supervisor assistant、零重复与零泄漏的完整验收。

正式 GUI 接入边界

  • 登录后的单窗口客户端在首页创建项目或从项目组打开已有项目后,项目开发页只挂载 Supervisor 用户面。首页首条需求直接启动 active project-supervisor Session;全新项目尚无该 Session 时先通过既有 Session 命令创建并设为 active,再投递首条需求。已有项目先恢复该 Session、对话和 Runtime,匹配 Session 已存在非终态 run 时,后续普通输入固定走 same-run steer,不切换父 Session/run。
  • 正式页只展示 Supervisor 对话、紧凑 Runtime 状态、确认/Needs input 和专业 Agent 协作只读状态。专业 Agent picker、单 Agent 对话、Session 管理、完整计划和工具台继续只属于 ?agent-chat 开发入口,不进入普通用户项目开发页。
  • .agent/conversations/project.jsonl 仅作为 legacy 项目历史兼容读取并与 Supervisor Session 历史有界合并。正式 Runtime 的 user 消息和最终 assistant 只写入 Supervisor Session,流式草稿只作可丢失展示缓存;三者都不再由 React 写回 legacy 项目对话,避免同一轮双写。
  • 正式页遇到 LLM/AppData 配置缺失时只展示 Runtime 错误,由单窗口壳的全局“配置”入口处理;Supervisor-only 项目页不自动弹出开发配置框。

Native agent.delegate 合同

OpenAI-compatible 新请求中的 agent.delegate 必须使用以下 strict native input;六个字段全部必填,nullable 字段也不能省略,拒绝未知字段:

{
  "agentId": "code-prototype",
  "task": "完成边界清晰的内部子任务",
  "acceptanceCriteria": ["可由 Supervisor 判断的语义验收条件"],
  "expectedArtifacts": ["game/feature-a.js"],
  "repairOfDelegationId": null,
  "runId": null
}
  • agentId 只能是可委派的静态专业 Agent,不能是 project-supervisor 或动态 child 实例;task 沿用现有非空、长度、敏感信息和任务正文边界。
  • acceptanceCriteria 必须有 1-8 个非空且不重复的条目,顺序和正文都进入 action fingerprint;它描述 Supervisor 最终要判断的语义条件,Runtime 不自行解释。
  • expectedArtifacts 可有 0-16 个非空且不重复的精确文件路径。每项必须是规范化的项目内非私有相对路径,不接受绝对路径、目录、glob、..、符号链接越界或现有敏感/控制面路径;它描述终态必须存在并计算 SHA-256 的文件,不是 write scope。
  • repairOfDelegationIdstring | null,首轮委派固定为 nullrunIdstring | nullnull 时继续由 Runtime 按既有规则分配目标 run 身份。
  • 兼容只发生在恢复边界:旧持久 pending action 缺少新字段时,按 acceptanceCriteria=[] / expectedArtifacts=[] / repairOfDelegationId=null 的空合同读取并继续原身份恢复;不得改写、迁移或批量重建已有 pending/delivery/claim sidecar。新 native 请求不得借此省略合同字段。

Durable delivery 与结构化回执

static delivery 在 V1.16 的 parent/target Agent、Session、run、action、delegation 等既有身份之外,必须原样持久化 acceptanceCriteria / expectedArtifacts / repairOfDelegationId / structuredResult。ready receipt 和 Prepared -> Committed -> Observed claim 快照携带同一合同与结构化结果,认领后不能从模型摘要反向重建:

structuredResult = {
  contractStatus: evidence-ready | needs-repair,
  artifacts: [{ path, sha256 }],
  missingExpectedArtifacts: [path],
  verificationRequired: boolean,
  verifiedRevision: number | null,
  evidence: [{ kind, summary, path?, sha256? }],
  error: string | null
}

artifactsmissingExpectedArtifacts 必须恰好分割全部 expectedArtifacts,路径保持合同中的精确相对路径;存在的普通文件在形成终态回执时重新计算 SHA-256。evidenceerror 只允许有界、已清洗的安全摘要、项目内相对路径和哈希,不得保存凭据、绝对路径、私有 observation 正文或 Provider payload。旧空合同 delivery 可以继续没有 structuredResult,且不得为了升级格式改写原 sidecar;新带合同 delivery 进入 ready/claimed 时必须有完整 structuredResult

客观门禁与语义验收

Runtime 只在以下客观条件同时满足时写 contractStatus=evidence-ready:子任务终态是 completed;全部 expectedArtifacts 存在并已取得 SHA-256;当该子 run 按既有 revision 规则需要验证时,verification gate 为 passedverifiedRevision 有效。任一条件不满足时,能够安全形成终态结果的 delivery 写 needs-repair;身份冲突、sidecar 损坏或结果未知仍沿用既有 fail-closed / needs-reconciliation,不能伪装成可返工的普通回执。

evidence-ready 只表示“证据具备被验收的资格”,不表示语义自动通过。Supervisor 必须逐条结合 acceptanceCriteria、专业 Agent 摘要、artifact 哈希、verification 和其它 evidence 做最终语义裁决;Runtime 不按关键词、摘要自报或文件存在代替该裁决。artifact 或 verification sidecar 损坏、读取失败等结果未知状态不得降级成普通 needs-repair,而要保持 delivery 未认领并把原 Supervisor run 置为 needs-reconciliation

单层 repair

Supervisor 只有在同一父 run 已认领原 delivery,且原回执为 needs-repair 或 Supervisor 明确判定语义未满足时,才能发出新的 agent.delegate,并把 repairOfDelegationId 指向该原 delegationId。被引用记录必须属于同一 project-supervisor 父 run、状态为 claimed-by-parent,且自身不是 repair;返工目标必须与原 delivery 的专业 Agent 完全一致。

repair 深度固定为 1;同一原 delivery 同时最多存在一个非 suppressed repair。相同 durable action/身份重放必须幂等复用已预留或已创建的 repair;不同 action 的重复或并发竞争必须在 delivery 锁内发现既有非 suppressed repair 后拒绝,不能创建第二个活跃目标 run、第二份可认领回执或 -dup-* repair。repair 结果继续唤醒、认领并收束到原 Supervisor Session/run;它不能创建第二条面向用户的 assistant。repair 再次 needs-repair 时不得继续嵌套委派,Supervisor 只能基于现有证据裁决或走用户输入门禁。suppressed repair 不视为已完成返工,原 repairRequired 门禁必须继续阻断 finalization;同一 durable action 可以在无终态字段时把原 delivery 恢复为 dispatched,若该 action 已持久失败,新 action 也只可在既有 repair 全部 suppressed 时创建替代的基础设施投递,不能形成第二轮语义返工。

Supervisor 认领回执后必须能够再次从 durable delivery 取回权威返工合同,不能依赖首次 agent.run_status observation 或模型记忆。普通 agent.run_status 要返回有界的 claimedDelegateContracts 目录,至少包含 delegationId / targetAgentId / repairOfDelegationId / contractStatus / acceptanceCriteriaCount / expectedArtifactsCount;带可选 delegationId 查询时,只允许原 project-supervisor 父 run 读取属于自己且已 claimed-by-parent 的 delivery,并返回未截断的 delegationId / targetAgentId / acceptanceCriteria / expectedArtifacts / repairOfDelegationId / deliveryStatus / terminalStatus / contractStatus。该查询是只读、可幂等重放的私有 observation,不返回 task 正文、Provider payload、凭据或绝对路径;合同超过明确有界输出上限时失败关闭,不能截断后让模型猜测。返工被“合同未完整继承”拒绝时,失败 observation 必须携带同一 durable delivery 的完整 claimedDelegateContract 权威快照,Supervisor 可直接逐字段据此修正;该字段缺失或身份不确定时才必须按原 delegationId 重读,不得重复无目标地轮询状态或从 action history 的摘要反推。

Prompt 与完成门禁

  • 专业 Agent 的 task prompt 必须带完整委派合同:delegationId / task / acceptanceCriteria / expectedArtifacts / repairOfDelegationId,以及当前 Agent/Session/run 与父 Supervisor 身份;同时明确它只提交内部回执和证据,不直接回答正式用户。
  • 结构化计划 checkpoint 只有在步骤或状态真实变化时才允许单独提交。当前 in_progress 步骤所需事实、权限和合同已经齐全时,Agent 必须在同一 Provider 响应附带具体 action;格式修复也必须保留原本可执行的动作意图,不能连续只改 explanation 或反复只调用 update_agent_plan。Runtime 的未完成计划 observation 和 nextStep 使用同一口径,真实 E2E 对 repair 创建另设有界父 loop 门禁。
  • Supervisor prompt 必须明确:不得把 evidence-ready 当作自动语义通过,不得忽略或吞掉 needs-repair;对无法自行裁决的冲突、缺失决策或用户偏好,只能汇总后通过既有 user.input_request 向用户提问,专业 Agent 与 child 不得各自直达用户。
  • finalization 在项目锁内必须确认所有必要 static delivery 已终态、ready 已认领、claim 已 Observed、允许的单次 repair 已收束;同时要求结构化计划全部完成,并清零 verification、pending confirmation、user.input_request、process/reconciliation、isolated join、Goal/steer 等既有 blocker。只有原 project-supervisor Session/run 可以随后写入唯一正式用户 assistant 和 completed 投影。

Provider 多 action 原批次门禁

为了让 Supervisor 在同一原生 planning 中提交两个专业委派,同时保持确认顺序和崩溃恢复,Provider 一轮返回 2-3 个 action 时必须先建立私有 durable action batch,再允许任何成员产生工具副作用。批次绑定 project、Agent、task、Session、run、loop、steer cursor、完整计划、项目 revision、仓库上下文指纹及全部稳定 actionId;不能在恢复时重新请求 Provider 或重建新身份。

  • Runtime 必须先对整批 action 完成本地策略和 MCP policy preflight。任一成员被拒绝时整批进入 aborted,所有成员保持零工具执行,只投影一份稳定拒绝 observation;存在确认成员时整批进入 waiting-confirmation,收集完全部精确确认之前,位于确认动作前后的 auto 成员都不得执行。
  • 全部确认完成后批次进入 ready,从 nextActionIndex=0 按 Provider 顺序执行。连续安全只读成员仍可复用 V1.27 parallel-read batch;两个 agent.delegate 虽按顺序完成 durable dispatch,但 child lane 可在第二个 dispatch 后并行运行。任一成员返回非 ok、same-run steer 或仓库上下文漂移时,剩余后缀先持久标记为 superseded,不得继续执行。
  • cursor 只能在成员的 observation、公共投影、receipt、Agent DB 和 context bundle 全部持久化后推进。Runner 重启必须分别恢复缺失的 confirmation sidecar、尚未首次 dispatch 的 ready 批次,以及“cursor 已推进但 observed pending 尚未删除”的窗口;相同 actionId 的恢复只补缺失投影,不增加物理副作用、receipt 或 action event。
  • waiting-confirmation / ready / aborted / superseded / completed sidecar 未完成幂等收束前,空 action 完成分支和 finalization 都必须由 runtime.provider_action_batch blocker 阻断。Goal pause/resume 不得把 ready 批次降级成普通 planning,而要保留原 loop、steer 与 action cursor 并投影 provider-action-batch

Provider 瞬态失败显式重试

真实 Swarm 会同时放大多个长 tool-plan 请求,上游连接在尚未返回任何可解析响应时可能出现 timeout、connectivity 或 transport 失败。Runtime 不得把 LlmClient.maxRetries 恢复成单 lifecycle 内部的隐式 HTTP 重放;已有 agentLlm.<agent>.maxRetries / retryBackoffMs 改由 Runtime 解释为可审计的物理请求重试上限和基础退避。

  • 每个物理尝试继续使用单次请求 client,并写自己唯一的 started -> completed | failed | interrupted Provider lifecycle。首次 slot 保持原值;第 N 次瞬态重试使用稳定后缀 -transient-N,因此 requestId、slot 和 lifecycle 都可区分,不能把两次物理请求伪装成同一条 lifecycle,也不能覆盖失败终态。
  • 只允许 timeout / connectivity / transport 进入显式重试。Provider 已返回但工具协议格式无效时继续走既有 repair-N 请求;HTTP 业务错误、配置错误、非法请求、反序列化、空回复和重试耗尽仍按当前 run 失败。重试发生在响应被解析和任何工具副作用之前,不创建 action、pending、receipt、delivery、conversation assistant 或项目 revision。
  • 每次重试前重新构建无自动重试的 LLM client,按 retryBackoffMs * 2^(N-1) 有界等待;等待结束后重新经过 Provider snapshot 的 Goal、steer、cancel、task/run 和 orphan lifecycle 门禁。期间收到控制请求时不得启动下一次物理请求;Runner 强杀后只有 started 无可信终态仍进入 reconciliation,不因配置了重试而自动补发。
  • 公共重试审计只保存 Agent/task/Session/run、request kind、原 request slot、重试序号、最大次数、错误 kind、错误指纹和字符数,不保存 URL、请求/响应正文、function arguments、凭据或绝对路径。验收必须逐 requestId 证明 lifecycle 无重复、全部已终态,并把失败物理尝试与 retry audit 一一对应;最终成功允许此前存在已闭合的瞬态失败,但不允许孤立 started、同 requestId 双终态或副作用重放。

验收口径

确定性测试至少覆盖 strict native schema、路径与数量边界、旧 action 空合同恢复且 sidecar 字节不迁移、合同字段跨 Runner 重启保持、客观 evidence-ready / needs-repair 判定、artifact SHA-256、verificationRequired、claim 快照、语义不自动通过、单层 repair、同原 delivery 并发 repair 幂等/拒绝、repair 后 final barrier,以及专业 Agent/child 无用户 assistant。

真实 gpt-5.5 swarm 验收必须在无固定工具顺序和修复配方的任务中,由同一 project-supervisor 父 run 并行委派两个专业 Agent;其中一份弱交付必须形成可解释的 needs-repair 或被 Supervisor 判为语义不满足,并恰好触发一次 repair。验收期间强杀并重启 Runner,证明合同、delivery/claim/repair 身份和原父 Session/run 不丢失;最终正式用户 conversation 只有一条由 project-supervisor 写入的 assistant。全量 task/event/action/delivery/claim/receipt/conversation/Provider lifecycle 交叉检查必须得到重复 action、receipt、message 均为 0,且凭据、私有正文、绝对路径、诱饵和 Provider payload 泄漏均为 0

2026-07-16 本地确定性回归已完成当前实现切片:project_supervisor_ 30/30、provider_action_batch_ 12/12、parallel_read_batch_ 8/8、终态 receipt reconciliation 1/1 PASS,另有 native agent.delegate 合同从 function call parser 到执行器和 durable delivery 的贯通测试 1/1 PASS。覆盖真实 artifact SHA-256、缺失产物与 verification gate、旧 Ready sidecar 字节不迁移、同原 delivery 双线程 repair 竞争只产生一个活跃 delivery/task/audit、错误目标与 repair-of-repair 拒绝、suppressed repair 持续阻断且同 action/新 action 基础设施恢复、父 lane 忙时损坏 verification 持续重试并在释放后进入 reconciliation、多 action 整批预检、零副作用拒绝、确认聚合、修改后验证 gate 滚动、稳定 cursor 恢复、Agent DB 终态先于 cursor 推进、steer 作废后缀及 Goal resume 不回退 cursor、规范字段和别名的显式空合同执行器拒绝,以及 repair 前零 assistant、repair 后唯一 Supervisor assistant/completed。正式 GUI 接入后的 appSurface.test.ts 当前为 280/280 PASS,覆盖首页首条需求只投递 active Supervisor Session、已有项目恢复、非终态 run same-run steer、专业 Agent 只读状态、开发入口隔离、legacy 项目对话零新增双写和唯一终态 assistant。Runner 重启扫描会再次发布终态 child 并重新挂接 reconciliation 重试,但本轮尚未完成强杀验收。

2026-07-17 正式 openai_chat / gpt-5.5 supervisor-swarm 完整 PASS:同一 native Provider 批次产生 2 个初始 agent.delegatedesign/quality 两个专业 Agent 的物理 Provider 区间真实重叠;2 份初始 delivery 经 1 个 Observed claim 的 2 条 receipt 认领,质量弱交付经 1 次 targeted contract read 创建唯一继承原合同的 repairrepair 再由第二个 Observed claim 的 1 条 receipt 认领。repair 待确认动作前后完成 Linux pidfd Runner 强杀、boot 变化、恢复扫描和同一父 Session/run 身份保持;最终只有 1 条 project-supervisor 用户 assistant3 条专业 assistant 只留在内部 Session。

正式报告包含 46 个 Provider request identity46 started / 46 terminal / 46 completed / 0 failed;成功计划 24/24、格式修复 20/20 均使用 native_runtime_toolswrapper/text fallback 为 0。父计划 5 步全部 completed,2 个公开项目文件通过宿主验证;4 个 run 共 16 个 finalization stage。delivery、message、action lifecycle、executing action、receipt、Provider lifecycle 的重复计数均为 0pending/batch/finalization/confirmation/user-input sidecar 均为 0steer、Provider payload、私有正文、API Key、项目绝对路径、正式配置路径、报告、secret 和 lure 泄漏均为 0。suite 只使用 sentinel 管理的隔离 AppData,正式配置 CLI 调用为 0,源 Runner endpoint 未变化,隔离 Runner/AppData 已清理。

V1.29 Project Supervisor 受控瞬态重试真实门禁

2026-07-17 新增独立 supervisor-swarm-transient-retry 真实门禁,补足上述 0 failed 报告未触发显式重试的证据缺口。suite 在正式 AppData 的同级目录创建 sentinel 管理的一次性 AppData,只把 design-director 配置指向本地回环 fail-first 代理,并把该 Agent 设为 maxRetries=1 / retryBackoffMs=100;正式 AppData 目录和文件只读,其他 Agent 保留源配置。代理在首个 POST 向真实 upstream 转发正文前主动断开,第二个请求先停在 forwarding gate;验收器在放行前交叉读取 lifecycle、retry audit、action、pending、receipt、delivery、claim、conversation、project revision 和目标产物,随后才让同一重试请求进入真实 Provider。代理只保留计数,不保存或输出 upstream URL、headers、Authorization、请求/响应正文或凭据;E2E 启动 CLI/Runner 时把 127.0.0.1 / localhost / ::1 合并进 NO_PROXYno_proxy,防止继承的系统 HTTP 代理先接触凭据或正文。源配置副本和临时 overlay 均为 0600source-dir guard 必须证明源目录未出现本 suite 前缀的事件或残留项,配置 inode/内容和 Runner endpoint 身份保持不变,并由 sentinel 清理隔离目录。源目录 mtime/ctime 不能作为归因证据,因为并发正式 Runner 会合法刷新 endpoint heartbeat。

最终加强版正式 openai_chat / gpt-5.5 复验 PASS46 个 Provider request identity 全部形成唯一终态,46 started / 46 terminal / 45 completed / 1 failed,恰好 1 条 retry audit;失败 attempt 与后继 -transient-1 使用不同 request identityAgent/task/Session/run/source/request kind 保持一致。forwarding gate 放行前 action、receipt、专业子委派、claim、assistant、pending、project revision 和 upstream forwarding 均为 0。代理观察到的 10 个目标 Agent 请求与该 Agent lifecycle 数量一致,其中 1 个注入失败、1 个暂停、9 个转发。放行后仍完成 2 个初始专业 Agent 真重叠、2+1 delivery、2 个 Observed claim、1 次 targeted contract read、唯一 repair、pidfd Runner 强杀/boot 恢复、5 步父计划、唯一 Supervisor assistant 与 3 条内部专业 assistant27/27 成功计划和 14/14 repair 均为 native_runtime_tools。重复、残留 sidecar、Provider payload、私有正文、API Key、项目/正式配置路径、报告、secret 与 lure 泄漏均为 0source-dir suite-prefix guard 与 sourceAppDataDirectoryUntouched 证明正式 AppData 未被写入,物理请求/lifecycle 一一对应和失败 partial checkpoint 门禁均通过,代理、隔离 Runner/AppData/项目全部清理。

该受控 suite 是 V1.28 协议与恢复的故障注入门禁,不替代后续自主 Swarm 验收。现有 fixture 明确给出两个专业方向、同轮要求和一次 repair 上限;“Supervisor 在不提供 Agent ID、并行配方或 repair 次数时自主选择编排”仍需独立 supervisor-swarm-autonomous 真实 suite 证明。真实 --swarm-chat、同一 run 的 static delivery + isolated all-join 组合以及 Tauri/WebView 宿主级 Supervisor GUI 也仍是单独完成项。

V1.30 Project Supervisor 自主终端协作验收

V1.30 新增独立 supervisor-swarm-autonomous-chat 真实 Provider suite,同时证明 Project Supervisor 的自主专业编排和正式 agc:chat / --swarm-chat 入口。它复用 V1.28 的 static delivery/claim/repair、External Runner、隔离 AppData、确认、恢复、finalization 和唯一回复事实源,不新增 Agent、调度器、Provider 客户端或第二套对话持久化。现有 supervisor-swarmsupervisor-swarm-transient-retry 继续分别承担固定协议链和受控瞬态故障门禁,不能被本 suite 替代。

  • 唯一用户任务只能表达业务结果,例如把试玩项目推进到可交给首批玩家体验并汇报交付、验证和风险;任务不得出现静态 Agent ID、Agent 数量、同轮/并行要求、planning 轮次、返工/repair 次数、原生工具名、run/action/delegation 身份或 Runner 操作。一次性仓库规则只描述玩家体验规格、发布质量记录、语义验收、修改后验证和安全边界;不得指定由哪个 Agent 承担、必须同批委派、必须返工几次或调用什么工具。
  • fixture 提供一项缺失的体验规格和一项“客观文件/验证存在但语义仍不满足”的质量记录。质量记录在初始阶段必须先独立审阅再允许修改;harness 只通过项目 policy 暂时拒绝质量角色写入,弱回执被父 run 认领后解除 policy,不发送 steer、不改业务文件、不补充新任务。初始弱回执必须是 completed + evidence-ready 且无缺失产物,确保后续 repair 来自 Supervisor 对 acceptance criteria 的语义判断,而不是 Runtime 自动把客观失败标成 needs-repair
  • --swarm-chat --init <project> 必须由真实发布二进制启动,省略 parentAgentId 后进入 project-supervisor;用户任务通过 stdin 发送,所有确认也经同一终端 approve 入口完成。允许 Supervisor 先做必要读取,但首个包含专业委派的 native Provider 批次必须自主选择至少两个不同规范专业 Agent,并在同批形成两个初始合同;两个 child 的真实 Provider lifecycle 必须重叠,不能用同一 Agent 的 retry/format repair 或仅凭 delegate action 时间冒充并行。
  • 弱质量 claim 进入 Observed 后,Supervisor 必须在同一父 Session/run 自主创建引用原 delivery 的唯一 repair;目标 Agent、acceptanceCriteria 和 expectedArtifacts 必须完整继承,repair action 必须晚于弱 claim、早于唯一最终回复。repair 待确认边界继续执行 pidfd Runner 强杀与 boot 恢复,任务、delivery、claim、pending action 和 Provider started 身份不得漂移或重放。
  • 终局必须同时满足:严格 host oracle 判定两项产物语义正确,最后修改后的验证凭证有效;[turn.report] 为 v1/settled、父 Agent/Session/run 与 journal 一致、新增 assistant 恰好 1、队列和 reconciliation 计数为 0;正式用户会话只有 1 条 user 和 1 条 Supervisor assistant,专业 assistant 仅留在内部 Session;无 steer、重复 delivery/action/message/receipt/Provider lifecycle、残留 sidecar、Provider payload、私有正文、API Key、诱饵、项目/正式配置路径或报告泄漏,隔离 Runner/AppData/项目全部清理。任何一次带更明确提示的重跑都只能算新的失败后尝试,不能与原 run 拼接成 PASS。
  • agent.message 的语义身份固定绑定来源 Agent/run、目标 Agent/已解析 Session 和清洗截断后正文 SHA-256。同一语义消息重放只能复用唯一 conversation message 与 agent.runtime.agent.message 审计,并以 messageAppended=false 返回 durable no-op;不同正文、目标、Session、来源 Agent 或来源 run 仍是新消息。该 no-op 不得计入上下文窗口的新进展,也不能替代专业 Agent 自身最终回执。若模型持续重复同一消息,Runtime 最迟在当前完整 6 轮停滞窗口结束时写 failed / budget-exhausted / loop-budget-exhausted,保留原 in_progress 计划,不写 completed 或伪造成功回复;每个尝试的 action/observation/receipt 仍须完整落账且公共 receipt 不保存消息正文。

2026-07-17 最终正式 openai_chat / gpt-5.5 诊断轮 PASS。唯一业务任务未提供 Agent ID、Agent 数量、并行、工具、repair 或 Runner 配方;Supervisor 在 1 个 native planning 批次自主选择 2 个不同专业 Agent,真实 Provider 区间重叠,并在同一父 Session/run 完成 2 份初始 delivery、1 次语义 repair、2 个 Observed claim、严格宿主验证、pidfd Runner 强杀、boot 切换和身份稳定恢复。最终 [turn.report]settled,正式会话新增 Supervisor assistant 恰好 1,内部专业 assistant 为 3;父计划 4/4 completedpending/running/confirmation/user-input/reconciliation 均为 0

该轮共形成 110 条 task、197 条 event、330 条 Agent DB 和 9 条会话消息;51 个 Provider request identity 全部唯一闭合为 51 started / 51 terminal / 51 completed / 0 failed,28/28 个成功工具计划和 19/19 个格式修复均为 native_runtime_toolswrapper/text fallback 为 0。delivery、message、action lifecycle、executing action、receipt、Provider lifecycle 的重复计数均为 0,所有 batch/finalization/confirmation/user-input sidecar 为 0Provider payload、私有正文、API Key、诱饵、项目/正式配置绝对路径和报告泄漏均为 0。隔离 AppData 自动清理;保留的 disposable 项目经 sentinel/进程核对后手动删除。此前两次独立尝试在 maxRetries=0 下各遇到 1 次外部 Provider 终态失败并在恢复边界前停止,均只作失败证据,未与本轮拼接。

确定性 background_agent_runtime_bounds_duplicate_agent_message_livelock 同时证明:6 次同指纹 Runtime action/observation/receipt 全部实际落账,目标 conversation、conversation.messageagent.runtime.agent.message 各仅 1 条,后 5 次为 durable no-op,第 6 轮保留 in_progress 计划并进入 budget-exhausted,不存在第 7 次 Provider 请求、context compaction 或 completed 投影。

V1.30 至此只证明自主 static 专业编排与真实终端聊天可组合;同一父 run 的 static delivery + isolated all-join 真实组合恢复,以及 Tauri/WebView 宿主级 Supervisor E2E 仍需各自独立门禁。

V1.31 Project Supervisor 静态与隔离子 Agent 混合协作门禁

V1.31 新增独立 supervisor-swarm-static-isolated-autonomous-chat 真实 Provider suite,用于验证同一个 project-supervisor Session/run 可以自主同时使用 static agent.delegate 与 dynamic agent.spawn_isolated(joinMode=all),并由同一个完成屏障、恢复链和 finalization journal 唯一收束。该 suite 复用 V1.28-V1.30 的 static delivery/claim/repair、isolated group/result/join delivery、External Runner、--swarm-chat、隔离 AppData 和零泄漏事实源,不新增调度器、对话入口、结果 sidecar 或第二种用户回复。

  • 用户任务只明确业务范围包括仓库既有的正式交付、临时检查和实际验证,不得出现 Agent ID、数量、并行、static/isolated、delegate/spawn/join、repair 次数、run/action 身份或 Runner 操作。一次性仓库规则可声明既有验证要求和安全禁用边界,但不得指定 Agent 编排工具、调用顺序或 Runner 配方。Supervisor 系统策略要求提交首个协作批次前分别枚举长期专业交付与临时隔离检查;两类都非空时不得遗漏任一类。
  • 首个形成协作的 native Provider 批次必须包含两个不同 static agent.delegate 与一个 agent.spawn_isolatedspawn 请求固定 joinMode=all,三个 child 的 expectedArtifacts 指向三个既有证据文件,writeScopes 互不重叠。批次必须先停在 waiting-confirmation / nextActionIndex=0,唯一 provider_action_batch.confirmation_required 与唯一 approval 都绑定 spawn 和原批次,approval 必须早于三个 action 的任何真实副作用;随后每个 action 的 side effect、observed、receipt 和终态 observation 严格按 actionIndex 推进。两个 static child 的 Provider 区间必须真实重叠,且至少一个 static child 与一个 isolated child 的 Provider 区间也必须真实重叠,不能用 action 时间、同 Agent retry 或格式修复冒充并行。
  • static 与 isolated 继续使用各自 durable 事实源。static 的 2 份初始 delivery 与 1 份 repair 分别由两个 Observed claim 认领 2/1 份 receiptisolated 形成 1 个 group、3 个唯一 instance/result、1 个 all-join delivery,并由同一父 run 的一个 agent.run_status action 认领。两类记录的 parent Agent/Session/run 必须一致;该 suite 要求 isolated child 的项目 mutation action 和实际文件修改均为 0,但这不是把生产 isolated 权限模型改成只读沙箱。
  • completion blocker 在项目锁内先检查 plan/Goal,再按 provider-action-batch -> process -> isolated join -> static receipts fail closed,随后检查 response revision 和 verification。单一 waiting phase 只是当前首个 blocker 的 UI 投影,不是事实源;Runner 恢复和每次 finalization 都必须重新枚举两类 barrier。project_supervisor_mixed_waiting_recovery_does_not_plan_until_all_join_readyproject_supervisor_mixed_waiting_recovery_does_not_plan_until_static_delivery_readyproject_supervisor_mixed_run_status_recovery_reuses_partial_isolated_claim_after_revision_drift 三条确定性回归分别覆盖双向等待切换和同 action 部分认领恢复,不能代替真实 Provider suite。
  • repair 待确认动作持久化后执行 pidfd Runner 强杀。强杀前后必须逐项比较 static delivery/claim、isolated group/instance/result/join delivery、父 task/context、pending action 和完整 Provider started identity setboot 必须变化,任何 child/action/receipt/join 不得重放。static claim 与 isolated join claim 的 observation 都必须早于父 finalization prepared,父计划、验证、确认、用户输入、process、两类 barrier 全部清零后,原 Supervisor run 才能写唯一 assistant 和 turn.report=settled
  • 最终报告必须单独给出两类 Provider 重叠、group/instance/result/join/claim、两类 parent identity、跨恢复身份稳定、isolated 项目修改、重复 continuation/group/join/action/receipt、残留 sidecar 和公共泄漏计数。任何一项缺失、从不同尝试拼接、用户/仓库规则含编排配方、isolated 修改项目、未认领即 final 或额外用户回复都必须 FAIL;确定性回归或 V1.30 static PASS 不能替代该门禁。

2026-07-17 最终正式 openai_chat / gpt-5.5 独立轮 PASS。该轮形成 149 条 task、261 条 event、451 条 Agent DB 和 14 条会话消息;67 个 Provider request identity 全部唯一闭合为 67 started / 67 terminal / 67 completed / 0 failed,37/37 个成功工具计划与 24/24 个格式修复均为 native_runtime_toolswrapper/text fallback 为 0。首批 3 个 action 的 confirmation-required/approval 各 1 且时序有效,static-static 与 static-isolated Provider 区间均真实重叠;static 形成 2 份初始 delivery、1 份 repair 和 2 个 Observed claimisolated 形成 1 个 group、3 个 completed result、1 个 parent-wake claimed join,全部绑定同一父 Session/run。

Runner pidfd 强杀后的 boot、父 context、pending action、两类 durable identity 和完整 Provider identity set 均稳定恢复;isolated mutation action、isolated 文件修改、continuation、重复 delivery/group/instance/result/join/claim/message/action/receipt/Provider lifecycle、残留 sidecar和公共正文/凭据/绝对路径/报告泄漏均为 0。turn.report=settled,父计划 4/4 completed,正式 Supervisor assistant 恰好 1,内部专业 assistant 3、isolated assistant 3,最终 disposable 项目与隔离 AppData 均自动清理。此前不完整编排、child 合同不满足、外部 Provider 终态失败和调试验收器误判均各自作为独立失败轮停止,未与本轮 PASS 拼接。

V1.32 Runtime 强制 Supervisor 协作合同

V1.31 证明真实 Provider 可以自主形成 static + isolated 混合协作,但首波是否完整仍主要依赖 Supervisor prompt。V1.32 把该要求收进 Runtime:项目可在 .agent/collaboration-policy.json 声明协作策略,缺失时使用 requiredInitialWave=autominStaticDelegates=0requiredStaticAgentIds=[]minIsolatedChildren=0orchestratorOnlyAfterDelegation=true。该 sidecar 是独立于 .agent/policy.json 的项目私有控制面,不扩展 133 处权限策略结构体字面量;通用 file.list/read/write/patch/delete 与 patchset 底层路径统一隐藏或拒绝该文件,并在项目锁、verification gate 和 revision 变化前失败,只有宿主配置入口可以原子写入。

  • requiredInitialWave 只接受 auto / static / isolated / mixedstatic 与 isolated 模式分别至少要求一项对应协作,mixed 同时要求两类。minStaticDelegatesrequiredStaticAgentIdsminIsolatedChildren 可进一步收紧,三项必须在单个最多 3 action 的 native Provider 批次内可满足。required Agent ID 只匹配非 repair 的 initial agent.delegate,拒绝 project-supervisorchild-* 冒充静态专业 Agent;isolated 最低数量必须由同一个 agent.spawn_isolated(joinMode=all) group 的 children 满足,不能把多个不足最低数量的小 group 相加,单个 Provider 批次也最多包含一个 spawn。
  • 首波要求尚未满足时,普通读取、project.verifyagent.run_status 和计划更新仍可进行;一旦 Supervisor 请求项目 mutation 或开始任何一类协作,Runtime 必须整批预检。缺少 required mode、数量或 Agent 时整个计划形成 runtime.collaboration_policy:blocked observation,不创建 pending action、provider batch、static delivery、isolated group/child,不推进 project revision,也不执行批次中其它动作。
  • 通过预检的 Supervisor 协作批次升级为 Provider action batch v2,并持久化完整策略快照、实际 initial static Agent、isolated child 数量和合同 SHA-256batchId 同时绑定合同。即使只有一个 delegate/spawn,也强制进入 durable batch。每个成员必须先把 pending action 和 batch 成员共同持久化为 executing,随后才能创建 delivery/group 等副作用,成功 observation 落盘后才推进 cursor。恢复、确认和每次 batch 读取都必须先重新校验项目策略、合同和 batch 身份,再考虑 pending action 恢复或 replayagent.spawn_isolated 的 v2 恢复若已存在绑定同一 action 和合同的持久 group/instance,必须复用它们并只补全缺失投影,不得重复创建 group/instance 或重复记录 spawn 审计。策略漂移、合同/动作不一致或旧 v1 协作批次统一进入 needs-reconciliation,不能按旧策略启动 child,也不能让已产生的 durable delivery 反过来使当前 batch 自我拒绝。
  • orchestratorOnlyAfterDelegation=true 时,只要同一父 run 已有非 suppressed static delivery 或 isolated group,或者当前原子批次正在创建协作,Supervisor 都不得执行 file.write / file.patch / file.delete / project.patchset / project.restore / project.git_commit / command.exec / command.start / command.stdin / canvas.asset_generate。门禁在批次预检、真实工具 dispatch 前以及 project.git_commit / canvas.asset_generate 取得项目锁后再次复核;阻断不得创建 confirmation、pending action、revision 或项目副作用。MCP 只有同时声明 readOnlyHint=truedestructiveHint=false 才视为只读,破坏性或注解不完整的 MCP 在首批原子预检和委派后执行阶段都失败关闭。
  • 总控只编排门禁继续允许读取、checkpoint/diff、project.verify、受限静态验证、进程观察与收束(command.poll / command.terminate)、任务编排、黑板/消息、agent.run_status、新的合法 isolated 检查,以及继承原合同的唯一 repair agent.delegate。专业 Agent 与 isolated child 的既有工具权限不因本条改变。
  • finalization 在两类 delivery/join blocker 之外追加协作策略完成门禁。配置要求的 initial static/isolated 事实缺失、required static Agent 不完整或策略 sidecar 损坏时,原 Supervisor run 必须回到 planning,不能提交最终回复。完成事实只来自当前父 run 的 durable delivery/group,不接受 prompt 声明、计划文字或 Agent DB 诊断投影代替。
  • 确定性验收至少覆盖:不完整 mixed 首波零 child/零 revision;完整 mixed 首波形成唯一 v2 合同;executing 先于首个 durable delivery 且 cursor 正确推进;恢复先验合同并在策略漂移时零 replay;委派后 mutation 在 confirmation 前被拒绝;Git commit 与画板生成在项目锁内再次阻断;破坏性 MCP、策略文件写/patch 和 revision 推进均为 0repair delegate、isolated spawn、project.verify 和读取仍允许;batch round-trip/Runner 恢复保持 batchId、policy/contract fingerprint 和 actionId,重复 child/delivery/group 为 0。真实 Provider 另建 V1.32 suite,不能把 V1.31 的一次成功样本外推为 Runtime 合同已验收。

V1.38 覆盖说明: 本节关于“恢复、确认和每次 batch 读取都重新校验当前项目策略,live policy 漂移即进入 needs-reconciliation”的口径自 V1.38 起废止。V1.32 的既有真实 PASS 只保留为当时实现的历史证据;现行编码与恢复语义统一以 V1.38 的父 run 持久策略快照为准,不能用 V1.32 报告宣称 V1.38 已通过。

2026-07-17 在最终代码 diff 上使用 gpt-5.5 / openai_chat / high 完成 V1.32 独立真实 PASS。supervisor-swarm-collaboration-policy-mixed-recovery 只在隔离 AppData 配置副本中把瞬态重试设为 maxRetries=2 / retryBackoffMs=500,正式 AppData、源配置和 Runner endpoint 均未修改;86 个 Provider lifecycle 全部完成,本轮未触发重试。首批 v2 batch 固化 3 个 action,包含 2 个指定 static delegate 与 1 个三 child isolated spawnwaiting-confirmation 零副作用边界、pidfd 强杀恢复、batch/contract/action identity、两类 Provider 重叠、1 次 repair、3 个 delivery、1 个 isolated group/3 个 instance/3 个 result/1 个 claimed join、宿主验证和唯一 Supervisor assistant 全部通过。

成功报告共记录 178 个 task snapshot、326 个 event、556 个 Agent DB record、30 个 action execution 和 38 个 receipt;重复 delivery/group/instance/result/join/claim/message/action/receipt/Provider lifecycle 与 pending/batch/finalization/confirmation sidecar 均为 0,私密正文、Provider payload、API Key、项目路径、正式配置路径和最终报告泄漏均为 0。turn.report=settled 且 reconciliation Agent 为 0。49 次 native tool plan 中发生 30 次格式修复,未破坏动作幂等与最终结果,但说明真实链路仍有明显延迟和 Provider 调用成本,后续应单独收敛工具合同表达和 repair 频率。

V1.33 原生工具计划 repair 收敛与分类

V1.32 的真实基线是 49 次成功 native tool plan 对应 30 次格式修复。V1.33 不放宽动作、完成、权限或恢复门禁,只收敛 OpenAI-compatible Provider 的工具响应兼容边界,并让每次 repair 可以按稳定类别计数。

  • platform-llm 的 Chat Completions 与 Responses content parts 只排除明确标记为 reasoning / reasoning_content / analysis / thinking 的内部推理 part;普通 text / output_text 继续进入可见正文,独立 reasoning_content 不提升为正文。不能因为响应同时包含 tool calls 就笼统丢弃 content。
  • Agent 原生工具解析可以移除完整、大小写不敏感且嵌套闭合的 <think>...</think> 块。对于不含 respond_to_user 和旧 submit_agent_tool_plan 的 native planning 响应,剩余普通文本只作为不具执行权的 planner-commentary 丢弃,以 function calls 作为权威动作;最终用户回复、legacy wrapper、未闭合 / 错配 thinking 标签仍按 response-shape 失败关闭。成功归一化的公共审计只保存固定 complete-think-block / planner-commentary kind、数量、原文本字符数和 SHA-256,不保存正文。
  • 工具计划错误使用固定类别 response-shape / call-identity / unknown-function / arguments-json / arguments-schema / batch-constraint / plan-semantics / catalog-binding。JSON 先递归遍历所有 object key,再做 schema 解析,既稳定区分语法与 schema,也拒绝顶层及任意嵌套 input 的重复字段。repair prompt 仍可在当前瞬时私有请求中使用过滤后的错误细节,Agent DB 与 E2E 报告只保存类别、计数和既有哈希;catalog-binding 属于本地目录冲突,必须直接失败,不能重问 Provider,也不能在成功 E2E 报告中出现非零计数。
  • OpenAI-compatible planning prompt 必须把原生 function schema 作为参数事实源。legacy text JSON schema 明确只供不支持 function tools 的 Provider 使用;所有动作函数参数统一为 {"reason":"...","input":{...}},工具输入示例只描述 input 字段,禁止把 input 属性扁平到 arguments 顶层。
  • E2E 证据固定输出发生过 repair 的 loop 数、第二次 repair 数和按上述固定类别补零后的直方图;分类总和必须等于 repair 总数。完整报告和失败 partial report 使用同一聚合器,禁止输出单条错误、错误正文、preview、arguments、Agent/run/loop 身份或动态类别。
  • 确定性验收覆盖 standalone reasoning、reasoning content part、可见 content、完整 / 嵌套 / 未闭合 thinking block、非最终 commentary、最终回复正文冲突、重复 JSON 字段、八类错误、repair 审计零正文和报告聚合闭合。真实验收继续复用 V1.32 supervisor-swarm-collaboration-policy-mixed-recovery,在相同正式路由和隔离 AppData 口径下对比 49 / 30 基线,并同时检查总耗时、唯一 lifecycle、零重复、零泄漏和现场清理。

2026-07-18 第一轮诊断在旧保守正文规则下形成 35 次成功计划与 23response-shape repair,比例未比 V1.32 下降;同时新 E2E 白名单遗漏 Agent DB 固有的 schemaVersion / updatedAt,把 58 条安全审计误判为 payload leak,因此该轮 FAIL 且不作为完成证据。第二次尝试在 2 次计划、0 repair 时因 Provider 给出的 isolated child write scope 不满足业务 fixture 提前停止,同样不作为完成证据。

最终代码对应的正式 gpt-5.5 / openai_chat / high 独立轮 PASS,总耗时 631.6s(约 10 分 32 秒)。46/46 次成功计划全部使用 native_runtime_tools,格式 repair 为 0,八类 repair 直方图全为 0Provider lifecycle 从 V1.32 基线的 86 降为 54started / terminal 均为 54,其中 53 completed、1 次瞬态失败通过新的 request identity 显式重试恢复,wrapper/text fallback 和协议审计 payload leak 均为 0。相同父 Session/run 完成 2 个 static delegate、1 个三 child isolated all-join、1 次业务 delivery repair、两类 Provider 真并行、pidfd Runner 强杀恢复、宿主验证和唯一 Supervisor assistant;重复 delivery/group/instance/result/join/claim/message/action/receipt/lifecycle、残留 sidecar、私密正文、API Key、项目 / 正式配置路径及报告泄漏均为 0,隔离 AppData 与 disposable 项目完整清理。

V1.34 动态隔离子 Agent writeScopes 命令绕过封堵

V1.34 修补动态 isolated child 的作用域绕过面。writeScopes 当前只对结构化文件工具和 project.patchset 的目标路径做确定性校验,而 V1.11 的 workspace-write OS sandbox 会把项目根整体挂为可写;因此 project.verify、通用命令、持久进程或预览启动一旦交给 child,shell、构建脚本、生命周期 hook 和后代进程仍可能写到自身 writeScopes 之外。用户确认只能批准动作,不能把项目根全局可写变成 scope-aware 隔离。在 scope-aware OS sandbox 完成并通过独立门禁前,本节覆盖 V1.11、V1.12 和第 4 节中较宽的 child 工具继承口径;静态专业 Agent 与父 Agent 的既有权限不因本节改变。

有效工具边界

  • Runtime 识别出动态 isolated child 后,有效策略快照把 project.verifyproject.git_commitcommand.execcommand.startcommand.stdinpreview.startagent.delegateagent.spawn_isolatedproject.restoreagent.schedule_readycanvas.asset_generatetask.createtask.updateblackboard.writemcp.call 显示为 denied。动态 MCP function 最终归一为 mcp.call 后同样拒绝。模板 Agent、项目 policy、legacy 空策略和用户 approval 都不能放宽这组边界。
  • child 继续可使用固定受限且不接受任意 program、argv 或 shell 的 command.run_limited,当前只允许只读验证 game.static_smokecommand.output_read 只回读本 child 有权访问的既有命令输出,command.poll / command.terminate 只观察或收束已绑定同一 child/run 的既有进程,不得启动、接管、重连或向进程写 stdin。preview.validate 继续只验证当前授权项目的精确既有 loopback 预览,不负责启动预览服务。
  • 项目内容写入只保留 file.write / file.patch / file.delete / project.patchset。每一个 create/update/delete 目标都必须经过现有私有路径、链接与规范化校验,并完整落在该 child 的有效 writeScopes 内;patchset 中任一目标越界时整组修改在 checkpoint、revision 和真实文件写入前失败。其它未在本节列出的工具继续遵守既有 isolated child 限制和有效 policy,本节不新增能力。
  • child 修改后可用符合固定合同的 command.run_limited 形成当前静态试玩凭证;需要通用构建、测试或项目级验证时,由父 Agent 或静态专业 Agent 在认领 child 交付后执行。preview.validate 仍只提供浏览器证据,不单独签发项目 revision 验证门禁。child 不得伪造 verifiedRevision,也不得借 project.verify / command.exec 绕过作用域。

拒绝、批次与恢复顺序

  • 单个新 action 在 durable child 身份核对后、项目 policy 确认和 OS launcher 之前执行 scope 校验;拒绝结果不进入 waiting-for-confirmation,不创建进程、revision 或项目副作用。
  • 新的 2-3 action Provider batch 在确定 confirmation 模式前逐项执行同一 scope 校验。任一成员被拒绝时,batch 直接写成 aborted / nextActionIndex=0,不发布独立 pending-action sidecar,不创建 confirmation,也不执行同批其它成员;安全 batch 事实仍保留用于恢复和审计。
  • pending / approved 动作即使已由旧版本显示或确认,真正进入执行器时仍会重新调用当前 scope 校验,approval 不能穿透;旧 Provider batch 到达对应成员时也应用同一边界。旧 executing 且没有可信终态的通用工具继续沿用既有 needs-reconciliation 规则,Runtime 不会自动 replay。已有 child-owned process 只允许通过保留的 command.poll / command.terminate 观察和清理。

确定性验收

新增 runtime_v134_isolated_child_unscoped_commands_cannot_bypass_write_scopes,用真实恶意 bash -lc 参数尝试写入 sibling scope,覆盖单动作、两动作 batch、策略快照和旧 executing pending 的执行器重验;断言 sibling 文件不存在、nested delivery 为 0、独立 pending sidecar 不存在且 project revision 保持不变。isolated_agent::tests::write_tools_stay_inside_instance_scopes_and_dangerous_tools_are_denied 逐项覆盖完整拒绝集合和保留工具。回归范围同时运行 isolated 30 项、project_supervisor_mixed_ 3 项、supervisor_collaboration_ 27 项与 provider_action_batch_ 12 项。

V1.31 与 V1.32 的真实 Provider suite 已分别证明 mixed static/isolated 协作、all-join、Runner 恢复和唯一收束,且验收中的 isolated child 项目 mutation 为 0。V1.34 只收紧 child 的本地工具能力,不改变 Provider 请求、委派合同或回复协议,因此本切片不重跑两套外部 Provider;后续只要改变 child prompt、任务、协作拓扑或写入语义,就必须重新建立真实 Provider 证据。

后续只有 scope-aware OS sandbox 能把 child 的有效 writeScopes 转换为 OS 强制边界,保证项目根其余部分只读、链接和挂载不能逃逸、所有 shell/构建器/hook/后代进程继承同一限制,并通过跨平台越界写与恢复测试后,才可在新的版本决策中重新评估 project.verify / command.exec / command.start / command.stdin / preview.start。scope-aware sandbox 是重新开放命令的必要条件而非自动授权;project.git_commit、委派、共享控制面写入、素材生成和 MCP 仍需各自的独立安全决策,模板或项目 policy 不得提前开放。

V1.35 多 ready isolated all-join 原子认领与恢复

同一父 run 的一次 agent.run_status 可能同时看到多个 ready isolated all-join。V1.35 把这些 group 收口到同一个 action 级认领协议,避免前一个 join 已发生 delivery mutation、后一个 join 因锁竞争失败而留下半完成认领。

全锁预取与持久认领

  • Runtime 先按 delegationGroupId 对当前父 run 的 ready all-join 去重排序,再按该稳定顺序一次性预取全部 join delivery 锁。只有全部锁均已取得,才允许创建 durable claim journal 或改写任一 delivery。
  • 任一后续 join 锁忙时,必须释放本次已经取得的锁并保持零 delivery mutation、零 claim sidecar;不得先认领先序 group,也不得留下可被恢复流程误判为部分提交的 journal。
  • 全锁就绪后,以当前 actionId 和完整有序 group 集合创建同一个 durable claim journal,并按 prepared -> committed -> observed 单向推进。prepared 后发生部分 delivery commit 或 Runner 退出时,恢复必须复用同一 action journal、按相同锁顺序幂等补齐尚未提交的 group,再推进到 committed;不得生成新 action、新 claim sidecar 或重复认领已经绑定的 delivery。
  • Runtime 只认领能够完整放入本轮 readyIsolatedJoins 私有观察预算的有序前缀,剩余 ready group 保持未认领并由后续 action 继续取得;readyIsolatedJoins 固定置于 agent.run_status detail 首部,不能再被普通状态、claimed 目录或 mixed static receipt 截掉。单个 group 已超过完整观察上限时在任何 claim mutation 前失败关闭。

Observation、完成门禁与审计

  • committed 只表示全部 delivery 已绑定当前 action,不表示模型已经观察结果。只有成功 agent.run_status observation 已持久写入该 action 的 pending sidecar 后,claim journal 才能标记为 observedobservation 或 sidecar 持久化失败时保持未观察状态并由同一 action 恢复补齐。
  • 若 isolated claim 已 committed,但同一次 mixed agent.run_status 随后的 static receipt 认领失败,下一次带新 actionId 的 agent.run_status 必须先完整重放旧 claim 的 ready 结果,再继续认领 static receipt;旧 delivery 和 journal 仍绑定原 action,不为恢复 action 新建第二份 isolated claim。只有这次恢复 observation 持久化成功后,旧 claim 才能转为 observed
  • 完成门禁要求每个 claimed-by-parent delivery 都被同一 claimedByActionId + delegationGroupId 的 journal 覆盖;旧版本遗留的无 journal delivery 继续计入 unjournaledClaimedGroups,不能仅凭 delivery 已 claimed 清除门禁。agent.run_status 先重放已有未观察 claim;没有未观察 claim 时,每轮只按稳定 action 顺序为一个旧 claimedByActionId 合成 journal 并完整重放,恢复 action 不取得该 delivery,也不创建自己的 claim。多个旧 action 不得一次合并后超过观察预算。
  • 旧 delivery 对应的原 action 已存在但未覆盖该 group 的 journal 时失败关闭,不能扩写 journal、改变 group 集合或把 Committed / Observed 倒退为 Prepared;同一 group 出现在其他 action journal 时按身份冲突处理。只有 observation 中完整出现的 group 集合可推进对应 claim 为 observed,不能顺带标记本轮未输出的其它 claim。
  • 同一父 run 仍存在任一未 observed 或无 journal 的 claimed delivery 时,finalization 必须继续失败关闭,不能写入最终 assistant。
  • 每个 group 的认领审计以 actionId + delegationGroupId 为唯一键;部分提交恢复、Runner 重启和 observation 重投影都只能补齐缺失审计,不能为同一 action/group 追加重复记录。该幂等追加必须在 Agent DB append 锁内先修复 JSONL 截断尾行,再从文件头扫描有效数据库的完整记录范围并核对既有 payload;尾行撕裂、重复键或内容冲突都不能绕过唯一性。

定向验收与边界

2026-07-18 定向验收新增“后一个 join 锁冲突”“isolated 已提交、后续 static delivery 锁失败后由新 action 完整重放”“Agent DB torn tail 后 prepared/partial claim 重放”和“多旧 action 逐轮迁移”回归,并覆盖已有 journal 不扩写/不倒退、跨 action group 归属冲突与 mixed partial claim 恢复;完整 observation 必须实际包含被标记 observed 的全部 delegationGroupIdisolated 36/36、project_supervisor 42/42、supervisor_collaboration 27/27、provider_action_batch 12/12 已通过,Tauri/Rust 全量为 915 passed、4 个环境依赖用例按设计 ignored。以上定向结果只证明本地协议回归,不能单独替代外部模型链路;后续真实 Provider 结论如下。

真实 Provider E2E

2026-07-18 后续真实 Provider E2E PASS。同一父 Session/run 先创建含 2 个 child 的初始 isolated all-join group;首次 parent-wake 后、任何 join claim 前,再创建含 1 个 child 的 follow-up group。两组的精确 writeScopes 集合互不重叠,最终由同一个状态为 observed 的 join claim journal 同时覆盖两个 group。Runner 强杀/恢复前后身份稳定;Provider lifecycle 53/53 全部 completed、failed 为 0,重复、泄漏与残留均为 0。验收器自测同时覆盖跨 group scope 不重叠及 parent-wake < follow-up spawn < first claim 时序。该结果关闭 V1.35 的真实 Provider 验收缺口,但只证明当前业务合同与 Supervisor 提示形成了该轨迹;Runtime 不会预知尚未生效的项目检查,若产品要求通用强制阶段,仍需先扩展 collaboration policy 契约。该结果也不扩大解释为 scope-aware OS sandbox 或其它独立门禁已经通过。

V1.35 只收紧多个 ready isolated all-join 的认领原子性、恢复和完成门禁,不等于 V1.34 所述 scope-aware OS sandbox 已落地。该 sandbox 仍未完成,V1.34 对动态 isolated child 的命令及其它高风险工具禁用边界继续有效。

V1.37 分阶段 isolated group 首次认领硬门禁

V1.35 已证明模型可以先建立一个 isolated group,再在首次 join claim 前补齐后续 group,但该顺序此前只由任务合同和 Supervisor 提示约束。V1.37 把“达到项目要求的 isolated group 数量后才能首次认领”下沉为 Runtime 硬门禁,同时保持既有 policy、恢复路径和旧项目兼容。

Policy 兼容与分阶段门禁

  • collaboration policy v1 新增可选 minIsolatedGroupsBeforeClaim,默认值为 0,上限为 16。零值序列化时省略,因此旧 policy fingerprint 与旧 collaboration contract fingerprint 保持不变;未配置项目继续沿用原行为。
  • initial preflight 与 initial contract 仍只校验既有首波协作要求,不提前要求最终 group 总数,因此首批只创建 1 个合法 group 仍可通过。finalization completion 在既有门禁之外,再校验同一父 run 已建立的 isolated group 总数达到 policy。
  • 首次新 claim 必须先按既有观察预算选定可完整输出的 ready group 批次,再同时校验已建立的 durable isolated group 数和该批 ready group 数均达到 minIsolatedGroupsBeforeClaim。任一不足都必须在 claim journal 创建和 delivery mutation 前失败关闭。
  • 恢复优先于升级门禁:已有 durable claim、尚未观察的 claim,以及 legacy claimed delivery / legacy claim 的恢复与重放继续按原身份推进,不重新套用首次新 claim 数量门禁,避免升级后把历史状态卡死。

Read-only scope 与验收

只读 isolated task 也必须提供 expected artifact 对应的最小目录 scope。该 scope 只能覆盖完成预期产物所需的最窄目录,不得为了只读检查扩大到 sibling scope 或共同父目录;通用 Supervisor 提示必须明确这一边界,不能依赖单个 E2E fixture 的特例文案。

2026-07-18 定向回归中,supervisor_collaboration_policy_ 23/23、project_supervisor_ 47/47 全部通过,E2E self-test PASSTauri/Rust 全量为 930 passed、4 个环境依赖用例按设计 ignored。

真实 Provider 第一次独立运行因模型给出的初始 child scope 不满足 expected artifact 最小边界而 FAIL;验收确认 child、claim 和 project mutation 均为 0,现场自动清理,该失败证据不得与后续运行拼接。补强通用 scope 边界提示后的第二次独立运行 PASS:报告记录 policy=2、2 个 group / 3 个 child、1 个 observed join claim 覆盖 2 个 groupRunner 强杀恢复前后身份稳定,Provider lifecycle 64/64 completed、failed=0,重复、残留与泄漏均为 0,且只产生唯一最终回复。

V1.38 父 run 协作策略持久快照、绑定记录与漂移隔离

V1.38 把 collaboration policy 的执行语义从“每次动作或恢复都读取项目级 live policy”改为“首个有效 durable collaboration batch 为父 run 固化策略”,并用独立 binding sidecar 持久证明“该 run 曾绑定”。本节覆盖 V1.32 的 live drift reconciliation 旧口径,不改变 V1.34 的 isolated child 能力边界、V1.35/V1.36 的 claim/observation 完整性或 V1.37 的首次认领数量门禁。

线性化点与写入顺序

  • 同一 project-supervisor 父 run 的首个非 aborted durable collaboration batch 是策略线性化点。这里的 collaboration batch 必须是携带完整 v2 collaborationContract 的 Provider action batch;尚无 binding 时,只有 aborted 事实的批次不绑定快照,也不阻止后续合法批次选择届时有效的项目策略。
  • 固定提交顺序为:完整预检并构造 v2 batch/contract -> 先持久化 status != aborted / nextActionIndex=0 的 batch -> 在父 run 快照锁内 CAS 写入并验真 collaboration policy snapshot -> CAS 写入并验真独立 binding sidecar -> 两者一致后才允许任何成员进入会产生副作用的 dispatch。delivery、isolated group/child、新 join/receipt claim、项目 mutation、MCP 调用和 finalization 都不得出现在完整绑定之前;没有既存 binding 的首次 aborted batch 不创建 snapshot 或 binding。
  • batch 已落盘而 snapshot 尚未落盘、以及 snapshot 已落盘而 binding 尚未落盘,都是受支持且保持零 action 副作用的崩溃窗口。前者只能从已完整验真的 v2 contract 补绑,后者只能从有效 snapshot 补写完全一致的 binding;恢复完成后才从原 batch cursor 继续。
  • snapshot 一旦存在就是该父 run 的不可变策略事实源;binding 是独立的“曾绑定”持久记录和防降级屏障,不承载 policy 本体。后续 static/isolated spawn、repair、新 claim、Supervisor mutation/MCP 门禁和 finalization 只能使用有效 snapshot,不能在同一 run 重新选择或升级 policy,也不能通过删除 snapshot 把已绑定 run 伪装成未绑定 run。

Snapshot schema 与指纹

快照固定写入 .agent/runtime/collaboration-policy-snapshots/<agentKey>/<runKey>.json。snapshot v1 固定且完整的字段集合为 schemaVersion / projectId / parentAgentId / parentRunId / boundFrom / policy / policyFingerprint / snapshotFingerprint / boundAt,不得缺少字段或接受未知字段:

{
  "schemaVersion": "game-creator-supervisor-collaboration-policy-snapshot.v1",
  "projectId": "project identity",
  "parentAgentId": "project-supervisor",
  "parentRunId": "parent run identity",
  "boundFrom": "initial-collaboration-batch",
  "policy": {},
  "policyFingerprint": "sha256",
  "snapshotFingerprint": "sha256",
  "boundAt": 0
}
  • policy 必须先经过 V1.32/V1.37 的完整规范化和上限校验;policyFingerprint 只对规范化 policy 的稳定序列化计算 SHA-256。
  • snapshotFingerprint 对稳定身份字段计算 SHA-256,必须绑定 schemaVersion / projectId / parentAgentId / parentRunId / boundFrom / policy / policyFingerprint,不包含审计时间 boundAt。读取时逐字段复核当前项目身份和调用方 parent 身份,任何未知 schema、未规范 policy、非法指纹、跨项目或跨 run 内容都失败关闭。
  • boundFrom=initial-collaboration-batch 用于正常线性化,boundFrom=legacy-provider-batch-contract 用于从可信 v2 contract 恢复。boundFrom=legacy-current-project-policy 仅允许没有 snapshot/binding、没有可信 v2 contract,且不存在 contractless/v1 collaboration batch,并由 durable run 身份与状态明确证明仍处于 pending / running / waiting-for-confirmation / waiting-for-user-input 的旧父 runterminal、needs-reconciliation 或身份/状态未知 run 的状态读取不得新建 snapshot。既有 snapshot 重读保持首次 boundFrom / boundAt / snapshotFingerprint,不得按本次调用重写。

Binding sidecar 与安全路径键

独立 binding 固定写入 .agent/runtime/collaboration-policy-snapshot-bindings/<agentKey>/<runKey>.json,只保存不可变绑定身份,不复制 policy:

{
  "schemaVersion": "game-creator-supervisor-collaboration-policy-snapshot-binding.v1",
  "projectId": "project identity",
  "parentAgentId": "project-supervisor",
  "parentRunId": "parent run identity",
  "boundFrom": "initial-collaboration-batch",
  "policyFingerprint": "sha256",
  "snapshotFingerprint": "sha256",
  "boundAt": 0
}
  • binding 与 snapshot 必须在同一父 run 锁内逐字段交叉验证 projectId / parentAgentId / parentRunId / boundFrom / policyFingerprint / snapshotFingerprint / boundAt。已有有效 snapshot 但没有 binding 时可从 snapshot 幂等补写;binding 一旦存在不得删除、替换或按 live policy 重建。
  • agentKey / runKey 不能只做可能碰撞的 lossy 字符替换。原始 ID 本身满足安全路径组件规则时可原样使用;否则使用有界可读安全前缀加原始完整 ID 的稳定 SHA-256,例如 <safe-prefix>--<sha256(raw-id)>,保证 a/ba\\ba_b 等不安全 run ID 不会落到同一路径。snapshot 与 binding 必须使用同一映射。
  • 锁 key 不复用规范化后的路径片段,固定对完整 parentAgentId + NUL + parentRunId 计算稳定 SHA-256。路径 key 或锁 key 的计算不能读取 live policy,也不能因进程重启、平台路径分隔符或 locale 改变。

锁内 CAS 与恢复优先级

  • 创建或读取 snapshot/binding 必须在按完整 projectId + parentAgentId + parentRunId 身份隔离的同一锁内完成 CAS。锁内先重读两份 durable 记录:两者一致时返回首次记录并视为幂等;policy、项目、父 run 或任一绑定字段冲突都失败关闭,通用原子 replace 不能覆盖已经绑定的 snapshot/binding。
  • 恢复优先级固定为:existing valid snapshot > 完整验真的 v2 batch contract > 符合严格状态门禁的 legacy 当前有效 project policy。最后一层不是一般回退,只允许无 snapshot/binding 且身份可信、状态明确属于 pending / running / waiting-for-confirmation / waiting-for-user-input 的旧父 runexisting snapshot 与 v2 contract 不一致时是同一父 run 的 durable 身份冲突,进入 reconciliation,不得以 live policy 裁决哪份更新。
  • 从 v2 contract 迁移前必须先完成不依赖 snapshot 的两阶段校验:batch v2 schema、project/Agent/run 身份、action 成员与顺序、batchId、contract schema、规范 policy、policy fingerprint 和 contract fingerprint 全部成立。不得先把未验 contract.policy 写成 snapshot,再让后续 batch 校验失败。
  • snapshot 存在而 binding 缺失时,从有效 snapshot 补写 bindingbinding 存在而 snapshot 缺失时,只能用完整验真的 v2 contract 按 binding 中的首次身份恢复 snapshot。matching binding 已存在时,完整验真的 aborted v2 contract 也可用于重建原 snapshot,因为这是恢复既有绑定而不是建立新绑定。binding 与恢复结果不一致、binding 损坏,或者 binding 已证明曾绑定而 snapshot 丢失且没有可信 v2 contract 时,都保持零新副作用并失败关闭,禁止按 live policy 重绑。
  • durable collaboration batch 的 contractless/v1 形态必须先失败关闭并进入 needs-reconciliation,不能跳过旧 batch、读取 live policy 后把 run 当成 fresh run;不含协作动作的 contractless/v1 batch 不受该门禁误伤。没有 snapshot/binding、没有上述旧协作 batch且没有可信 v2 contract 时,只有 durable task/run ledger 能同时证明父 run 身份和 pending / running / waiting-for-confirmation / waiting-for-user-input 状态,才可用 legacy-current-project-policy 迁移;terminal、needs-reconciliation 或身份/状态未知只允许无副作用读取状态。尚无任何 durable run/collaboration 事实的真正新父 run可在首批 planning/preflight 读取当前 project policy,并把它固化进首个 v2 contract,但这不创建 legacy snapshot。

绑定后的统一读取与漂移语义

  • 绑定后,planning prompt、batch preflight/validation、后续 spawn、agent.run_status 新 claim、Supervisor mutation、破坏性 MCP 判断、completion blocker、finalization 创建与 finalization 恢复都必须通过同一个 effective-snapshot resolver 取得有效 snapshot,并核对 matching binding。项目级 .agent/collaboration-policy.json 不再参与这些执行裁决。
  • global project policy 相对 snapshot 的状态只允许报告 matched / drifted / unreadable:当前有效 policy 与 snapshot 相同为 matched,有效但不同为 drifted,读取或解析失败为 unreadable。三者只进入有界状态与诊断元数据;planning prompt 继续渲染 snapshot 中的规范 policy 本体,不改变现有 JSON 外形。漂移状态不能改变后续 spawn、claim、mutation、MCP、finalization 或 batch replay,也不能制造 project revision、verification 或 reconciliation。
  • policy 更新只供后续新父 run 在其首个非 aborted collaboration batch 选择;已有 snapshot 的 run 不原地重绑。需要应用新策略时必须创建新父 run,不能通过删除 snapshot、重写 batch 或 status 查询迁移活跃 run。
  • durable claim 恢复优先于 effective snapshot 解析和新 claim 门禁。已有 Prepared / Committed / Observed static 或 isolated claim、尚未观察 claim 及 legacy claimed delivery,允许先按原 action/group 身份幂等重放或补齐;global policy 漂移、snapshot 缺失或 binding 故障都不能把已经提交的 claim 卡成第二次认领。恢复路径不得取得新的 delivery。只有创建新 claim 时,才必须先成功解析 effective snapshot 并核对 binding;解析失败必须发生在新 claim journal、delivery 锁与 delivery mutation 之前,成功后再执行 V1.35-V1.37 的全锁、预算、完整观察和 group 数量门禁。

本轮验证状态

  • 2026-07-19 确定性门禁已完成:E2E self-test PASS,同时覆盖 modern provider_action_batch.confirmation_required 与 legacy tool_confirmation_required、requirement/approval/receipt 唯一性、confirmation execution mode、目标 Session/run 和严格持久化顺序;snapshot/binding 的终态预期改为由已验真的非 aborted v2 collaboration batch 决定,不再用 mixed suite 拓扑代替 durable 事实。supervisor_collaboration_ 52/52、provider_action_batch_ 12/12、project_supervisor_mixed_ 5/5 通过;Tauri/Rust 全量为 949 passed、4 个环境依赖用例按设计 ignored,check:rustfmt 通过。
  • 确定性覆盖包含 snapshot 的 9 个完整字段、首次 aborted 零绑定与 matching binding 的 aborted v2 恢复、batch -> snapshot -> binding 双故障窗口、CAS 冲突、篡改 contract、binding/snapshot 丢失组合、contractless/v1 协作批次失败关闭与非协作批次兼容、legacy 非终态迁移与终态拒绝、危险 Agent/run ID 路径及锁隔离、global policy 漂移、已有 claim 恢复与新 claim 失败关闭。新增 supervisor_collaboration_policy_snapshot_survives_terminal_runtime_cleanup 证明终态只删除 pending/provider batch/confirmation 等临时 sidecarsnapshot/binding 字节保持不变且 resolver 继续返回 run-snapshot
  • 真实 supervisor-swarm-static-isolated-autonomous-chat 曾在单次独立运行中完整形成 2 个 isolated group / 3 个 child、1 个 observed join claim 覆盖两组、唯一 repair、宿主验证、Runner pidfd 强杀恢复和唯一 Supervisor assistantsnapshot/binding 均为唯一、字节及字段稳定,global policy drift 被观察,重复、临时 sidecar、正文、API Key、项目路径和配置路径泄漏均为 0。但该轮运行期间正式客户端在测试外部重启了正式 Runnersource endpoint 所有权门禁按设计失败,因此该功能样本不能记为 PASS。
  • 随后使用权限为 0700/0600、不含 endpoint/锁/会话的私有配置源副本隔离正式客户端干扰,source endpoint、源目录和清理门禁均稳定;五次最小 OpenAI-chat 探针全部 HTTP 200。然而多次独立完整运行仍在长链路耗尽 transient Provider retry。最后一轮隔离 overlay 已提高到 requestTimeoutMs=300000 / maxRetries=3 / retryBackoffMs=500,仍在首个业务批次前形成 4 个 failed lifecycle / 3 个 retry 后终止,child、delivery、claim 和项目 mutation 均为 0,现场清理与泄漏门禁通过。失败轮不得与前述功能完整轮拼接;截至当前,V1.38 独立真实 Provider E2E 仍未 PASS,需在外部 Provider 稳定后以最终代码重新独立运行。

V1.39 首次规划 Provider 瞬态重试持久等待态

V1.39 把 V1.28 的显式瞬态重试从单纯进程内退避扩展为可跨 Runner 重启恢复的持久等待态。本切片只覆盖后台 tool-plan 的首次请求(repair-0)以及该请求前自动触发的 context-compactionfinal-reply、手动压缩和 tool-plan repair-N 仍使用进程内重试,因为现有持久上下文不能仅凭请求指纹无歧义重建这些请求。

上述范围是 V1.39 当时的历史边界;final-reply 自 V1.40 起按下一节升级为持久重试,手动压缩和 tool-plan repair-N 仍保持进程内重试。

Sidecar 与提交顺序

  • 每个 Agent/run 最多存在一条 .agent/runtime/provider-retries/<agentKey>/<runKey>.json。安全 ID 原样使用;危险 ID 使用有界安全前缀加完整原始 ID 的 SHA-256,避免 lossy 替换碰撞。记录使用严格 v1 schema,拒绝未知字段,并绑定 projectId / agentId / taskId / sessionId / runId / source / goalId / goalRevision / goalSnapshotFingerprint / appliedSteerCursor / requestKind / baseRequestSlot / requestFingerprint / providerConfigFingerprint / webSearchEnabled / allowIdleContextCompaction,以及下一 requestSlot / attempt / maxRetries / backoff / retryAt / errorKind / errorFingerprint
  • 每个物理请求继续使用 max_retries=0 的 Provider client。瞬态失败先闭合当前 started -> failed lifecycle,再写 retry audit,随后原子提交 sidecar 和 .previous,最后把 task/state 投影为 running / waiting-for-provider-retry 并释放 Agent lane。sidecar 未可信落盘前不得宣称进入等待态;task/state 已投影但 sidecar 缺失,或两者身份冲突时进入 needs-reconciliation,不得猜测补发。
  • 首次请求保留原 slot;第 N 次持久重试固定使用 <baseRequestSlot>-transient-N。同 attempt 的重复写必须字节语义幂等,attempt 只能逐一递增,不能跳号、回退或在同一 sidecar 中排队多个请求。
  • sidecar 只保存错误类别/哈希、请求与配置指纹和恢复身份,不保存 prompt、messages、tool arguments、Provider 正文、API Key、配置文件绝对路径或项目绝对路径。

恢复、并行与控制

  • Runner 启动扫描 provider-retriesprimary 缺失时允许从原子 .previous 恢复,并对 primary/previous 去重。未到期记录只重建定时唤醒;到期后先重新校验 cancel、steer、Goal、task/run、Provider 配置和重建请求指纹,再沿原 Session/run/loop/attempt 发出一个物理请求。重启不得清零 attempt,也不得因进程启动提前发送。
  • waiting-for-provider-retry 释放当前执行 lane,因此其它 Agent 可继续并行;同 Agent 后续 pending task 仍被该 running task 阻挡,保持 FIFO。每个 project/Agent/run 的定时唤醒必须 singleflight,重复 resume 或到期通知不能制造第二个物理请求。
  • cancel、终态、重试耗尽和有效 steer 会删除旧 sidecarsteer 使用同一 run 的新 cursor 重新规划,不复用旧 attempt。Goal pause 保留 sidecar且零请求,resume 校验完整身份后恢复原等待态;即使暂停跨越秒级时间边界,也必须保留相同 request fingerprint 和 -transient-N slot。
  • 请求指纹只包含实际 Provider 请求的稳定语义。工具策略的 updatedAt 等刷新时间只用于 Runtime/UI 投影,不进入 planning prompt;否则一次普通 pause/resume 或 Runner 等待跨秒就会把同一请求误判为上下文漂移并作废 sidecar。
  • 活跃 sidecar 同时阻断 finalization 与 runner.shutdown_if_idle。Runner 只有在 retry sidecar、pending action、confirmation、finalization、进程会话和其它 durable 工作全部清空后才能进入 idle shutdown。

验收边界

确定性回归必须覆盖:未到期零请求、到期唯一请求、耗尽清理、cancel、steer、Goal pause/resume 跨秒保持正文与 attempt、自动 context-compaction 先恢复再进入 tool-plan、sidecar 先于 task/state 的 torn projection、Runner 重启扫描、同 Agent FIFO、跨 Agent 并行、finalization/idle blocker、.previous 恢复/去重/排序和危险路径身份。原有 final-reply/repair 进程内重试回归必须继续通过。

V1.39 的真实 suite 把受控故障放在 Project Supervisor 首次 tool-plan,此时尚无子 Agent in-flight Provider 请求;否则强杀共享 Runner 会让无可信终态的旁路请求按既有 orphan 规则进入失败关闭,不能用它证明单一 retry sidecar 的恢复。隔离 collaboration policy 要求首批同批产生 design-director + quality-review 两个 static delegate,单委派由正式 preflight/协议修复拒绝,不能只依赖提示。故障代理使用 30s 退避与 metadata-only 时间日志:只记录请求序号及 acceptedAtMs / faultInjectedAtMs / heldAtMs / forwardingStartedAtMs,不记录 URL、method、headers、正文或凭据;退避期强杀后,sidecar 完整身份、字节、attempt、slot 和 retryAt 必须保持不变,重启后与到期前请求数均为 1,第二个请求的网络接收时间不得早于 retryAt

2026-07-19 最终代码的确定性门禁已通过:provider_retry_ 19/19、provider_transient_retry_ 6/6Tauri/Rust 串行全量为 968 passed、4 个环境依赖用例按设计 ignored,cargo check、rustfmt、编码与 diff 检查通过。

同日最终代码的独立 openai_chat / gpt-5.5 / high 真实 Provider suite PASS,最终样本单轮耗时 891.1s。37 个 request identity 全部形成唯一终态:37 started / 37 terminal / 36 completed / 1 injected failed / 1 retryincidental Provider failure/retry 均为 0;目标父 Agent 的首次请求在正文转发前断线,retry sidecar 与 task/state 完整进入等待态后执行一次 pidfd Runner 强杀,新 boot 从旧 boot 恢复同一父 Session/run/loop/attempt。强杀前、重启后、到期前代理请求数均为 1,early request 为 0,第二个请求 acceptedAtMs >= retryAtMs,后继仅有一个稳定 -transient-1 identity。放行后完成同批两个指定 static delegate、专业 Provider 真重叠、2 条初始 delivery + 1 条继承原合同的 repair、2 次 Observed claim、宿主验证、5 个父计划步骤、唯一 Supervisor assistant 与 3 条内部专业 assistant;重复 lifecycle/action/receipt/delivery/message 均为 0pending/confirmation/finalization/provider-action-batch/provider-retry sidecar 全为 0Provider 正文、私有正文、API Key、项目路径和正式配置路径泄漏均为 0,代理、Runner、隔离项目与 AppData 全部清理。验收器按 request identity 区分受控注入与真实网络抖动:额外瞬态失败只有逐条通过既有 lifecycle/retry/后继终态门禁并以相等 incidental failure/retry 计数公开时才允许继续,不能混入注入链。此前首批合同不完整、在专业 Agent in-flight 时强杀、sidecar-first 投影窗口误判、单委派和额外已恢复 Provider 抖动样本均只保留为独立失败证据,不与本次 PASS 拼接;V1.38 的真实 E2E 结论仍独立记账。

V1.40 最终回复 Provider 瞬态重试持久恢复

V1.40 把后台 final-reply 请求及其前置自动 context-compaction 分别以 requestKind=final-reply / final-reply-context-compaction 接入 V1.39 的 per-Agent/run retry sidecar。专业 Agent 或 Project Supervisor 已完成工具行动、协作回执认领和验证后,如果最终回复发生 timeout / connectivity / transportRuntime 不再在 Runner 进程内 sleep;当前物理请求先闭合为 failed,再提交 retry audit 和 sidecar,把 task/state 投影为 running / waiting-for-provider-retry 并释放执行 lane。Agent DB Provider lifecycle 校验必须接受两个 request kind,避免压缩请求在网络调用前被拒绝并静默落入 planning fallback。

可重建请求与恢复阶段

  • final-reply Provider 请求不再序列化整份临时 tool-plan,也不把会随 waiting -> planning -> response 改变的 Runtime 投影写入 prompt。最终回复只使用稳定的任务、Goal、steer、仓库/会话上下文、已获准 observation,以及可从 context bundle 精确恢复的规范收束摘要;摘要只包含经过项目路径脱敏和有界截断的 thinkingSummary / fallbackResponse。retry sidecar 仍只保存身份、请求/配置指纹、attempt、slot、到期时间和错误元数据,不保存 prompt、消息正文、工具输入或凭据。
  • 进入 final-reply Provider 请求前,Runtime 必须先把 response 阶段的计划步骤与 context bundle 同步落盘,避免 sidecar 已提交而 bundle 仍停在旧 planning 快照。恢复扫描允许 requestKind=final-reply / final-reply-context-compaction 归属原 task 的 response / waiting-for-provider-retry 投影;sidecar-first 窗口可用已有 context bundle 补齐等待投影。
  • Runner 恢复任务时虽然公共 state 会先投影为 planning,但执行 pass 必须先读取当前 run 的 retry sidecar。命中 final-replyfinal-reply-context-compaction 时直接用 bundle 的 nextLoopIndex 恢复原 loop 并跳过新的 tool-plan;后者先按原 base slot 重建并完成同一压缩请求,再生成原 final-reply。请求、Provider 配置、Goal、steer 或项目 revision 任一稳定身份变化时,旧 sidecar 删除并记录仅含字段名的 retry_superseded 审计,随后同一 run 回到新 planning;不得把旧回复提交或继续旧 attempt。
  • 流式 final-reply 的失败 attempt 标记为 failed/discarded,不把半句作为 assistant;恢复 attempt 沿同一 response-stream 基础身份单调推进 sequence。Provider 成功返回后当前实现先删除 retry sidecar 并写 ready stream,唯一 canonical assistant 仍只在后续通过原 finalization journal 后写入;该顺序的崩溃窗口按下方边界显式保留。Goal pause/resume、cancel、steer、同 Agent FIFO、跨 Agent 并行和 idle blocker 继续复用 V1.39 语义。

验收边界

  • 确定性测试必须分别停在“final-reply 或其前置压缩 retry sidecar 已提交、task/state 尚未投影”的窗口,确认恢复前 phase 仍为 response、重启扫描补齐 waiting 状态且网络接收时间不早于 retryAt;到期后必须直接恢复原 -transient-1 final-reply,或先恢复原 final-reply-context-compaction 再继续 final-reply,不得多一次 tool-plan。失败与恢复两次 HTTP body 必须逐字节相同,只在失败信息中公开 SHA-256、字节数和首个差异位置,不公开正文。
  • 终态必须只有 1 条 completed task、1 条 conversation assistant 和 1 个 committed response streamfinal-reply lifecycle 固定为初始 started -> failed 加恢复 started -> completedretry audit/waiting 各 1provider retry sidecar 为 0。前置压缩恢复还必须形成 final-reply-context-compaction 的两组唯一 lifecycle,并且不增加 tool-plan。最终实现的当前验证计数统一见 V1.41,不再沿用本切片较早的局部计数。
  • V1.40 尚未以真实外部 Provider 完成 final-reply 退避期 Runner 强杀门禁,因此不得把 V1.39 首次 tool-plan 的真实 PASS 外推为 V1.40 PASS。后续独立 suite 必须在 Supervisor 已完整认领专业回执、完成 repair 和宿主验证后,对首次 final-reply 注入唯一瞬态故障;退避期强杀后证明原父 Session/run、request fingerprint、retryAt 和 slot 稳定,且 delivery/claim/receipt/finalization/assistant 无重复、终局零 sidecar/泄漏。手动压缩与 tool-plan repair-N 仍不在本切片内。
  • Provider 成功返回到消费端 durable commit 之间仍有独立崩溃窗口:final-reply-context-compaction 的成功响应在压缩 sidecar 落盘前、final-reply 的成功响应在 finalization journal prepared 前都可能因 Runner 退出而丢失并重新请求 Provider。当前 response stream ready 不是 durable 结果提交协议;finalization journal 清理后到 stream 标记 committed 之间退出或写失败,还可能留下已持久化唯一 assistant、但展示 stream 仍为 ready 的终态差异。V1.40 只保证瞬态失败后的请求恢复与最终 assistant 幂等,不能把它扩大为成功请求 exactly-once 或 stream 终态事务;后续须以可重放成功响应 journal 和可恢复 stream commit 或等价提交协议单独解决。

V1.41 Provider 成功响应持久交接与回复流终态恢复

V1.41 为 V1.40 明确留下的成功响应交接窗口增加 .agent/runtime/provider-handoffs/<agentKey>/<runKey>.json 私有 sidecarschema 固定为 game-creator-provider-handoff.v1。每个 Agent/run 最多一条记录,绑定完整 Provider retry identity、实际已注册的物理 providerRequestId、request slot/attempt、Provider/model、脱敏文本响应、finish reason、response ID、usage、响应指纹和创建时间。schema 拒绝未知字段,记录受字段长度、安全路径和 512 KiB 硬上限约束;写入使用 0600 临时文件、sync_data、原子替换、父目录同步和跨平台 .previous 恢复副本,写后必须回读并与内存记录完全一致。

本轮实际写入 handoff 的是 tool-plan 前置自动 context-compaction、final-reply 前置自动 final-reply-context-compactionfinal-reply 三种无工具调用文本请求。手动压缩仍走非持久重试路径,不会写 handoff;tool-plan 本身的成功响应和 function arguments 也不在本轮。响应落盘前会删除 thinking block,并依次过滤密钥、项目路径和其它绝对路径;sidecar 不保存 prompt、请求消息、API Key、Provider URL、tool call/arguments 或错误正文,也不复制到公共 Runtime、event、Agent DB、CLI 或报告。

Durable handoff 提交与 handoff-first 恢复

  • 支持 handoff 的物理 Provider 请求返回成功后,Runtime 先用该次 lifecycle 实际解析出的 requestId 原子写入并回读 handoff,然后才允许同一 request identity 追加 completed 终态。handoff 写入、回读或内容校验失败时,原 lifecycle 保持只有 startedRuntime 进入 needs-reconciliation,不得自动补发该成功请求。
  • 每次可持久化请求在读 retry sidecar 或发起网络请求之前必须先读 handoff。完整 identity 相同时,Runtime 核对可选 retry sidecar 的 identity/attempt/slot,并把原实际 providerRequestIdstarted lifecycle 幂等补齐为 completed;随后删除匹配 retry sidecar 并回放响应,不注册新 started、不生成新 request identity,也不调用 Provider。
  • handoff 与 retry sidecar 同时存在时,后者必须精确指向 handoff 的 identity/attempt/slot;任一不符都进入 needs-reconciliation,不允许以任意一方覆盖另一方。同一 durable run 内若 Goal/steer/revision/request/config 等稳定 identity 已漂移,Runtime 先用旧 handoff 的实际 requestId 闭合旧 lifecycle,公共审计只记录漂移字段名,再删除旧 handoff/retry 并让同一 run 重新规划;跨 durable run 身份冲突则直接失败关闭。
  • cancel、生效 steer、非 pause Goal 控制、失败、budget-exhausted 和其它终态清理 handoff/retryGoal pause 保留原交接记录,resume 后仍消费同一响应。provider-handoffs 中任何 primary、.previous 或损坏普通文件都是 Runner busy 事实,必须阻止 runner.shutdown_if_idle,直到恢复消费、明确作废或人工核对后清理。

Compaction 消费与 finalization 固定流身份

  • 自动 context-compaction 消费 handoff 后,先原子写入规范 game-creator-runtime-context-compaction.v1 sidecar,再回读确认整条记录与本次结果完全一致,最后才删除匹配 handoff。若上次已完成 compaction 但在清理 handoff 前退出,恢复时以 source fingerprint、request kind 和 base slot 识别“没有新 source”,复用已提交 compaction 并幂等删除 handoff,不重新请求 Provider。compaction 回读或 handoff 清理失败保持 reconciliation。
  • 流式 final-reply 在 Provider 成功时调用 publisher handoff:持久化最新可见快照并停止 Drop 把它改成 discarded,但不提前写 ready。只有 handoff 完成且经规范脱敏响应回放后,才将同一 stream 身份写为 ready;中途 streaming 半句不是可提交 assistant。
  • finalization journal 正式升级为 game-creator-runtime-finalization.v4,在 prepared 时固定绑定 responseRequestSlot,并把该 slot 与 Agent/Session/run、response fingerprint/revision、steer cursor、计划和 Goal 快照一起纳入 finalizationId 指纹;篡改 slot 必须直接造成幂等身份不匹配。v3 journal 缺少 responseRequestSlot 仍可读,按 v1-v3 旧指纹规则校验,并在 stream commit 时由已绑定的 Runtime/finalization revision 与 steer 身份派生 legacy slot,不能反向伪装成 v4。project.rs 的 Agent DB agent.runtime.finalization.lifecycle 白名单必须兼容 journalSchemaVersion v1-v4,保证升级前四阶段 lifecycle 仍可扫描和幂等核对;lifecycle audit schema 本身继续为 v1。final-reply handoff 在 prepared 后仍保留,直到整个 finalization 和 stream commit 均完成后才与 journal 一起清理。
  • assistant、Runtime completed 和 Goal completed 幂等提交后,finalization 必须用 journal 固定身份读取回复流。流缺失,或仍为 streaming / failed / discarded 等非 ready 状态时,Runtime 以 journal 中的 canonical response 重建同身份 ready stream;已有流身份冲突则失败关闭。ready 正文必须与 journal 完全一致才能推进为 committed;已 committed 且正文一致是幂等成功,正文冲突则停止恢复。
  • committed 写入后必须立即回读,再次核对固定身份、status=committed 和完整正文;只有回读通过后才删除 finalization journal 与所属 handoff。stream 写入/回读失败,或在 ResponseStreamCommitted checkpoint 后、清理前退出,都保留 journal 和可恢复 finalizing 状态;Runner 重放同一 finalization,只补 stream commit 或幂等清理,不重写 assistant、不调用 Provider。

Exactly-once 承诺边界

  • V1.41 只保证 handoff 已可靠落盘之后的 exactly-once 消费:同一响应只能由匹配的 compaction 或 finalization 身份消费,恢复只回放该 handoff,不再请求 Provider,终局只有一条 canonical assistant/completed/committed stream。
  • 外部 Provider 已返回完整响应、但 Runtime 尚未写入 handoff 的硬杀窗口仍然不能承诺 Provider 调用 exactly-once。该窗口没有可重放成功响应,只能把未闭合 started 视为未知并进入 reconciliation;后续人工处理可能需要重新请求 Provider,因此不得把消费幂等扩大为端到端 Provider 物理调用幂等。
  • tool-plan 成功响应/function arguments 的 durable handoff 另行设计;真实外部 Provider 的 final-reply 退避期 Runner 强杀也仍需独立 E2E,不得借用 V1.39 首次 tool-plan PASS 或本轮确定性 mock 门禁宣称已通过。

确定性测试矩阵

范围 故障/恢复窗口 必须断言 定向用例
sidecar 契约 首次写入、同内容重写、.previous、损坏/超限/路径或内容冲突 严格 schema、0600 原子交接、实际 requestId 稳定、tool call 拒绝、thinking/密钥/路径零落盘 provider_handoff_* 单元用例
final-reply handoff-first Provider 成功交接后、lifecycle 终态前停止 恢复零新网络请求,原 requestId started -> completed,唯一 assistant/completed/committed stream,终局零 retry/handoff/finalization provider_handoff_final_reply_restart_replays_success_without_network_request
compaction consumer 前置压缩 handoff 已落盘、compaction sidecar 未提交,以及 sidecar 已提交但 handoff 未清理 压缩结果回读后清理,不重放 tool-plan/压缩,只发后续 final-reply provider_handoff_final_reply_compaction_restart_only_requests_final_reply
identity/retry 冲突 Goal/steer/revision/request/config 漂移,或 retry identity/attempt/slot 与 handoff 不一致 漂移先闭合旧 lifecycle 再作废,审计零响应正文;retry 冲突进入 reconciliation 且零 Provider 请求 provider_handoff_identity_drift_closes_lifecycle_without_leaking_responseprovider_handoff_ 冲突门禁
finalization schema/身份 v4 slot 被篡改,或读取缺少 slot 的 v3 journal 与 v1-v4 lifecycle v4 responseRequestSlot 进入 finalizationId 指纹;v3 按旧身份可读;Agent DB lifecycle 白名单接受 v1-v4 journal schema finalization_v4_binds_response_request_slot_into_identityfinalization_v3_without_response_request_slot_remains_readablefinalization_lifecycle_accepts_supported_v1_through_v4_journals
finalization 四 checkpoint Prepared / AssistantAppended / RuntimeCompleted / ResponseStreamCommitted 任一点中断 原 messageId/finalizationId 幂等恢复,无 Provider/工具重放,最终 journal/handoff 清理 finalization_*response_stream_committed_checkpoint_recovers_by_idempotent_cleanup
回复流重建 stream 缺失、停在 streaming、commit 写失败、已 committed 后清理中断 按 v4 固定 slot 从 journal 重建 readycommitted 写后回读,正文唯一,冲突失败关闭 response_stream_finalization_recovers_missing_stream_after_project_revision_driftresponse_stream_finalization_repairs_streaming_after_commit_write_failureresponse_stream_committed_checkpoint_recovers_by_idempotent_cleanup
Runner busy primary、.previous 或损坏 handoff 存在时请求 idle shutdown idle=false,不进入 draining;清理后才可 shutdown durable_provider_handoff_prevents_shutdown_even_when_corrupt

2026-07-20 当前最终实现的最新验证证据为:provider_retry_ 21/21、response_stream_ 23/23、finalization_resume_ 12/12Tauri/Rust 串行全量共 989 tests985 passed / 4 ignored / 0 failed。这些数字替代 V1.40 较早快照,后续当前结果统一使用本行口径。

上表是 V1.41 的确定性门禁,不代表真实外部 Provider E2E 结论。除表内窗口外,还必须继续扫描 task/event/Agent DB/CLI/report,确认 Provider 响应、compaction summary、API Key、Provider URL 和项目/配置绝对路径公共泄漏均为 0。

V1.42 Project Supervisor final-reply 瞬时重试 Runner 强杀真实门禁

V1.42 不改变生产 Runtime、Provider lifecycle、retry sidecar、handoff、finalization 或 response stream 协议,只扩展一次性 loopback fault proxy 和真实 E2E harness。新 suite 固定为 supervisor-swarm-final-reply-transient-retry,发布 AppData 复验入口为:

npm run ai-game-creator-shell:agent-runtime:supervisor-swarm-final-reply-transient-retry-real-e2e -- --config-dir <发布AppData绝对路径>

受控故障选择与命中前事实

  • fault proxy 的异步 shouldInjectFault selector 只接收 Object.freeze({ sequence, acceptedAtMs })。selector 不得看到或保存 URL、header、请求/响应 body、API Key 或其它凭据,也不得靠解析 Provider payload 判断请求种类;代理既有 metadata-only 请求日志边界保持不变。
  • harness 只能选择当前 project-supervisor 父 Agent、同一父 Session/run 的唯一 base final-reply started lifecycle;带 -transient-N 的后继、专业 Agent/child 请求、tool-plan 和 context-compaction 都不得成为注入目标。候选缺失、重复或身份不符必须让 suite 失败,不能退回“首个请求”语义。
  • 命中 base final-reply 前,持久选择上下文必须已经证明:恰好 2 条初始 delivery 加 1 条 repair delivery 均为 claimed-by-parent / completed;两次 observed claim 完整观察这 3 条 receipt;父 conversation assistant 仍为 0,且项目 revision 与 final-reply task identity 有效。候选或这些事实不唯一时不能注入,也不能退回“首个请求”语义。
  • selector 必须在 proxy 对目标请求执行 reset 或正常 forward 之前,以可信宿主 Node 在 disposable project cwd 同步运行固定命令 node verify-e2e.mjs。只有命令正常结束、stdout 含 real-e2e-command=passed,且 stdout/stderr 均不含 real-e2e-command=failed 时才返回允许注入;spawn 失败、超时、非零退出、marker 缺失或冲突一律返回不注入。捕获的 stdout/stderr 只用于本次内存判定与敏感扫描,失败内容不得进入 selector state、checkpoint、report 或公共日志。
  • 父 run 的 project.verify audit/receipt/observation 数量与顺序继续写入有界诊断字段,但它们不是 fault injection prerequisite;计数为 0 也不能单独阻止注入,更不能替代上述可信宿主 marker oracle。

30 秒退避、Runner 强杀与恢复

  • base final-reply 必须先形成唯一 started -> failed lifecycle、唯一 retry audit 和已原子落盘的 provider retry sidecar,并把父 task/Runtime 都投影为 running / waiting-for-provider-retry。只有完整等待态成立且 retryAt 仍留有保护窗口时,才允许对本 suite 持有的 Runner 执行 pidfd SIGKILL
  • 新 boot 接管后必须保持原父 Session/run、task、request fingerprint、retry identity、attempt、next request slot、sidecar 字节和 retryAt 不变,并明确证明从旧 boot 恢复。重启后及 retryAt 前新增代理请求数都必须为 0;到期后只允许出现一个 <baseRequestSlot>-transient-1,且其 acceptedAtMs >= retryAtMs
  • -transient-1 在 forwarding gate 内仍不得进入 upstream;放行前再次核对 delivery、claim、receipt、assistant、pending、project revision、可信宿主 marker 结果和父 tool-plan 计数均未漂移。父 project.verify 只保留诊断计数,不提升为放行前置条件。放行后只能由该唯一后继成功完成,受控 failed/retry 与其它 incidental Provider failure/retry 必须按 request identity 分开计数。

终局门禁与六轮证据

  • 恢复前后的父 tool-plan started 数必须完全相等,不得为收尾新增 tool-plan。终局只允许唯一成功的 parent final-reply、唯一 Project Supervisor assistant 和唯一 committed response streamstream 身份绑定原 base final-reply slot 且正文与 assistant 完全一致。
  • retry、handoff、finalization artifacts 必须全部为 0;重复 delivery/claim/receipt/action/message/lifecycle 必须为 0。公共 task/event/Agent DB/CLI/report 中的 Provider/assistant 正文、API Key 和项目/发布配置绝对路径命中必须为 0
  • supervisor-swarm-transient-retry 继续只证明 Project Supervisor 首次 tool-plan 的持久退避与 Runner 强杀,不能替代本 suite,也不能把它的历史 PASS 外推为 V1.42 final-reply PASS。
  • 2026-07-20 确定性与静态门禁已完成:fault proxy 14/14、E2E self-test PASS、前端 308/308,以及 shell typecheck、platform-llm 41/41platform-agent 17/17shared-contracts 7/7 均通过。
  • 真实外部 Provider suite 总计执行六轮,逐轮独立裁决且严禁拼接:第一、二轮沿用既有失败记录,均为 FAIL;第三轮已走通故障、持久重试和唯一回复,但验收过早观察到 1 个 finalization journal,仍为 FAIL,随后改为终态后显式等待 sidecar 全部清零并设置 10s 硬超时;第四轮在 quality-review 的普通 tool-plan 连续发生 transport/connectivity 失败并耗尽重试,未进入目标 final-reply 故障,仍为 FAIL;第五轮暴露并修复并行 Agent 的 file.write 与项目写锁竞争,失败 observation 携带绝对锁路径,继而触发 pending 持久化拒绝并进入 needs-reconciliation,仍为 FAIL。修复后 file.write / file.patch / file.delete 统一使用 Runtime 短等待项目写锁,file.write 错误在持久化前脱敏,并新增 2 条 Rust 回归测试。
  • 第六轮在同一轮内完整 PASS:正式路由为 gpt-5.5 / openai_chat;形成 2 条初始 delivery、1 条 repair delivery 和 3 条专业 Agent assistant;受控目标精确命中 Project Supervisor base final-reply,可信宿主 verify marker 门禁通过。受控 Provider failed=1 / retry=1incidental failure=0 / retry=030s backoff 成立,pidfd claim=2 / signal=2Runner resumed=true / identityStable=true;故障前后父 tool-plan 均为 13,只产生唯一 parent final-reply 和唯一最终 assistantresponse stream 以 sequence=2 提交为 committed。pending、retry、handoff、finalization、confirmation sidecar 全部为 0,全部重复计数为 0,API Key、私有正文、项目路径、正式配置路径及公共报告泄漏扫描命中均为 0
  • 第六轮 PASS 只关闭“final-reply 瞬态失败进入持久退避后强杀 Runner”的真实证据缺口。V1.41 中“Provider 已成功返回、但 handoff 尚未原子落盘并回读”仍是 unknown-result 边界;tool-plan 成功响应及 function arguments 的 durable handoff 仍未覆盖。

V1.43 tool-plan 成功响应持久交接与 repair 链恢复

V1.43 不放宽 V1.41 的文本型 game-creator-provider-handoff.v1,而是为 requestKind=tool-plan 增加独立私有账本 .agent/runtime/tool-plan-handoffs/<agentKey>/<runKey>.jsonschema 固定为 game-creator-tool-plan-handoff.v1。同一 Agent/run 账本按 (loopIteration, repairAttempt) 单调保存已成功的 repair-0..N Provider 响应,每条绑定完整 retry identity、实际物理 providerRequestId、真实 request slot/attempt、Provider/model、去除 thinking 后的响应、thinking 归一化哈希/计数、完整 function call envelope、usage、响应指纹和创建时间。账本使用既有 0600、原子替换、父目录同步、.previous 恢复和写后完整回读;未知字段、乱序/缺口、重复 slot 冲突、超限、危险可执行路径、密钥或配置痕迹一律失败关闭。

提交、重放与所有权

  • 每个 tool-plan 物理请求的顺序固定为:Provider 成功 -> tool-plan handoff 追加并回读 -> 同一实际 requestId lifecycle completed -> 解析/格式修复或动作预检。function arguments 只存在于私有 handoff 与后续 pending/action batch。protocol/repair 公共审计共同保存 agentId/taskId/sessionId/runId/source/loopIteration/repairAttempt/requestSlot/responseFingerprint/providerRequestIdSha256/protocolprotocol 只额外保存 functionCallCount/callIdSha256s/functionNames/responseIdSha256/responseIdChars 和既有 normalization 字段,其中 function names 必须由 catalog 绑定;repair 只额外保存 attempt/maxAttempts、协议错误/preview 哈希与字符数及 callIdSha256/functionNameSha256。公共 task、event、Agent DB、CLI 和报告不得保存原始 callId/callIds/responseId/providerRequestId。两类审计都在 Agent DB append 锁内按完整 Agent/task/Session/run/source/slot 身份做全历史 compare-and-append,不能以受限尾部读取替代幂等。
  • repair-0 与全部 repair-N 统一使用持久 transient retry。Runner 恢复总是从当前 loop 的 repair-0 重建请求:账本中已成功的 entry 按序零网络回放并幂等补齐原 requestId lifecycle;若某条响应需要格式修复,则用同一有界 preview/protocol error 重建下一 repair 请求。后继 repair 的 retry sidecar 可以与前序 handoff entry 同时存在,前序回放不得误删后继 retry。
  • 账本保留同一 run 已成功的 tool-plan entry,直到当前 run 完成、取消、失败、作废或明确 reconciliation 清理。这样单动作、并行动作、confirmation、协作 batch 和直接回复都不会在下一 durable owner 建立前丢失 function arguments;后续 loop 可在同一账本中追加,条目数和总字节数都有硬上限。steer/cancel/终态/漂移删除前必须按整本账本补齐所有实际 requestId lifecycle,任一条失败则保留账本并进入 reconciliation。
  • 同 slot 同 identity/response 重写是幂等成功;同 slot 指纹、requestId、attempt 或响应冲突进入 reconciliation。Goal/steer/request/config 漂移命中旧 slot 时,先按账本顺序把旧 base 与全部后继 repair 的实际 requestId 幂等闭合,再删除旧 tool-plan handoff/retry 并在同一 run 重新规划。Runner 启动恢复会严格发现 hash 归属正确的 primary/.previous;Unix 扫描和删除固定在已打开目录句柄,只回收原子命名正确、0600、单链接且 owner PID 已死亡的临时文件,活跃 owner 临时文件保持 busyWindows 拒绝 reparse/非普通项并只回收 owner PID 已死亡的原子临时文件。已终态 run 的合法遗留可回收,未知、链接、冲突或无所属任务项失败关闭并保持 Runner busy。跨 durable run、越序 entry、未来 entry 或不匹配 retry 不允许猜测恢复。
  • 有效和无效 Provider 响应都必须先做私有内容安全检查。完整 function arguments 为恢复语义不得被静默脱敏或改写;命中 API Key、Token、password/client secret/private key/credential 等敏感 key、配置痕迹,或结构化可执行路径/命令参数中的项目及其它绝对路径时,handoff 写入失败并进入 reconciliation。content / patch / plan / step / response 等正文与叙述字段仍做密钥检查,但不能用面向日志的路径 token 扫描把 HTML </tag>、源码字符串或计划标题误判为可执行路径。格式不合法但安全且有界的 arguments 可作为不执行的 opaque repair 输入持久化,只有既有严格 parser/schema/catalog 门禁通过后才可转成工具动作。未闭合或孤立 thinking wrapper 不保存 thinking 正文,只保存严格无效元数据;重放合成无正文协议标记并进入同一 repair,不能被清洗成可执行计划。

确定性与真实门禁

  • 单元测试覆盖严格 schema、原生 tool call 精确 round-trip、thinking 去除、base+repair 单调追加、幂等重写、乱序/冲突/超限、敏感内容拒绝、.previous 恢复、活跃/死亡 temp 判定、目录替换和双副本安全清理;Agent DB 审计另以真实双进程竞争固定 compare-and-append。primary、.previous 或损坏账本都必须使 Runner 保持 busy。
  • Runtime 集成测试至少在 repair-0 handoff 落盘且 lifecycle 仅 started、以及 malformed base 已完成而 repair-1 handoff 落盘且 lifecycle 仅 started 两个断点停止 Runner。关闭 mock Provider 后恢复必须零网络,原 physical request lifecycle 唯一闭合,protocol/repair audit 不重复,最终 assistant/completed/stream 唯一,终局 retry/tool-plan handoff/finalization 均为零。
  • 非默认真实 Provider 门禁 supervisor-swarm-tool-plan-handoff-runner-kill 已实现并完成 Shell/Root 两级命令注册。suite 只使用 sentinel-owned sibling AppData 和不注入故障的 metadata-only zero-fault proxy;代理为转发请求只做协议校验,但请求日志仅保存序号与时间元数据,不持久化或暴露 URL、method、headers、正文或凭据。每轮生成随机 capability,并严格绑定 disposable project、目标 Agent、run 与实际 request slot,任一身份不匹配都不得 ACK 或强杀。断点只能在目标 tool-plan handoff 已原子落盘并逐字段回读一致、同一实际 requestId 的 lifecycle 尚未写入 completed 时 ACK,随后才允许通过 pidfd 向 suite 自有 Runner 发送 SIGKILL
  • 恢复验收必须在同一轮证明:同一 requestId 只闭合一次且不产生替代 requestIdproxy 的 networkReplayCount=0protocol/repair audit compare-and-append 幂等,handoff 与恢复后 durable pending/action batch 的 plan fingerprint 对应;ACK、强杀和恢复消费前不得出现由目标计划产生的 action、pending、delivery、claim 或其它副作用。终局 retry/tool-plan handoff/provider handoff/finalization/confirmation 等 sidecar、重复 lifecycle/audit/action/message、临时 capability/Runner 资源与 AppData 残留均为 0,公共报告中的 Provider URL、headers、正文、凭据及项目/正式配置绝对路径泄漏命中也必须为 0。2026-07-20 的真实外部 Provider 单轮已证明 checkpoint、Runner boot 切换、同一请求零网络重放、恢复前零副作用与唯一生命周期闭合,但随后专业 Agent 连续连接失败使整轮 FAIL;另一独立轮首批工具数不满足 fixture,同样未通过。两轮不得拼接,当前仍无该 suite 的完整外部 PASS。
  • V1.43 仍不关闭“外部 Provider 已成功返回、但本地 handoff 尚未完成原子写入并回读”的 unknown-result 窗口;没有 Provider 级幂等键或结果查询能力时,该窗口继续进入人工 reconciliation,不能宣称端到端物理调用 exactly-once。手动 context-compaction 也不在本切片。
  • 2026-07-20 当前确定性证据:本轮 tool_plan_handoff_44/44Supervisor collaboration 相关过滤为 55/55,权威返工合同用例为 1/1Tauri/Rust 串行全量 1058 tests 为 1054 passed / 4 ignored / 0 failedLinux cargo check --testsx86_64-pc-windows-gnu cargo check --tests 均通过。E2E self-test、typecheck、变更脚本 ESLint、encoding 与 git diff --check 通过。默认并发全量只作竞态诊断,不替代 --test-threads=1。Unix handoff 存储使用固定目录句柄、根/Agent 双层 flockRENAME_EXCHANGE 安装回滚和 RENAME_NOREPLACE quarantineWindows 使用相对父句柄、GetFileInformationByHandleEx 句柄枚举与独占 temp 句柄,并拒绝 junction/reparse point 与硬链接。非协作同 UID 进程仍属于宿主 OS 信任边界,不能据此宣称完整沙箱。真实 suite 的 checkpoint 已有单轮外部证据,但整轮仍无 PASS。

验收命令

  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml structured_plan_ -- --nocapture
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml agent_goal_ -- --nocapture
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml goal_context_bundle_v4_migrates_v3_and_v2_then_rejects_plan_mismatch -- --nocapture
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml provider_handoff_ -- --nocapture --test-threads=1
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml tool_plan_handoff_ -- --nocapture --test-threads=1
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml response_stream_ -- --nocapture
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml finalization_v4_binds_response_request_slot_into_identity -- --nocapture
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml finalization_v3_without_response_request_slot_remains_readable -- --nocapture
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml finalization_lifecycle_accepts_supported_v1_through_v4_journals -- --nocapture
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml mcp_ -- --nocapture
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml provider_action_batch_ -- --nocapture
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml provider_retry_ -- --nocapture --test-threads=1
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml provider_retry_waiting_final_reply_restart_commits_once -- --nocapture --test-threads=1
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml provider_retry_waiting_final_reply_compaction_resumes_without_new_tool_plan -- --nocapture --test-threads=1
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml provider_transient_retry_ -- --nocapture --test-threads=1
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml parallel_read_batch_ -- --nocapture
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml runtime_v134_ -- --nocapture
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml isolated -- --nocapture --test-threads=1
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml project_supervisor_mixed_ -- --nocapture --test-threads=1
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml supervisor_collaboration_ -- --nocapture --test-threads=1
  • npm run agc:collaboration-policy-e2e -- --config-dir <AppData>
  • npm run agc:mixed-swarm-e2e -- --config-dir <AppData>
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml swarm_cli::tests -- --nocapture
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml typed_goal_pause_and_cancel_require_durable_intent_and_keep_exact_run -- --nocapture
  • npm run ai-game-creator-shell:typecheck
  • npm run test -- apps/ai-game-creator-shell/tests
  • cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml
  • cargo check --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml --target x86_64-pc-windows-gnu
  • cargo test -p platform-agent --manifest-path server-rs/Cargo.toml game_creation
  • cargo test -p shared-contracts --manifest-path server-rs/Cargo.toml game_creation_app
  • npm run ai-game-creator-shell:agent-run:smoke
  • npm run ai-game-creator-shell:agent-runtime:real-e2e -- --config-dir <AppData> --suite llm-runtime
  • npm run ai-game-creator-shell:agent-runtime:real-e2e -- --config-dir <AppData> --suite goal-runtime
  • npm run ai-game-creator-shell:agent-runtime:real-e2e -- --config-dir <AppData> --suite response-stream
  • npm run ai-game-creator-shell:agent-runtime:real-e2e -- --config-dir <AppData> --suite web-search
  • npm run ai-game-creator-shell:agent-runtime:real-e2e -- --config-dir <AppData> --suite context-compaction
  • npm run ai-game-creator-shell:agent-runtime:real-e2e -- --config-dir <AppData> --suite mcp-runtime
  • npm run ai-game-creator-shell:agent-runtime:real-e2e -- --config-dir <AppData> --suite user-input-runtime
  • npm run ai-game-creator-shell:agent-runtime:real-e2e -- --config-dir <AppData> --suite scoped-agents
  • npm run ai-game-creator-shell:agent-runtime:real-e2e -- --config-dir <AppData> --suite project-skill
  • npm run ai-game-creator-shell:agent-runtime:real-e2e -- --config-dir <AppData> --suite parallel-read
  • npm run ai-game-creator-shell:agent-runtime:real-e2e -- --config-dir <AppData> --suite supervisor-swarm
  • npm run ai-game-creator-shell:agent-runtime:supervisor-swarm-transient-retry-real-e2e -- --config-dir <AppData>
  • npm run ai-game-creator-shell:agent-runtime:supervisor-swarm-final-reply-transient-retry-real-e2e -- --config-dir <发布AppData绝对路径>
  • npm run ai-game-creator-shell:agent-runtime:supervisor-swarm-autonomous-chat-real-e2e -- --config-dir <AppData>
  • npm run ai-game-creator-shell:agent-runtime:real-e2e -- --config-dir <AppData> --suite full
  • npm run check:encoding
  • git diff --check