合并主分支
Project CI / Repository checks (pull_request) Failing after 14s
Project CI / Backend tests (pull_request) Failing after 11s
Project CI / Frontend tests (pull_request) Successful in 3m5s
Project CI / Native shell tests (pull_request) Failing after 10m48s

解决合并冲突
This commit is contained in:
2026-08-11 11:00:11 +08:00
52 changed files with 6018 additions and 606 deletions
@@ -6918,6 +6918,29 @@
- 安全边界:动态端口不恢复旧 Vite 复用。无法证明 worktree 归属的监听器仍不复用、不主动终止;同用户多 worktree 通过段内漂移并行,不通过共享未知服务并行。
- 验证:公共端口映射、Linux 默认槽位与段内漂移、非 Linux 兼容漂移、Tauri 动态配置、启动前预检、进程树收束、AGC typecheck / 配置门禁、编码检查和差异检查必须通过。
## 2026-08-10 AGC 默认使用 Codex CLI 作为节点 Agent
- 决策:AGC AppData 配置新增 `agentMode=codex_cli|provider`,默认切到 `codex_cli`,原 HTTP Provider 实现、配置和显式回退能力保持不变。External Runner 和现有 manifest DAG 不分叉;每个节点请求在现有 Provider lifecycle 外壳内选择执行器。
- 安全:Codex CLI 只负责结构化推理。它在空临时目录、ephemeral、忽略用户配置、read-only、never approval、禁用 shell tool 的边界内运行;项目读写、命令、MCP、Canvas、权限、revision、验证、receipt 和 reconciliation 仍由 AGC Runtime 执行。Codex 认证留在用户级 CLI,任何凭据和认证文件都不进入项目事实。
- 恢复:执行模式和 CLI 身份进入 Provider 配置指纹;模式或 CLI 变化会使旧 retry/handoff 作废并沿现有恢复合同处理,禁止跨模式复用成功交接或自动重放未知结果。
- 关联:`docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md` V1.51,以及 `docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md` 的“2026-08-10 Codex CLI Agent 执行模式”。
## 2026-08-10 AGC 默认切换为 Codex app-server 长期节点 Agent
- 决策:新增 `agentMode=codex_app_server` 并设为默认,保留 V1.51 的一次性 `codex_cli` 与原 `provider`。External Runner 内按有效 Responses 凭据/路由及 `projectId/agentId/sessionId/runId` 为每个权威节点隔离长期 app-server;稳定节点 run 对应独立进程和 ephemeral thread,节点请求对应串行 turn,但 AGC lifecycle、handoff、manifest、Agent DB 和 finalization 仍是唯一 durable owner。单节点 stdio/进程失败只能影响本节点,不得把其它并发 Agent 一并置为 reconciliation。
- 配置:有无 AGC LLM Key 都只支持 `openai_responses`;非空 Key 映射后 base URL 与逐 Agent model/effort 生效,Key 只经专用环境变量;空 Key 只桥接用户 Codex `auth.json`,移除继承环境 Key。`stream=true` 复用现有 durable final-reply delta`webSearchEnabled=true``openai_chat / anthropic` 必须显式切换 `provider`,不得静默忽略已有 LLM 配置。
- 安全与恢复:app-server 使用隔离临时 `CODEX_HOME` 与 OS HOME,只桥接认证,不加载用户 MCP/config/skills/hooks;启动前关闭 web/multi-agent/shell/browser/plugin/image 等原生能力,固定 read-only、network off、never approvalAGC 是唯一 ToolHost。取消覆盖 turn-start 回包前窗口并只发送单 turn interrupt;已开始 turn 的连接/终态未知直接标记 reconciliation,明确 failed/interrupted 不自动重试。模式与 durable 指纹取同一配置快照。
- 资源与退出:pool 按实际凭据快照/base URL/API kind/CLI 版本和节点 run 身份隔离;空 AppData Key 只允许桥接一次性读取的有界 `auth.json` 快照,并用同一字节快照生成池指纹,宿主 `CODEX_API_KEY` 对 app-server 与一次性 CLI 都必须移除。节点进程与 thread 均有上限并只淘汰 inactive LRUstdout NDJSON 与 stderr 无换行记录均有硬上限,stderr 原文不得写入错误或日志,只记录固定分类、总字节数、SHA-256 与可取得的退出状态。Runner 正常、强制、watchdog 退出显式关池;Linux child 绑定 parent-death signal,避免 Runner 被强杀后遗留带凭据孤儿进程。
- 兼容迁移:已有 AppData 未写 `agentMode` 时,仅当全局及逐 Agent 都是 `openai_responses` 才迁入 app-server;任何 `openai_chat / anthropic` 路由保持 `provider`,防止项目自动恢复先于用户改配置而批量失败。新安装仍默认 app-server;已确认兼容 Responses 的旧端点可由用户显式切换且继续使用原 model/base URL/API Key。
- 关联:`docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md` V1.52。
## 2026-08-10 Supervisor steer 改为 LLM 判定后的条件中断
- 决策:根 Project Supervisor 收到运行中消息后继续原 Run,先由独立 LLM 生成非终态回复并判断 `interruptCurrentProvider`。状态询问、解释和不冲突补充默认不中断;只有明确停止、改向或在途方案会过期时才可请求中断。过程回复持久进入原 conversation,但不得调用终态 `respond_to_user`
- 时序:steer durable 入队后不先通知 Runner。`false` 或判定失败才调用只唤醒的 `runtime.steer``true` 直接调用 `runtime.interrupt_for_steer_decision`。后者必须读取已持久化判定,并只中断 `appliedSteerCursor < steer.sequence` 的旧 Provider;新规划 Provider、工具和外部副作用不可被误杀。
- 失败:判定调用、协议解析或持久化失败时公开回复“继续当前任务”,在下一安全边界应用 steer,绝不退化为默认中断。External Runner 与本地进程内执行保持同一语义。
- 关联:`docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md` V1.53,以及 `docs/project-memory/shared-memory/pitfalls.md` 的“Supervisor steer 不能只有内部排队事件”。
## 2026-08-10 普通图片废弃 assetKind 的迁移与写入门禁
- 语义:普通静态图片的持久化 `asset_kind``NULL`,旧值 `image` 不再是合法业务类型。登录态 API 和 SpacetimeDB storage 的项目资源 / 账号素材创建边界统一将 trim 后精确等于 `image` 的输入归一为空;其它值不借本次迁移扩大或收紧既有校验。
+50 -1
View File
@@ -135,6 +135,23 @@
- 验证:用 deferred graph Promise 断言终态前 Tauri layout read/update 调用均为 0;图就绪后首次坐标直接按最终深度生成,旧 scope 迟到结果无效,手动坐标不变且相同自动布局不增加 revision。
- 关联:`apps/ai-game-creator-shell/src/view/project-development/index.tsx``apps/ai-game-creator-shell/src/view/project-development/useProjectResourceCanvasLayout.ts``apps/ai-game-creator-shell/src-tauri/src/project/resource_dependency_graph.rs`
## 等价 Runtime 投影刷新不能清空资源依赖图(2026-08-10)
- 现象:专业 Agent 运行期间,资源画布中的卡片按轮询节奏整批消失并立即恢复;停止产生新的 Runtime 时间戳后闪烁减弱或消失。
- 原因:专业 Agent 轮询会重建结果数组;资源内容虽然相同,前端图读取 effect 仍因数组引用变化重新执行,并先把图和布局置空。布局位置暂时缺失时,所有资源卡都会返回 `null`
- 处理:用包含项目与资源输入的语义 scope key 稳定图请求参数,等价输入不重复读取;同一项目的资源集合确实变化时,异步刷新期间保留上一个已解析图和布局,只有首次加载或切换项目才启用空图屏障。刷新失败继续展示旧快照,不能用瞬态失败清空画布。
- 验证:AppSurface 先用全新但内容相同的 Agent 结果数组 rerender,断言图读取仍只有一次且原卡片 DOM 保持连接;再增加真实资源并延迟第二次图响应,断言旧卡片在刷新窗口持续挂载,新图返回后新增卡片正常出现。
- 关联:`apps/ai-game-creator-shell/src/view/project-development/index.tsx``apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts`
## Supervisor steer 不能只有内部排队事件(2026-08-10)
- 现象:自主制作期间继续向项目总控发消息,用户消息已进入同一 Run,当前 Provider 也被中断并重新规划,但普通工作台短暂的提交状态消失后一直没有回复,直到整轮制作最终收束。
- 原因:steer 只持久化用户消息与内部 `steer.queued` 事件;公开事件投影又明确排除 `steer.*`。普通工作台提交后会用后端 conversation 覆盖本地消息,因此仅追加临时前端气泡也无法稳定跨刷新显示。
- 处理:根 Project Supervisor 的 steer 进入 durable `queued` 后,先写“正在判断、当前任务继续”的公开确认,再由独立 `steer-decision` LLM turn 返回自然语言回复和 `interruptCurrentProvider`。状态询问、解释和不冲突补充默认不中断;明确停止、改向或会使在途方案过期时才允许请求中断。判定和回复按 `run + steer` 持久幂等,刷新后仍可见;判定失败时继续当前任务,并在下一安全边界应用 steer。
- 并发边界:steer 入队、Runner `runtime.steer` 通知都不得直接触发 Provider interrupt。Codex app-server 的判定使用独立节点,不能等待主节点 turn 锁;判定为 true 后也只能中断 `appliedSteerCursor < steer.sequence` 的旧 Provider 请求,已经消费该 steer 后启动的新请求不可被误杀。已经开始的工具和外部动作不强杀,完成 observation 后再消费 steer。
- 验证:真实 mock LLM 回归必须覆盖状态询问回复且 `interruptCurrentProvider=false`;持久重放只保留一条语义回复;steer 入队后旧 Provider 继续运行,判定为 true 后才中断;新规划 Provider 的 cursor 已包含该 steer 时即使旧判定为 true 也不能中断。前端同秒多条消息保持“用户补充 → 判断提示/语义回复”的关联顺序。
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent/interaction.rs``apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/steering.rs``apps/ai-game-creator-shell/src-tauri/src/runner/dispatch.rs``apps/ai-game-creator-shell/src/features/agent-runtime/model.ts`
## Jenkins 异步备份不能用 nohup 脱离作业
- 现象:Stdb Publish 成功,上传日志只留下“已获取进程锁 / 上传已有备份 / 目标对象”,没有成功或可捕获错误;本地 tar.gz 和 `uploadStatus=deferred` manifest 每次发布后继续增长。
@@ -4131,6 +4148,7 @@
- 现象:延迟重试携带比既有行更旧的调用方时间,回填图片序列字段时若无条件写入,会使 `updated_at` 倒退,导致基于时间戳的同步看不到更新或排序错误。
- 处理:同源图片序列字段只允许 `None → Some`,非空冲突失败关闭;发生回填时 `updated_at = max(existing.updated_at, request_timestamp)`。legacy 音频 repair 不派生资源级图片序列或通用时长,重放继续精确匹配。
## 历史钱包消费不能从最近流水或通用订单快照推算
- 现象:后台用户详情要展示累计花费时,直接复用只返回最近 50 条的 `list_profile_wallet_ledger`,或在充值订单每行使用的通用钱包快照里扫描该用户全部流水。
@@ -4198,7 +4216,9 @@
- 原因:不是业务递归。debug 构建中 pending action continuation、后台 task queue 和 Agent 主循环各自形成大型 async poll frame;恢复路径在同一次 poll 调用链直接进入下一层状态机,累计超过 worker 默认栈。
- 处理:整个 pending continuation、它进入的后台主循环,以及完成、取消或失败后 drain 同 Agent 后续队列时,都必须跨越独立 Tokio task 轮询边界,使上层 poll 先退栈后再轮询下一层状态机。传入边界的 future 必须先装箱;若泛型 helper 直接持有大型 future,即使随后 `spawn`,调用方 async frame 仍会把它保留在默认 worker 栈上。边界必须保留结构化取消语义;当前使用 boxed future 与 `JoinSet`,父 continuation 被丢弃时同步 abort 子任务。不得只增大 CI 的 `RUST_MIN_STACK`,否则生产默认栈仍可能崩溃。
- 验证:失败用例必须在未设置 `RUST_MIN_STACK` 时通过;同时覆盖 policy batch 全组、拒绝 pending 后重规划并 drain 下一任务,以及 pending/cancellation 回归,证明恢复不重复生成 isolated spawn、队列继续推进且父任务取消不遗留后台子任务。
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/pending_execution.rs`
- 2026-08-10 补充:Provider、Codex CLI 与 Codex app-server 合并到同一个模式分发后,即使本轮实际选择普通 Provider,未装箱的组合 future 仍携带最大分支状态;委派子任务完成后回流父 Agent 的既有回归会在默认 Tokio worker 栈稳定溢出,单独运行同样失败,扩大 `RUST_MIN_STACK` 才通过。持久重试 helper 与非持久压缩路径都必须在构造完整物理 Provider request 后、进入下层泛型 control/lifecycle helper 前装箱;不要逐个扩大 queue worker 栈,也不要等到底层 helper 内部再装箱已经进入调用方 frame 的泛型 future
- 2026-08-10 验证:未设置 `RUST_MIN_STACK` 时运行 `background_agent_runtime_can_delegate_task_to_other_agent`,并追加 `provider_retry_``provider_handoff_``response_stream_` 与 Native shell 完整门禁;测试只能以默认 worker 栈通过,不能把 CI 环境变量当修复。
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/pending_execution.rs``apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/provider_retry.rs`
## Provider 可扩展不能用一个全局 protocol 枚举代替实例隔离
@@ -4451,6 +4471,7 @@
- 原因:正式 SFX handler 把计费、翻译、provider、持久化和写回内联在一个 future 中;分层测试只能证明单个 helper,不能证明组合顺序和“失败后不继续”。同时若把 mock 流程另写一遍,它本身又可能与生产逻辑漂移。
- 处理:抽出单一 Worker 编排函数和计费 / stage adapter。生产 adapter 代理现有正式实现:OSS 后只准备 asset object / binding 候选,项目资源、账号素材、画布和 job 终态通过同一原子提交落库;测试 adapter 逐段记录调用与注入失败。组合矩阵同时断言 charge / refund、LLM / provider / OSS / writeback 计数、稳定 reason code 和权威值等值。ElevenLabs 二进制、MIME、大小、timeout 和 MP3 仍由 loopback adapter 测试负责,组合 mock 不替代协议测试。
- 验证:自动 / 手动时长 × Loop 四组合成功;余额不足;翻译、HTTP、无效音频、时长探测、OSS PUT / HEAD、asset confirm / bind、项目资源、账号素材和画布写回逐点失败;所有 job provider POST `<= 1`,预扣后失败 refund `= 1`
## 生成结果的稳定 ID 和 job 终态都不能代替 durable receipt2026-08-06
- 现象:Provider / OSS 已成功,但项目资源、账号素材、binding、画布和 job 只完成一部分;不确定结果重放时,有时又复制一批素材或重复推进 canvas revision。inline 路径在进程重启后尤其无法判断前一次提交是否整笔完成。
@@ -4478,3 +4499,31 @@
- 原因:`normalize_generated_asset_folder_id` 只处理 `project`、旧 `folder-*` 和默认目录 ID 的兼容映射,不读取 SpacetimeDB;真正的 `require_owned_asset_folder` 位于生成结果持久化末端。把“失败会退款”误当成副作用补偿,漏掉退款不能撤销 provider 请求与 OSS PUT。
- 处理:所有付费编辑器生成在队列 enqueue 前和 worker / inline 执行前复用只读 `preflight_editor_generation_target_and_return`,按认证 owner 校验可选项目及归一化目录;读取失败和归属不匹配一律失败关闭。helper 返回 canonical 项目与目录并覆写后续入队 / worker / 原子准备使用的 payload,不能校验 trim 后的项目却持久化原始空白值。角色图片、角色动作、图标 spritesheet 与 UI 提取省略目录时按实际默认目录预检;默认目录允许尚未创建,自定义目录必须存在且 owned。预检不替代最终 procedure 复验,也不保证跨外部调用的目录锁定。
- 验证:源码顺序回归必须覆盖图片生成、图片修改、图标 spritesheet、UI 设计图提取、视频、角色动作、SFX 与 BGM 的 enqueue / direct 两层,证明纯本地格式和 `data:` / `blob:` 稳定引用门禁先执行,canonical target 在预检后写回 payload,远端引用解析、generation input rebuild、扣费、入队、provider 与 OSS 均留在预检之后;模块侧扫描证明预检只调用 runtime identity、项目、目录只读校验且不含 insert / update / delete,并覆盖带空白项目、`project`、旧 `folder-*`、默认目录 ID、自定义目录与 `None` 归一化。
## Codex CLI 节点不能把进程终态当成 Runtime 提交证据(2026-08-10
- 现象:`codex exec` 已启动或退出码为 `0`,但 JSONL 没有 `turn.completed`;或者已出现 `thread.started`,Runner 随后退出,重启时误以为节点已完成。GUI 进程的 PATH、安装或登录状态与交互终端不同时,还可能在默认模式下静默落回 HTTP Provider。
- 原因:CLI 进程、Provider lifecycle、retry/handoff 和 Runtime finalization 是连续但不同的 durable owner;本地进程退出不能代替现有账本的原子提交与回读。模式切换若不进入配置指纹,还会把另一执行模式的 retry/handoff 当成当前结果。
- 处理:Codex CLI 必须只作为新的节点推理适配器,继续经过原 Runtime 的 lifecycle、retry、handoff、receipt、revision、verification 和 reconciliation。只接受完整 JSONL `turn.completed` 与可验证的最终消息;`started``completed`、超时、异常退出或输出破损都继续走原失败/核对边界。`agentMode`、CLI 版本和影响输出的固定参数必须纳入配置指纹;CLI 不可用时显式报错,不得静默切回 Provider。
- 验证:确定性回归覆盖 stdin prompt、空临时 cwd、read-only/no-shell/ephemeral 参数、structured tool call 转换、缺失终态、超时进程组回收和 stderr 不泄漏;真实 smoke 必须显式 opt-in,并分开报告 CLI 协议成功与本机认证/网络结果。
## 空 MCP 覆盖不会清除 Codex 用户配置中的 MCP2026-08-10
- 现象:以 `codex app-server -c 'mcp_servers={}'` 启动后,`thread/start` 仍发出用户配置中各 MCP server 的 startup 事件;若直接把这种进程当 AGC 节点 Agent,会出现 Codex 与 AGC 两套 ToolHost、副作用和审批边界。
- 原因:Codex `-c` 对 table 做配置合并,空 table 不是“删除已有所有条目”。长期 app-server 与一次性 `codex exec --ignore-user-config` 的配置隔离能力不同,不能照搬参数后假设用户配置已清空。
- 处理:为 AGC app-server 创建权限受限的临时 `CODEX_HOME`,只桥接已有 `auth.json`,不带入用户 `config.toml`、MCP、skills、hooks 或项目 rulesmodel/provider/effort 全部由 AGC 显式传入。server→client 请求一律拒绝,原生工具 item 一律协议失败。临时 HOME 和认证桥接不得写入项目、日志或持久账本。
- 验证:协议 smoke 必须观察 `thread/start` 后没有 MCP startup 事件;fake server 还要断言 API Key 不在 argv、初始化只一次、结构化输出回到 AGC ToolHost。只看到 `initialize` 成功不能证明安全隔离成立。
## 只隔离 CODEX_HOME 仍会加载用户 Skill,且 Codex 原生工具默认不全关闭(2026-08-10)
- 现象:app-server 虽然使用临时 `CODEX_HOME` 和 read-only turn,仍可能发现 `$HOME/.agents/skills`,并默认提供 cached web search、multi-agent 及其它稳定原生能力;等 `item/completed` 后再拒绝已经太晚,工具调用和额外模型成本可能已发生。
- 原因:Codex 的用户 Skill 发现根是 OS HOME,不是 `CODEX_HOME``dynamicTools=[]` 也只清空宿主动态工具,不会移除 Codex 内建工具。read-only/network off 是副作用防线,不等于从模型工具目录删除能力。
- 处理:同时隔离 `HOME / USERPROFILE / APPDATA / LOCALAPPDATA`,并在临时 workspace 创建空 `.git` 作为仓库发现边界,防止继续向父目录(例如 `/tmp`)发现 `.codex/.agents`;启动前设置 `web_search="disabled"``agents.enabled=false`,并关闭 shell/unified exec/browser/plugin/image/workspace dependency 等原生 feature;接收 `item/started` 时只允许消息、计划、推理和压缩等被动 item,其余立即 interrupt。配置中的 `webSearchEnabled=true` 必须失败关闭并提示切 `provider`
- 验证:fake app-server 检查 argv 不含 Key、专用 Key 只在环境、继承 `CODEX_API_KEY` 被移除、HOME 指向临时目录、web/multi-agent/shell 关闭;另覆盖 turn-start 回包前 drop 最终只发一次对应 interrupt。
## 多 Agent 共享一个 Codex app-server 会放大单点终态丢失(2026-08-10)
- 现象:多个节点最初已有 `started -> completed`,随后一个 app-server stdio 连接关闭,同一秒多个仍在途节点一起进入 `needs-reconciliation`;单看 threadId 不同会误以为节点已经进程隔离。
- 原因:pool 只按 LLM 凭据和路由复用进程,节点身份只用于进程内 thread map。任一 stdout framing、子进程退出或连接故障都会 drain 整个进程的 pending/turn router,使所有共享节点同时失去可信终态。
- 处理:pool key 必须包含 `projectId + agentId + sessionId + runId`,每个权威节点直接持有独立 app-server 子进程;同节点 turn 还要串行,不能向同一 thread 并发 `turn/start`。只发送当前 CLI schema 定义的字段;stderr 使用有界内存尾部并先脱敏再进入 Runner 诊断。
- 验证:至少两个节点并发各跑多轮,确认存在两个 app-server PID;终止其中一个后只有对应节点进入 reconciliation,另一个仍能收到 `turn/completed`。旧 AppData 缺 `agentMode` 且含非 Responses 路由时必须保留 `provider`,不能在项目自动恢复时批量失败。
@@ -47,6 +47,7 @@
- 新增 Markdown 文档时,文件名必须以分类标签开头,格式为 `【标签名】中文标题-日期.md`;只在任务需要时重命名历史文档,避免无关大 diff。
- 涉及中文文本时注意 UTF-8 编码和乱码排查。
- 涉及后端时遵循 DDD 分层,不把业务真相下沉到前端或临时兼容层。
- 对已明确退役且不存在现役调用方、公开契约、持久化数据、活跃实例或迁移要求的对象,不新增历史兼容代码、维持退役行为的防御性兼容测试、墓碑注释或墓碑文档;权威文档直接更新为当前状态。公开 API、持久化数据、SpacetimeDB schema、跨版本重放、活跃实例和正式迁移仍须保留最小化、白名单化的必要兼容及契约或迁移测试,并在迁移完成后同步删除。
- 运行时日志禁止对完整配置、应用状态或 provider client 做递归 `Debug` 输出;当前 `AppConfig``AppState``AppStateInner``SpacetimeClientConfig``SpacetimeClient` 必须保持封闭的手写安全摘要,并用唯一哨兵测试锁定顶层与可独立格式化路径。其它仍使用派生 `Debug` 的历史 provider 类型不得新增整对象日志调用,后续按类型独立脱敏。新增字段默认不进入摘要,确需排障时只增加枚举、数值、布尔值或是否配置等非敏感字段。
- `packages/shared` 用于前后端 DTO、公开契约及跨页面复用的无业务真相 UI 组件和纯工具;不得把领域规则、后端副作用或正式状态放入其中。
- 修改 `/api/external/v1` 的路由、HTTP 方法、请求 / 响应 DTO、请求头、状态码、鉴权或异步语义时,必须同批更新 `docs/openapi/genarrative-external-v1.openapi.json` 和对应契约测试;Rust 实现与 OpenAPI 未对齐时不得完成、提交或发布。
@@ -1592,6 +1592,58 @@ V1.49 已经让 `agent-runtime-core` 能在不依赖 Provider 的情况下独立
- core conformance 覆盖第三方 fake Provider 注册/调用、重复与未知 ID、能力不匹配零调用和 stream callback。`platform-llm` 覆盖三种 descriptor、request/response/tool-call/stream/error 双向转换与实例隔离;AGC 覆盖 interaction 实际走 registry 及原 fallback 语义。
- 完成后运行 core conformance、`cargo test -p platform-llm --manifest-path server-rs/Cargo.toml`、AGC interaction/config 定向回归、Tauri `cargo check --tests``npm run ai-game-creator-shell:check``npm run check:encoding``git diff --check`;独立 core 生成的 `Cargo.lock/target` 交付前清理。
## V1.51 Codex CLI 节点执行模式
V1.51 在不替换现有 Provider、Runner 和 Runtime 事实源的前提下增加第二种节点 Agent 执行器。AppData `agentMode` 只接受 `codex_cli / provider`,默认 `codex_cli`;显式 `provider` 继续执行 V1.29-V1.43 的原 HTTP LLM 路径。Runner 不新增模式参数,每次节点请求从当前 AppData 配置解析模式。
### 执行与协议
- 每次 Runtime 节点的 tool-plan、格式修复、上下文压缩或 final-reply 请求仍先构建既有 `LlmRunRequest`、捕获同一 Provider snapshot,并进入原 started/completed lifecycle。`codex_cli` 分支启动一次 `codex exec`,把 prompt 经 stdin 输入,把当前函数目录转换为 structured-output schema,并把终态 JSONL 转回现有 `LlmRunResponse / LlmToolCall`
- Codex CLI 只充当推理 Agent,不充当第二个 ToolHost。调用固定使用空临时 cwd、`--skip-git-repo-check --ephemeral --ignore-user-config --ignore-rules --sandbox read-only --disable shell_tool` 和 never approval;不得加载项目 `AGENTS.md`、用户 MCP/plugin/hook 或执行项目命令。所有项目读写、命令、MCP、Canvas、权限、pending、receipt、revision 与 verification 继续由 AGC Runtime 执行。
- prompt 和 schema 有界,prompt 只走 stdin,不进入 argvstdout/stderr 有独立上限,持久审计只保存模式、版本、退出分类、字符数和指纹,不保存 prompt、函数参数、CLI 认证、本机路径或原始错误正文。CLI 非零退出、缺少终态 agent message、JSONL/schema 损坏和超限输出统一失败关闭并走既有安全错误摘要。
### 生命周期与恢复
- Codex child 绑定当前 request future 并设置 drop killsteer、取消、暂停、Runner draining 和 GUI owner 丢失继续沿现有 Provider interruption 收束。started 后没有 completed 的请求继续进入 `needs-reconciliation`,不得重新启动同一 request slot。
- 由于 CLI shell、MCP 和项目写入被禁用,Codex 请求本身没有项目副作用;但其响应交接仍可能处在未知窗口,必须继续使用 V1.41/V1.43 的 handoff 与零重放规则。`agentMode`、CLI 稳定身份和影响输出的 CLI 参数进入 `providerConfigFingerprint`,跨模式或 CLI 漂移必须作废旧 retry/handoff,不能当作同一请求恢复。
- 同 wave 并发仍由现有 per-Agent lane 和 scheduler 决定;一个节点只启动一个 Codex 子进程,依赖节点只在原 manifest 终态门满足后启动。CLI 模式不新增 Codex 内部子 Agent,也不把 Codex session 当 AGC Session 或恢复事实。
### 配置与验收
- `check_game_creator_llm_config` 在 CLI 模式只检查固定 Codex 可执行文件可启动并返回受支持版本,不要求 LLM API Key;Provider 模式保持既有检查。配置 UI 显示全局模式,始终保留旧 LLM/逐 Agent/MCP/Editor 配置;切换模式不清空任何旧值。
- fake Codex fixture 必须覆盖 argv/stdin、structured calls、final text、非零退出、挂起取消、损坏/超限 JSONL、无 shell/MCP 参数和并发节点;真实 smoke 只复用用户已有 Codex 登录态。旧 Provider smoke 继续作为回退模式门禁,不能被新 CLI smoke 替代。
## V1.52 Codex app-server 长期节点 Agent 模式
V1.52 保留 V1.51 一次性 `codex_cli` 和原 HTTP `provider`,新增 `codex_app_server` 并切为默认。External Runner 按实际 LLM 凭据、Responses 路由与 `projectId / agentId / sessionId / runId` 为每个权威节点隔离长期 `codex app-server --stdio` 子进程;节点 run 在自己的进程内映射一个 ephemeral Codex thread,每次权威 `LlmRunRequest` 快照映射一个串行 turn。Codex thread 不是持久恢复真相,Runner 重启后仍只依据 AGC lifecycle、retry/handoff、manifest、Agent DB 与 finalization 重建工作。
### 配置、认证与安全边界
- `apiKind` 在有无 API Key 时都必须为 `openai_responses`;非空 Key 由 app-server 启动参数注册隔离 model providerbase URL 和 `wire_api=responses` 显式生效,Key 仅通过专用环境变量传入,不进入 argv、日志、项目或指纹明文。`openai_chat / anthropic` 不伪装兼容,配置检查明确要求切换 `provider`。API Key 为空时只使用用户现有 Codex `auth.json` 登录态,model 与 reasoning effort 仍取当前有效 Agent LLM 配置;继承的 `CODEX_API_KEY` 必须移除,避免实际账号与池/账本身份不一致。
- app-server 使用带空 `.git` 边界的临时 cwd、隔离 `CODEX_HOME` 和隔离 OS `HOME / USERPROFILE / APPDATA`,让仓库发现停在临时 workspace,并只桥接用户已有 `auth.json`;不得沿临时目录父级加载配置/skills,也不加载用户 `config.toml`、用户 skills、MCP、hooks 或项目 rules。启动前显式设置 `web_search="disabled"``agents.enabled=false`,并关闭 shell、unified exec、浏览器、插件、图像、workspace dependency 等原生能力;thread/turn 固定 never approval、read-only、network disabled,并只发送当前 Codex CLI schema 声明的字段。任何 server→client 审批/交互请求失败关闭,任何非被动 item 在 `item/started` 即中止。AGC Runtime 继续是唯一 ToolHost,因此 `webSearchEnabled` 在本模式必须为 `false`;需要原 Provider 联网检索时切换 `provider`
- Pool key 绑定本次实际凭据快照指纹、base URL、API kind、Codex CLI 版本与权威节点 run 身份:非空 AppData Key 指纹绑定实际注入的专用环境变量字节,空 Key 则先一次性读取有界 `auth.json`、按同一份字节生成指纹并复制进隔离 `CODEX_HOME`,登录态变化后不得复用旧池连接。最多保留 32 个节点进程,仅淘汰没有外部 lease 的 LRU 连接。每个连接最多保留 128 个 inactive LRU thread,但正常只服务自己的节点身份。Provider 配置指纹另外绑定模式、CLI 版本、app-server 协议、model/effort、安全参数和 output schema 合同。逐 Agent override 与不同节点不得共享进程。
### turn、取消与恢复
- JSON-RPC stdout 使用有界 NDJSON 行,stderr 按固定块排空并对无换行单条记录设置硬上限;两条路径在没有换行时都不得无限增长。stderr 原文不进入错误、Runner 日志或持久记录,只累计固定分类、总字节数与 SHA-256,并同时记录可取得的 exit status。协议继续使用单调 request ID、有界 pending RPC map 与 turn event routerinitialize 每个进程 generation 只执行一次。`stream=true` 的 final-reply 把 `item/agentMessage/delta` 转成现有 `LlmStreamDelta`,半句仍只是可丢失展示缓存;只有 `turn/completed` 且最终 agent message 满足 output schema 后才转换为 `LlmRunResponse / LlmToolCall`,随后仍走既有成功 handoff 原子写入和回读。
- 当前 request future 被取消、暂停或 drop 时只发送对应 `turn/interrupt`;取消状态从 `turn/start` 写出前就建立,若取消与 turn ID 回包乱序,双方通过共享槽位恰好一次补发 interrupt。异常路径立即删除本地 turn routerorphan pending RPC 在 30 秒后自清理。app-server EOF、损坏 JSON、`turn/start` 回包丢失或已开始 turn 的等待超时属于终态未知,必须进入 `needs-reconciliation`,仅关闭当前节点进程且不得作为瞬态错误自动重放同一 request slot;其它节点进程继续运行。明确 `failed / interrupted` 是确定失败,不做 transport retry。
- 执行模式与 Provider 配置指纹必须来自同一次配置快照;不能先捕获 executor、再重新读取 `agentMode` 生成 durable identity。Runner 正常/强制/watchdog 退出都会显式关闭池;Linux 子进程额外设置 parent-death signalRunner 被 SIGKILL 时也不能遗留持有凭据的 app-server。
- 每个 turn 输入仍是 AGC 构建的完整权威消息快照,因此复用 thread 会累计完整轮次历史;这只影响进程内推理上下文和 token,不改变 AGC durable owner。后续若改为增量消息协议,必须另行版本化 request fingerprint 与恢复合同,不能静默改变本模式输入语义。
### 验收
- fake app-server 覆盖 initialize、thread/start、turn/start、structured output、delta、turn-start 回包前取消、凭据只进专用环境变量、隔离 OS HOME、原生能力关闭和跨配置/CLI 版本 pool 隔离;定向测试覆盖三态默认/round-trip、unknown terminal reconciliation 与旧 `codex_cli/provider` 回归。真实模型 smoke 为 ignored/显式 opt-in,避免自动消耗用户 Provider。
## V1.53 Supervisor 运行中非终态回复与 LLM 条件中断
V1.53 把根 Project Supervisor 的 same-run steer 从“收到消息立即中断”改为“先回复并判断、按需中断”。用户消息仍先进入原 run 的 durable steer ledger 与 conversation;公开确认明确说明正在判断且当前任务继续运行。随后由独立 LLM turn 调用严格 `runtime_steer_decision`,一次返回自然语言 `reply``interruptCurrentProvider` 与安全原因。该回复按 steer 身份持久幂等,是制作过程中的非终态对话,不调用 `respond_to_user`,也不关闭 task、Goal、Run 或 finalization。
- 命令层在 durable 入队后不得先通知或唤醒 External Runner,避免 Runner 抢先消费 steer 后让判定快照漂移。判定为 `false` 或判定失败时,才发送只校验 ledger 并唤醒任务的 `runtime.steer`;该 RPC 必须固定返回 `providerInterrupted=false`。判定为 `true` 时直接发送 `runtime.interrupt_for_steer_decision`,由该 RPC 完成条件中断并唤醒同一 run。本地进程内路径遵循同一顺序。
- 状态询问、解释、鼓励、确认和不冲突补充默认不中断;只有明确停止、改向,或继续当前方案会产生明显过期结果时才允许 `true`。判定使用当前有效 `provider / codex_cli / codex_app_server` 模式;app-server 以独立 synthetic 节点运行,不能等待主节点的 turn gate。
- 条件中断必须先读取已持久化 decision,并只允许中断注册时 `appliedSteerCursor < steer.sequence` 的旧 planning/final-reply Provider。若旧请求已自然结束,或新 Provider 已消费该 steer 后启动,则返回 `providerInterrupted=false`,不得误杀新规划。工具、外部副作用、确认、process session、Git、receipt 和 finalization 始终不强杀,在下一安全边界消费 steer。
- LLM 判定、解析或持久化失败时写入关联的非终态 fallback 回复,保持当前任务运行,并在下一安全边界应用已排队 steer;失败不能退回“默认中断”。判定与回复按 `agentId / runId / steerId` 幂等,冲突终态失败关闭。
- 验收必须覆盖判定 LLM 的 `true / false` 协议、公开回复幂等、入队本身不中断、`runtime.steer` 有活动 Provider 时仍不中断、缺失 decision 拒绝条件中断、`false` decision 不中断、`true` decision 只中断旧 cursor,以及判定失败后同一 run 继续。
## 验收命令
- `cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml structured_plan_ -- --nocapture`
@@ -84,6 +84,33 @@
## Runtime 边界
### 2026-08-10 Codex CLI Agent 执行模式
- 模式合同:客户端 AppData 配置新增全局 `agentMode`,只接受 `codex_cli / provider`。缺省和新安装默认使用 `codex_cli`,原有 HTTP LLM Provider 路径完整保留并可显式切回 `provider`;切换只影响下一次节点请求,不新增 Runner、任务图、会话库、配置库或业务事实源。
- 调度边界:正式 DAG、manifest、Agent task/session/run 身份、队列、锁、委派、all-join、完成门、Provider lifecycle、持久 retry/handoff 与 `needs-reconciliation` 继续由现有 AGC Runtime 掌控。每个被调度节点在 `codex_cli` 模式下直接启动一次非交互 `codex exec` 充当该节点的推理 AgentCodex 返回当前 Runtime 广告函数的结构化调用,Runtime 仍是唯一 ToolHost,不允许 CLI 自己写项目、执行命令、调用 MCP 或形成第二套 revision / verification 真相。
- CLI 安全边界:CLI 固定使用 argv 启动,禁止 shell 拼接;工作目录使用本次请求专用的空临时目录,不把游戏项目绝对路径写入 prompt、stdout、stderr 或持久记录。调用固定使用 ephemeral、忽略用户配置和 exec rules、read-only sandbox、never approval,并关闭 Codex shell tool;只继承 CLI 运行和认证所需的最小环境,显式移除宿主 `CODEX_API_KEY`。用户级 Codex 登录态继续由本机 Codex 自己读取,API Key、auth 文件、Cookie、Token、`CODEX_HOME` 私有内容不得复制到项目配置、Runtime sidecar、Agent DB、conversation 或日志;stdout / stderr 无换行时也受硬上限约束,stderr 诊断只记录固定分类、字节数和 SHA-256。
- 协议边界:Runtime 把既有 `LlmRunRequest` 的消息和当前函数目录编码为有界 prompt,并从同一函数 JSON Schema 生成 Codex structured-output schema。CLI 输出转换为现有 `LlmRunResponse / LlmToolCall` 后,继续经过 native tool / MCP 参数校验、动作上限、权限、pending、receipt、验证与格式修复链;最终回复仍走现有脱敏和唯一提交路径,不新增平行响应协议。
- 取消与恢复:Codex 子进程绑定当前 Provider request lifecycle,取消、暂停、Runner draining 或 GUI owner 丢失时终止并回收当前进程;started 后没有可信终态仍沿现有 Provider reconciliation 处理。`agentMode`、CLI 可执行身份和影响输出的 Codex 参数进入 `providerConfigFingerprint`,模式切换不得消费另一模式遗留的 retry/handoff。
- 可用性与兼容:`check_game_creator_llm_config``codex_cli` 模式检查 Codex 可执行文件和版本,不再要求 HTTP API Key;在 `provider` 模式保持原有 API Key、base URL、model 和逐 Agent override 校验。设置面板始终保留旧 Provider 配置,模式切回后不得丢失既有密钥或逐 Agent设置。配置向导若写入 HTTP Provider 凭据,必须显式把模式切到 `provider`
- 验收:覆盖缺省模式、显式 Provider 回退、配置 round-trip、CLI 缺失/非零退出/损坏 JSONL/超限输出、structured tool calls、普通最终回复、进程取消、模式指纹漂移和旧 Provider 回归;同时执行 AGC 定向 Rust 测试、前端配置测试与 typecheck、配置门禁、编码检查和 `git diff --check`
### 2026-08-10 Codex app-server 长期 Agent 执行模式
- 模式升级:`agentMode` 扩为 `codex_app_server / codex_cli / provider`,新默认为 `codex_app_server`V1.51 的一次性 `codex exec` 保留为显式兼容模式,HTTP Provider 保留为非 Responses 配置及故障回退模式。
- 进程与节点:External Runner 按“有效 Agent LLM 凭据/Responses 路由 + `projectId/agentId/sessionId/runId`”隔离长期 `codex app-server --stdio`,即每个权威节点 run 直接持有自己的 Codex CLI 子进程与 ephemeral thread,每次完整权威请求映射 turn。同一节点 turn 串行,节点之间进程级隔离;单节点连接失败不得使其它节点同时失去终态。Codex thread 不写 durable recovery;节点完成、重启、retry、handoff 和 finalization 仍只认 AGC 账本。
- LLM 配置:`apiKind` 始终只接受 `openai_responses`;非空 Key 转换为 app-server model providerbase URL 生效,Key 仅走专用环境变量;空 Key 只桥接用户 Codex `auth.json`,不继承环境 `CODEX_API_KEY`。设置面板在 app-server 模式继续显示并保存 model、effort、stream、全局/逐 Agent Key 与路由配置;`openai_chat / anthropic` 明确提示切 `provider`,不得悄悄忽略。`stream=true` 接入 app-server 文本 delta`webSearchEnabled=true` 因唯一 ToolHost 边界明确拒绝。
- 安全与取消:临时 cwd、隔离 `CODEX_HOME` 与 OS HOME、read-only、network off、never approval,并在启动前关闭 web/multi-agent/shell/browser/plugin/image 等原生能力;取消从 turn-start pending 阶段就跟踪且只 interrupt 当前 turn。已发送 turn 后连接断开或终态丢失进入 reconciliation,只关闭当前节点进程且不重放同一 request slot;明确 failed/interrupted 不按 transport 重试。
- 资源与退出:app-server pool 按实际凭据快照/base URL/API kind/CLI 版本和节点 run 身份隔离并做有界 LRU;空 AppData Key 必须读取同一份有界 `auth.json` 字节来生成池指纹并桥接隔离登录态,继承的 `CODEX_API_KEY` 始终移除,node thread 也只淘汰 inactive LRU。Runner 正常、强制和 watchdog 退出都显式关池,Linux child 绑定 parent-death signal,防止强杀 Runner 后遗留带凭据孤儿进程。stdout NDJSON 与 stderr 无换行记录均有硬上限;stderr 原文不写入诊断,只记录固定分类、总字节数、SHA-256 和可取得的退出状态。
- 旧配置迁移:既有 AppData 若没有 `agentMode`,只有全局和逐 Agent 路由均为 `openai_responses` 时迁移到 `codex_app_server`;存在 `openai_chat / anthropic` 时显式保留 `provider`,避免打开项目自动恢复时把所有节点批量写成 `invalid-config`。用户确认端点支持 Responses 后,可在设置中显式切换并保留原 model/base URL/API Key。
- 验收:fake JSON-RPC fixture、三态 UI/config、配置指纹、unknown-terminal 零重放、旧两种模式回归和显式 ignored 真实 smoke 全部通过后,才可视为模式切换完成。
### 2026-08-10 Supervisor 边做边聊与条件中断
- 根 Project Supervisor 的运行中消息继续进入当前 `taskId / sessionId / runId`,先持久显示“正在判断、当前任务继续”,再由独立 LLM 生成非终态语义回复并给出 `interruptCurrentProvider`。过程回复不能调用终态 `respond_to_user`,不能把制作 Run、Goal 或 task 提前完成。
- steer 入队后不得先通知 Runner。判定为无需中断或判定失败时,`runtime.steer` 只校验 durable ledger、唤醒同一 Run 并固定保持 `providerInterrupted=false`;判定为需要改向时,只有 `runtime.interrupt_for_steer_decision` 可以读取持久 decision 后条件中断旧 Provider。已经消费该 steer 的新 Provider、工具和外部动作不得被中断。
- 状态询问、解释和不冲突补充默认继续当前 Provider;明确停止、改向或会让在途方案过期时才允许请求中断。判定失败时继续任务,并在下一安全边界消费消息,不得把失败等同于需要中断。
- UI 通过持久 conversation 展示关联回复,刷新后仍可见;返回的 `assistantReply / interruptDecision / decisionReason` 只用于本次命令结果与诊断,不形成第二个会话或第二个 Run。
V1.11 的受保护仓库控制目录同时包含 `.git / .agent / .agents / .codex / .hermes`;其中 `.agent` 对项目命令隐藏,其余控制目录只读。
2026-08-04 起,Runtime 的公共工具规划指令、Supervisor 协作编排 playbook、条件 overlay 和编译期静态 Agent 节点目录统一由版本化 Prompt Bundle 驱动,位于 `apps/ai-game-creator-shell/src-tauri/prompts/runtime/``manifest.json` 是 section 路径、组合顺序、平台 / Editor 变体、role overlay、Provider 协作 fragment,以及 Supervisor 与六组专业 Agent 静态目录的单一来源;role overlay 只允许 `rootSourceKind` 强类型语义 selector,构建期拒绝未知 kind,运行期把权威 source 常量映射为生成 kind。`build.rs` 同时监听 Bundle 每一级目录、manifest 和已登记 section,保证任意嵌套目录新增孤立 Markdown 都会触发增量构建,并以失败关闭方式校验 schema、引用、路径 / symlink、孤立 Markdown、selector、节点身份、旧 alias 和生成标识符,再生成 `'static + Copy` Rust 定义并编译进发布二进制。公共 runtime system header 保持身份中立;生成的 Supervisor planning composition 必须复用 `supervisorChat.identity`。每个 section 只能属于 runtime composition、Supervisor composition、chat 字段、platform variant、visual variant、role overlay 或 Provider fragment 中一个语义所有者;唯一例外是同一 identity section 由 Supervisor planning 与 `supervisorChat.identity` 显式复用,从而同时阻断 Supervisor 指令外泄和动态 variant 与静态 composition 的重复注入。专业节点 taskId / group / role 还必须在构建期与 `shared-contracts::new_game_creation_app_seed_tasks()` 强一致,防止身份合同、静态目录和正式 seed DAG 漂移。Bundle 承载公共指令、隔离 Agent 合同、平台差异、角色选择、并行委派、all-join、视觉返工、claim gateSupervisor 共享核心身份、interaction / final-reply 专属合同及其组合,以及首批协作、delivery 收敛、manifest wait、试玩后续委派等 repair 自然语言合同;background planning 在 system composition 复用核心身份,所有 user context 都不再重复注入 Supervisor 身份合同正文。`agent_runtime_native_executable_tools()` 仍是原生可执行工具的权威源列表,同时供 Prompt 工具目录与 native capability registry 使用,MCP 工具只从当前请求的动态 catalog 暴露。最终 Provider 请求必须通过生成的 section、composition、overlay 与 provider fragment API 构建,禁止恢复直接 `include_str!("prompts/runtime/...")`、在 Provider 或 `prompt.rs` 源码中复制协作 graph 文案,或依赖自然语言精确 `.replace()` 注入工具合同、平台规则或角色规则。Bundle 不是完整可执行 graph:正式 DAG 依赖边、权限、沙箱、委派容量、持久 all-join 状态机、完成门和身份校验仍由 Rust、`shared-contracts` 与经校验的 `.agent/collaboration-policy.json` 强制执行,不允许通过 Skill、外部配置或任意运行时 Prompt 覆盖绕过。
@@ -788,7 +815,7 @@ game-project/
- 开发模式可通过本地项目文件面板执行 `file.list/read/write/delete`,普通用户界面不暴露文件面板。
- 2026-07-17 起,同一 Runtime 文档的“V1.32 Runtime 强制 Supervisor 协作合同”作为 mixed swarm 可靠性事实源。项目可用 `.agent/collaboration-policy.json` 约束首波 static/isolated 模式、数量和 required static AgentRuntime 在任何 child 副作用前整批校验并把合同指纹固化进 Provider batch v2。当前父 run 一旦形成 delivery/group,正式 `project-supervisor` 默认只负责编排、状态认领和验证,不再直接执行项目 mutation;专业 Agent/isolated child 权限与唯一 Supervisor 最终回复边界保持不变。
- 2026-07-17 V1.32 最终代码已完成独立真实 Provider PASS:首批 mixed batch、三 isolated child、Runner 强杀恢复、专业返工、宿主验证、唯一最终回复与零重复/残留/泄漏同时成立。真实报告计数、隔离重试配置和仍待收敛的 tool-plan repair 成本统一以 Runtime 文档 V1.32 章节与共享决策记录为准。
- 2026-08-03 恢复执行补充约束:整个 pending action continuation、它进入的后台主循环,以及完成、取消或失败后 drain 同 Agent 后续队列时,都必须跨越独立 Tokio task 轮询边界,不能让 pending executor、task queue 与 Agent 主循环的大型 async poll frame 在同一 worker 调用栈连续嵌套。边界输入必须先装箱,避免泛型 helper 在真正 spawn 前仍把大型 future 保留在调用方 async frame;边界同时必须随父 continuation 取消子任务并保持 durable action、batch、run/session 身份及恢复防重语义,当前使用 boxed future 与 `JoinSet` 承担该约束。CI 和生产均使用默认 worker 栈验证,不以提高 `RUST_MIN_STACK` 代替代码边界。
- 2026-08-03 恢复执行补充约束:整个 pending action continuation、它进入的后台主循环,以及完成、取消或失败后 drain 同 Agent 后续队列时,都必须跨越独立 Tokio task 轮询边界,不能让 pending executor、task queue 与 Agent 主循环的大型 async poll frame 在同一 worker 调用栈连续嵌套。边界输入必须先装箱,避免泛型 helper 在真正 spawn 前仍把大型 future 保留在调用方 async frame;边界同时必须随父 continuation 取消子任务并保持 durable action、batch、run/session 身份及恢复防重语义,当前使用 boxed future 与 `JoinSet` 承担该约束。2026-08-10 起,Provider、Codex CLI 与 Codex app-server 的组合分发也必须在持久重试 helper 或非持久压缩路径内构造完整物理请求后、进入下层泛型 control/lifecycle helper 前装箱;不能靠逐个扩大 queue worker 栈掩盖模式分支放大的 future。CI 和生产均使用默认 worker 栈验证,不以提高 `RUST_MIN_STACK` 代替代码边界。
- 2026-07-18 起,同一 Runtime 文档的“V1.34 动态隔离子 Agent writeScopes 命令绕过封堵”作为 isolated child 的现行能力事实源。在 scope-aware OS sandbox 完成前,动态 child 无条件禁用 `project.verify / project.git_commit / command.exec / command.start / command.stdin / preview.start / agent.delegate / agent.spawn_isolated / project.restore / agent.schedule_ready / canvas.asset_generate / task.create / task.update / blackboard.write` 和全部 MCP;原生工具策略统一显示 `denied`,模板、项目 policy 与用户确认均不能放宽。保留固定只读 `command.run_limited`、同身份 `command.output_read / command.poll / command.terminate`、既有预览的 `preview.validate`,以及严格位于 `writeScopes` 内的 `file.write / file.patch / file.delete / project.patchset`
- V1.34 的新单动作在 confirmation 和 OS launcher 前拒绝;新多 action 原生 batch 只要含一个 denied member 就在独立 pending-action sidecar、confirmation、OS spawn、revision 和任何成员项目副作用前整批 abort,只保留 `aborted / nextActionIndex=0` batch 事实。旧 pending / approval / batch 真正进入执行器时仍重新应用当前 child 边界,旧 executing 未知结果继续进入既有 reconciliation。该安全收紧由恶意 sibling 写入、策略快照、batch、旧 pending 执行器重验和 isolated/mixed/collaboration/provider-batch 回归证明;不因本切片重跑已通过且 isolated mutation 为 0 的 V1.31/V1.32 外部 Provider suite。通用命令只有在后续 scope-aware OS sandbox 对所有后代强制同一 `writeScopes` 并通过独立决策与测试后才可重新评估开放。
- 2026-07-18 起,同一 Runtime 文档的“V1.35 多 ready isolated all-join 原子认领与恢复”作为 `agent.run_status` 同父 run 多 group 认领的现行事实源。Runtime 按 `delegationGroupId` 排序并一次性预取全部 join 锁;任一后续锁忙时保持零 delivery mutation、零 claim sidecar。全锁就绪后,同一 action 的 durable claim journal 按 `prepared -> committed -> observed` 推进;部分 commit 或 Runner 恢复只能复用该 journal 幂等补齐。只认领可完整放入优先 `readyIsolatedJoins` 观察预算的有序前缀,未观察旧 claim 可由后续 action 完整重放,但不创建第二份 isolated claim。每个 claimed delivery 必须由匹配原 action/group 的 journal 覆盖;无 journal 的旧 delivery 每轮只迁移一个原 action,已有 journal 不得扩写或状态倒退,跨 action group 归属冲突失败关闭。成功 observation 写入 pending sidecar 后只能把本轮完整输出的 claim 标记 `observed`,任一未观察或无 journal claim 继续阻断 finalization;每个 group 审计按 `actionId + delegationGroupId` 唯一,并在 Agent DB 锁内修复 torn tail、全量核对后幂等追加。