修复自主构建收束回复与公共失败审计

为已通过完成门禁的自主构建总控补充确定性最终回复兜底。

保留 Provider 失败生命周期并沿用回复流与 finalization 幂等提交。

将公共失败事件和 Agent DB 审计改为哈希、长度与稳定分类。

补充私有诊断隔离回归、真实外部 E2E 证据与项目文档。
This commit is contained in:
AIGameCreator App
2026-07-22 17:48:00 +08:00
parent 759951ab12
commit e142ef5eac
10 changed files with 845 additions and 54 deletions
@@ -5234,3 +5234,21 @@
- 后续收口:`App.tsx``12983` 行降到 `9794` 行,项目工作区下沉到 `src/features/project-workspace/` 的 11 个模块;`runtime_actions.rs``12519` 行降到 `139` 行,拆为 19 个生产模块和 2 个测试模块;`runtime_driver.rs``10510` 行降到 `394` 行并拆为 11 个模块;`runtime_protocol.rs``8623` 行降到 `105` 行并拆为 14 个模块,单模块不超过 `1319` 行。`runtime_driver/main_loop.rs` 仍约 `2995` 行,因为它承载现有单一主循环函数;后续必须先按运行状态阶段建立边界再拆分,不能继续机械切割。
- Rust 可见性与兼容性:嵌套子模块会改变 `pub(super)` 的直接父级语义。`runtime_tools` 中原本要供 `crate::agent` 兄弟模块使用的符号最小化调整为 `pub(in crate::agent)`;同一 facade 下跨子模块 helper 保持直接父级 `pub(super)``runner``process_session` 的内部兄弟调用仍经父模块 facade,不扩大到 crate 公共 API。新增 `runtime_protocol::provider_retry` 后,访问 crate 根同名模块必须写为 `crate::provider_retry`;原 facade 的兼容重导出继续保留,编译器仅因当前文件未直接消费而告警时使用局部 `#[allow(unused_imports)]`,不得机械删除。
- 验收:稳定共享树的客户端 `cargo fmt --check`、typecheck、Prettier、ESLint 和编码检查通过;Rust 串行全量 `1139 passed / 5 ignored / 0 failed`,客户端前端 `329/329` 通过。确定性 E2E self-test 与完整 E2E 均通过;完整链路继续满足 17 次 Provider lifecycle、revision `0 -> 2`、真实浏览器 `37/37`,重复、残留和泄漏均为 `0`
## 2026-07-22 AI 游戏创作自主构建完成后由 Supervisor 确定性收束回复
- 背景:最新真实外部 E2E 已推进到 revision 5,最终浏览器试玩 `37/37`、Supervisor 计划 `8/8``image.inspect` 视觉请求与最终回复却先后命中同一 deserialize fingerprint。终局 `114` 个 Provider request identity 中 `113 completed / 1 final-reply failed`,因没有 Supervisor assistant,整轮仍是 **FAIL**,不得记为外部 Provider 全链路 PASS。
- 决策:确定性最终回复只适用于 `autonomous-game-build` profile、规范 Agent `project-supervisor`,并且当前 revision 的 completion gates 已全部通过之后发生的 `final-reply` 收束。优先使用非空 `plan.response`;只有它为空时,才生成“当前 revision 已完成生成并通过静态、桌面和移动试玩”的确定性回复。
- 失败关闭:普通 Agent、尚未收敛的自主构建、任一完成门禁未通过或存在 reconciliation 时,继续沿用原失败路径,不得生成成功回复。该兜底不放宽工具、协作、验证、试玩或恢复门禁,也不从中间 planning 或失败 observation 推断项目已完成。
- 证据边界:Provider lifecycle 必须保留真实 final-reply failed identity、fingerprint 和终态,不得为了写 assistant 把失败请求改成 completed、隐藏或重编号。兜底只解决已完成项目缺少用户收束的问题,不能成为 Provider 成功证据。
- 验证:代码修复完成后必须重新运行独立真实外部 E2E,并在同一轮核对当前 revision、completion gates、唯一 Supervisor assistant、Provider lifecycle、残留、重复与泄漏。新一轮完整通过前,外部 Provider 全链路状态继续记为未 PASS。
- 最新真实轮次:新 fallback 已命中,父 Supervisor 终局为 `idle / completed``turn.report``settled`,只产生 `1``44` 字符的 Supervisor assistantpending、retry、handoff、finalization、reconciliation、重复、API Key 和路径泄漏均为 `0`。因此“完成后不回复”已在该轮解决。
- 轮次结论:该轮仍是 **FAIL**,不能记为 PASS。`105` 个 Provider identity 中 `103 completed / 2 failed`;两个原始专业 Agent 失败均已由 repair 恢复,但最终验收命中 `supervisor-swarm-private-body-public-event-leak`
- 脱敏定位:两个专业 Agent 的失败正文分别为 `149 / 123` 字符,对应 SHA-256 前缀 `494ce8 / 3089ad`,共进入 `4``event.detail``2``agent.runtime.background_task.failed.error`。六处内容均属于 delivery result,不是 userTask、委派任务或对话正文,与 final-reply fallback 无直接关系。
- 修复原则:私有 `state.error` 和私有 delivery 保留诊断正文;公共 event 与 agentDb 只写 `errorSha256 / errorChars /` 稳定 `failureKind`。不得依赖正文黑名单,也不得为通过验收把真实失败改写为成功。
- 后续验收:完成上述公共投影脱敏后,必须另起一轮独立真实外部 E2E;在该轮完整通过前,当前外部 Provider 全链路状态仍为未 PASS。
- 最终独立真实外部轮次:公共投影脱敏修复后另起的新轮次独立取得完整证据,`status=PASS``evidence=complete``privacy scan=complete`。上述 `114` identity 与 `105` identity 两个 **FAIL** 继续保留为独立历史失败,不与本轮拼接;最终 PASS 是单个新轮次的完整证据,当前外部 Provider 全链路状态据此更新为 **PASS**
- Provider 与任务终态:本轮共有 `84` 个 Provider identity`started / terminal / completed` 均为 `84``failed / retry / open / duplicate` 均为 `0``1` 个原专业任务以 `budget-exhausted` 终止,唯一 repair 已 `completed` 并标记 `recovered`;最终 child 为 `2 completed + 1 historical failed`,所有任务均处于终态。
- 父级收束:父 Supervisor 为 `idle / completed``turn.report``settled`;唯一 Supervisor assistant 为 `297` 字符,`completed audit=1`finalization 完成 `4` 个 stages。
- 项目与试玩:revision 从 `0 -> 4``game/index.html``7639` bytes 且内容已变化,`game.static_smoke` passed`lane-defense-v1` 的 desktop / mobile 浏览器验证均通过,固定试玩为 `37/37`
- 零值、隐私与清理:pending / confirmation / user-input / provider batch / retry / handoff / tool-plan handoff / finalization 残留 / reconciliation / duplicate 全为 `0`Provider payload / private body / API Key / project path / config path / log / browser report leak 全为 `0`;人工 approve / answer / steer 全为 `0`。Runner 与 AppData 已清理,项目因 `--keep-project` 暂留后由主线程清理。
@@ -3512,3 +3512,19 @@
- 原因:多个 Agent 虽然拥有互不重叠的写入文件,但全 crate 编译会同时读取所有模块。某个入口刚写入 `mod`、对应子文件尚未全部落盘时启动构建,会读到合法的中间态半成品。
- 处理:并行 Agent 只做各自 scoped 格式和测试;主 Agent 等所有写入方正式完成并关闭后,再在稳定共享树统一运行 crate fmt、全量测试和真实 E2E。编译前失败且 `stdin/provider/task=0` 的轮次只能算 harness 准备失败,不能归因给 Runtime 行为。
- 关联:`apps/ai-game-creator-shell/src-tauri/src/runner.rs``apps/ai-game-creator-shell/scripts/agent-runtime-real-e2e/`
## 确定性最终回复不能掩盖外部 Provider 的真实失败
- 现象:自主构建已经推进到 revision 5,浏览器试玩 `37/37`、Supervisor 计划 `8/8`,但 `image.inspect` 视觉请求与最终回复命中同一 deserialize fingerprint`114` 个 Provider request identity 中仍有 `1` 个 final-reply failed,且没有 Supervisor assistant。只看项目已完成或后续确定性回复,容易把这轮误写成 PASS。
- 原因:项目 completion gates、用户是否收到收束回复和 Provider lifecycle 是否全成功是三个独立事实。确定性回复可以补齐已完成项目的用户出口,但不能反向证明失败的 Provider 请求成功,也不能覆盖失败 identity。
- 处理:兜底条件必须同时锁定 `autonomous-game-build``project-supervisor`、当前 revision completion gates 全通过和 final-reply 阶段;优先使用非空 `plan.response`,为空时才生成当前 revision 已完成生成并通过静态、桌面和移动试玩的固定回复。普通 Agent、未收敛、门禁未通过或 reconciliation 一律继续失败关闭,并原样保留 Provider failed lifecycle 证据。
- 验证:把已有外部轮次继续标记为 **FAIL**。修复后另起独立真实外部 E2E,在同一轮同时证明唯一 Supervisor assistant、完成门禁、Provider lifecycle、零残留、零重复和零泄漏;复验完成前不得宣称外部 Provider 全链路 PASS,也不得与旧失败轮拼接。
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent/``apps/ai-game-creator-shell/scripts/agent-runtime-real-e2e/``docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`
- 最新复验:新 fallback 已真实命中,父 Supervisor 为 `idle / completed``turn.report``settled`,唯一 assistant 为 `44` 字符;pending、retry、handoff、finalization、reconciliation、重复、API Key 和路径泄漏均为 `0`。“完成后不回复”已解决,但该轮仍是 **FAIL**`105` 个 Provider identity 只有 `103 completed / 2 failed`,两个原始专业 Agent 失败虽均由 repair 恢复,最终仍因 `supervisor-swarm-private-body-public-event-leak` 未通过。
- 泄漏定位:两个专业 Agent 的 `149 / 123` 字符失败正文,分别对应 SHA-256 前缀 `494ce8 / 3089ad`,进入 `4``event.detail``2``agent.runtime.background_task.failed.error`。这些内容是 delivery result,不是 userTask、委派任务或对话正文;不要把该问题误归因到 final-reply fallback。
- 脱敏处理:私有 `state.error` 与私有 delivery 应保留完整诊断;公共 event / agentDb 只投影 `errorSha256 / errorChars /` 稳定 `failureKind`。禁止按正文黑名单打补丁,也禁止把失败状态伪装为成功来消除泄漏。
- 复验要求:公共投影修复后必须另起独立真实外部 E2E,重新核对同轮 Provider lifecycle、唯一回复、残留、重复和泄漏;当前仍未 PASS。
- 最终复验:修复后另起的独立真实外部轮次已取得 `status=PASS``evidence=complete``privacy scan=complete`。此前 `114` identity 和 `105` identity 两个 **FAIL** 仍是各自独立的历史失败,未与本轮拼接;最终 PASS 仅由这个单个新轮次的完整证据构成,当前状态现已 **PASS**
- Provider 与恢复证据:`84` 个 Provider identity 的 `started / terminal / completed` 均为 `84``failed / retry / open / duplicate` 均为 `0``1` 个原专业任务为 `budget-exhausted`,唯一 repair `completed``recovered`;最终 child 为 `2 completed + 1 historical failed`,全部任务均已终态。
- 收束与项目证据:父 Supervisor 为 `idle / completed``turn.report=settled`,唯一 assistant 为 `297` 字符,`completed audit=1`finalization stages 为 `4`。项目 revision `0 -> 4``game/index.html``7639` bytes 且已变化,static smoke passed`lane-defense-v1` 的 desktop / mobile 浏览器验证均通过并取得 `37/37`
- 零值与清理证据:pending / confirmation / user-input / provider batch / retry / handoff / tool-plan handoff / finalization 残留 / reconciliation / duplicate 全为 `0`Provider payload / private body / API Key / project path / config path / log / browser report leak 全为 `0`;人工 approve / answer / steer 全为 `0`。Runner 与 AppData 已清,项目因 `--keep-project` 暂留后由主线程清理。
@@ -66,6 +66,22 @@ V1.11 的受保护仓库控制目录同时包含 `.git / .agent / .agents / .cod
2026-07-22 补充:自主构建的最终 `preview.validate` 在当前 revision 失败后,修复责任必须继续服从 Project Supervisor 的只编排边界。父 run 尚无协作事实时可沿用总控直接修复兼容路径;一旦 durable 协作事实已建立且 `orchestratorOnlyAfterDelegation=true`,活性门不得再强迫 Supervisor 调用 `file.write / file.patch / project.patchset`。没有 ready 回执且委派容量未满时,可向 `code-prototype` 创建 `repairOfDelegationId=null / runId=null` 的新后续修复任务,并把最新浏览器诊断和 `game/index.html` 验收产物写入合同;已有 ready 未认领回执或 active delivery 已达 3 个时,原生工具目录必须只保留 `agent.run_status`,先原子认领既有交付,不得创建第四次委派。专业 Agent 推进到更高 revision 后,固定顺序为“认领 ready delivery -> 取得当前 revision 的静态通过凭证 -> 父 Supervisor 重跑固定试玩”。每个固定 `data-playtest-id` 在对应动作发生时必须恰好匹配一个可见、启用且真实可点击的 HTMLElement;缺失、重复、隐藏或 disabled 都失败关闭。失败 revision、专业修改、总控复验与最终试玩之间不得用伪造 mutation 衔接。
2026-07-22 外部自主构建 E2E 的最新失败轮已推进到 revision 5,最终浏览器试玩 `37/37`、Supervisor 持久计划 `8/8`;但 `image.inspect` 视觉请求与最终回复先后命中同一 deserialize fingerprint。终局 `114` 个 Provider request identity 中 `113 completed / 1 final-reply failed`,没有产生 Supervisor assistant,整轮因此仍为 **FAIL**,不得写成外部 Provider 全链路 PASS。
该问题的收束修复严格限制为 `autonomous-game-build + project-supervisor + completion gates 已通过` 后的 `final-reply`。优先使用非空 `plan.response`;为空时才生成确定性回复,明确当前 revision 已完成生成并通过静态、桌面和移动试玩。普通 Agent、尚未收敛、任一完成门禁未通过或存在 reconciliation 时继续失败关闭。Provider lifecycle 中真实的 final-reply 失败证据必须保留,兜底只保证已完成项目能向用户收束,不把失败请求改写为 completed。修复后必须重新运行一轮独立真实外部 E2E;该轮完成前不能宣称外部 Provider 全链路 PASS。
2026-07-22 修复后的最新独立真实外部轮次确认新 fallback 已命中:父 Supervisor 终局为 `idle / completed``turn.report``settled`,只产生 `1``44` 字符的 Supervisor assistantpending、retry、handoff、finalization、reconciliation、重复、API Key 和路径泄漏均为 `0`。因此“完成后不回复”已在该轮解决。
该轮整体仍为 **FAIL**,不能称为 PASS`105` 个 Provider identity 中 `103 completed / 2 failed`;两个原始专业 Agent 失败均由 repair 恢复,最终验收却命中 `supervisor-swarm-private-body-public-event-leak`。脱敏定位共 `6` 处:两个专业 Agent 的失败正文分别为 `149 / 123` 字符、对应 SHA-256 前缀 `494ce8 / 3089ad`,进入 `4``event.detail``2``agent.runtime.background_task.failed.error`;这些内容均属于 delivery result,不是 userTask、委派任务或对话正文,与 final-reply fallback 无直接关系。
修复必须保留私有 `state.error` 和私有 delivery 的诊断正文,公共 event / agentDb 只写 `errorSha256 / errorChars /` 稳定 `failureKind`;禁止采用正文黑名单,也禁止把真实失败改写为成功。修复后必须另起独立真实外部 E2E,当前外部 Provider 全链路仍未 PASS。
2026-07-22 最终独立真实外部轮次已完整 **PASS**`status=PASS``evidence=complete``privacy scan=complete`。本轮共有 `84` 个 Provider identity`started / terminal / completed` 均为 `84``failed / retry / open / duplicate` 均为 `0``1` 个原专业任务以 `budget-exhausted` 终止,唯一 repair 已 `completed``recovered`,最终 child 为 `2 completed + 1 historical failed`,所有任务均处于终态。
父 Supervisor 最终为 `idle / completed``turn.report``settled`,只产生 `1``297` 字符的 Supervisor assistant`completed audit=1`finalization 完成 `4` 个 stages。项目 revision 从 `0 -> 4``game/index.html``7639` bytes 且内容已变化,`game.static_smoke` passed`lane-defense-v1` 的 desktop / mobile 浏览器验证均通过,固定试玩为 `37/37`
终局 pending / confirmation / user-input / provider batch / retry / handoff / tool-plan handoff / finalization 残留 / reconciliation / duplicate 全为 `0`Provider payload / private body / API Key / project path / config path / log / browser report leak 全为 `0`;人工 approve / answer / steer 全为 `0`。Runner 与 AppData 已清理,项目因 `--keep-project` 暂留后由主线程清理。此前 `114` identity 与 `105` identity 两个 **FAIL** 继续保留为独立历史失败,证据未与本轮拼接;最终 PASS 是这个单个新轮次的完整证据,当前外部 Provider 全链路状态现已 **PASS**
2026-07-15 起,Runtime V1.1 文档的“V1.17 单 Agent 持久计划”作为后台工具规划进度的新事实源。`submit_agent_tool_plan` 新增 nullable `planUpdate={explanation,steps[{step,status}]}`;步骤只接受 `pending / in_progress / completed`,最多 8 步且至多一个 `in_progress`。结构化计划一旦建立,legacy `plan` 只作旧协议 fallback;终态步骤必须保留,`planRevision` 只在真实变化时单调递增,工具 action 下标不得自动完成结构化步骤,存在未完成步骤时不得写最终回复或 completed。
V1.17 计划快照随 `game-creator-runtime-context-bundle.v3` 持久化,v2 在通过原身份、revision 和 verification gate 校验后从当前 Runtime state 补齐计划字段继续恢复;计划元数据本身不推进项目 revision、不改变 verification gate,也不触发项目权限确认。开发 UI 和 CLI 有界展示 revision、说明与完整 8 步;正式用户的 Supervisor 只展示完成数、当前步骤、等待对象、下一步和协作数量的紧凑摘要。恢复、same-run steer 和真实 Provider 的完整验收矩阵以 Runtime V1.17 章节为准;2026-07-16 已在当前 v5 context 上完成正式 `openai_chat / gpt-5.5` 的同 run steer + Runner 强杀恢复专项,门禁状态为 PASS。