Codex/fix pr188 191 ci (#194)
Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/194 Co-authored-by: kdletters <kdletters@qq.com> Co-committed-by: kdletters <kdletters@qq.com>
This commit was merged in pull request #194.
This commit is contained in:
@@ -117,10 +117,9 @@
|
||||
- 工作台四区作为同一应用工作面直接衔接,外层不使用卡片圆角或留白间距。中央主视窗与右侧 Supervisor 使用各自的平台区域底色,并以稳定的竖向分隔线明确边界;不通过外层圆角容器、阴影或区块间缝重新包装四区。
|
||||
- 右侧正式钱包入口属于客户端宿主 chrome,在普通项目工作台与 UI Editor 子路由中都必须持续可见、键盘可达且可操作,不得因进入素材编辑壳或隐藏全局 chrome 而丢失余额、充值和使用详情入口。
|
||||
- 资源总览的“资源依赖 / 资源类型”视图切换使用连通的分段按钮组,相邻选项共享边界并保持唯一选中语义。每个分段都必须有清晰的键盘焦点指示,焦点环不得被分段容器的圆角或 `overflow` 裁切。
|
||||
- 右侧 Supervisor 对话中,用户消息使用右对齐、最大宽度受限的主题暖色气泡,assistant 消息保持左对齐;消息换行不得产生水平溢出,执行过程卡继续占满消息区可用宽度。气泡正文在 light / dark 平台主题下均须满足 WCAG AA 普通文本 `4.5:1` 对比度。
|
||||
- 右侧 Supervisor 对话中,用户消息使用右对齐、最大宽度受限的主题暖色气泡,assistant 消息保持左对齐;消息换行不得产生水平溢出,执行过程卡继续占满消息区可用宽度。消息列表必须约束在右侧对话列内并独立滚动,不得覆盖中央资源或运行视图;提交按钮必须保留随状态变化的可访问名称。气泡正文在 light / dark 平台主题下均须满足 WCAG AA 普通文本 `4.5:1` 对比度。
|
||||
- 客户端正式产品仍只按最小 `1280×720` 横屏合同交付,并保留 `1280×800` 默认窗口与既有基线验收;更窄浏览器样式只负责不崩溃和开发兼容,不改成移动端创作工作台。
|
||||
- 工作台顶部播放按钮在桌面视窗中水平居中;资源管理视窗触发播放时直接切换到运行视窗并启动本地预览,不再弹出 `game.run_local` 二次确认。
|
||||
- 普通用户界面不默认展示内部错误码或本机绝对路径,也不展示 External Editor Base URL 或 Developer API Key;官方服务地址由客户端构建固定,远端编辑自动使用当前陶泥儿登录态。仅独立 standalone game-chat release 或显式高级自定义模式在隔离配置页维护 External v1 URL/Key,确需诊断的信息进入受控详情或开发模式。
|
||||
- 创建模式素材画布的“素材名称”是用户可编辑的正式输出名称;“资源用途”是 manifest subtype,不向普通用户开放自由文本。新增资源默认“普通游戏美术”,可从普通游戏美术、统一视觉规范、游戏界面原型、核心美术图集四项中选择。图片精修继承源名称和用途,不显示创建模式保存设置;候选图片只从选中图片的“设为最终图”提交。精修顶栏只保留返回、导入、定位当前最终图、撤销和重做,删除进入图片上下文工具栏,通用 AI 生成只保留给创建模式。图片输出统一使用 PNG;创建模式工具动作与保存设置分层展示,“保存到项目”在 `1280×800` 和窄容器中都必须完整可见。
|
||||
- 首页创作输入区与“最近项目”之间不展示共享项目状态文本,“最近项目”标题下也不追加解释性副标题;默认、成功、进行中或失败状态均不得在该位置形成文字行,项目管理页继续保留自己的状态反馈。
|
||||
|
||||
@@ -551,7 +550,6 @@ type ProjectAgentMudPointAttribution = {
|
||||
|
||||
### 7.6 素材创作无限画布阶段一至五最终验收
|
||||
|
||||
实现状态(2026-08-15):当前产品切片禁用“新增资源”,只从现有资源进入非破坏性编辑。图片进入中央 refine 画布,其他现役类型进入统一派生编辑壳;取消恢复、正式 manifest/revision 实时合并、依赖图重建、dependency/type 双布局协调和三阶段自动定位已经接通。command/event 任意顺序按项目、commit、event 与 revision 去重;低 revision、旧 graph/layout 和失效 focus generation 均不能倒灌。普通 Tauri 客户端登录陶泥儿后直接使用固定官方 origin 下的网站现役 `/api/editor/*`、`/api/assets/*` 与 `/api/runtime/external-generation/jobs/*`,不展示或要求填写 Base URL/API Key;短期 Access Token 只进入 WebView、GUI 与 Runner 内存。独立 standalone game-chat release/高级自定义模式保留隔离 AppData Developer API Key 与 `/api/external/v1/*`。重启恢复只继续原 operation,不以新请求、新幂等键或新 operationId 替代结果未知的旧任务。
|
||||
|
||||
1. 网站与 Tauri 实际 import 同一份 `@genarrative/image-canvas-core` 和 `@genarrative/image-canvas-react`,客户端没有复制的主站画布目录;viewport、selection、变换、renderer 与 history 算法位于共享层,宿主只保留事件接线与 adapter 副作用。
|
||||
2. “新增资源”在当前产品切片中保持禁用;“编辑资源”只接受现有资源。图片 refine 为稳定 `sourceAssetId` 保存一个持续精修草稿和多个私有 `draft-media` 候选;只有用户显式“设为最终图”时才安装新的正式 PNG,并保持原 asset ID 不变、事务化更新其 manifest `localPath/mediaType`。候选图不进入 manifest 或资源总览。其他类型继续只追加派生文件/asset 或子版本。
|
||||
@@ -561,7 +559,6 @@ type ProjectAgentMudPointAttribution = {
|
||||
6. 搜索/筛选隐藏新资源时保留条件,明确提示“新资源已保存,当前筛选条件下不可见”,只通过显式动作清除条件并定位。
|
||||
7. 现有资源编辑、生成、保存、取消、失败和恢复必须覆盖权威专题 §13 中与当前非破坏性编辑切片对应的验收矩阵;只完成画布 UI 或只完成本地写文件都不能算正式闭环。
|
||||
8. 自动定位必须分别证明资源已投影、dependency/type 两份布局都 settled 且存在目标位置、目标卡 DOM 已提交;搜索隐藏走显式清除/定位,任何 commit 最多自动聚焦一次。
|
||||
9. 普通 Tauri 远端媒体编辑只使用当前陶泥儿登录态与固定官方 origin;后端按 owner 预扣/退款泥点并返回可轮询 operation。凭据失效、余额不足、平台生成配置故障和远端失败必须在画布内可见;生成状态不得因固定高度或 `overflow` 裁剪而消失,终态后刷新钱包余额。External v1 配置仅属于独立 standalone game-chat release/高级自定义模式。
|
||||
10. 普通素材画布生成账本的服务身份固定为 `official-platform-v1 + 官方 origin + ownerUserId`,不绑定 Access Token;高级 External v1 账本只绑定显式服务 origin,不绑定 Developer API Key。两种模式的 `accepted/running` 都只恢复原 GET,`prepared` 只可精确重放冻结的原 POST、原正文和原幂等键。普通模式退出或换号后提升账号 generation,中止并脱离旧请求;旧账号账本在新账号下零网络、零安装,只有重新登录同一 owner 后才可恢复。不能通过更换 Token、Key、URL、请求正文或 operationId 绕过该隔离。
|
||||
11. 资源编辑恢复面板必须为独立 modal,展示后端权威队列的全部 operation。用户可继续任意可恢复项;`remote-failed` 只允许显式移出活动队列,并保留私有账本审计;`reconciliation-required` 只读展示对账。读取失败必须提供重试,不得伪装空队列;操作后必须重读后端。
|
||||
12. `remote-failed` 已是远端明确终态,重启后不再 POST、不再轮询、不再扣费;`archived` 仅表示用户已将它移出活动恢复队列,不等于 `committed`。`result-unknown`、鉴权临时失败和 `reconciliation-required` 均不允许归档或重新生成。
|
||||
|
||||
@@ -22,13 +22,11 @@
|
||||
本次复现暴露的不是孤立实现缺陷,而是生成控制面的系统性断链:
|
||||
|
||||
- 普通工作台提交使用 `project-supervisor-gui`,进入固定专业任务图;一个单 HTML MVP 也会被美术、音频等前置依赖阻塞。
|
||||
- 现役 `project-supervisor-game-chat` 已具备“单主 `code-prototype` + 按真实缺口动态委派美术”的快车道,但普通 GUI 默认没有复用它。
|
||||
- 工作台仍展示“严格审批”,运行期间可以进入 `waiting-for-confirmation` 或要求用户继续,不满足无人值守目标。
|
||||
- `game.static_smoke` 失败时,持久回执可能只剩 `safeDetail=null`、`detailUnavailable=true`;同一 owner 看不到失败项,只能猜测修补。
|
||||
- 可修复的验证失败可能结束旧任务、留下空队列或失败卡片,未保证回到同一主 Run 继续“诊断 -> 修复 -> 重验”。
|
||||
- 子任务可以先报告 completed,再在投影阶段发现正式产物缺失,造成 Runtime 终态、manifest 状态和文件事实不一致。
|
||||
- `execution-owner` 对应进程消失后,持久 Runtime 仍可能显示 running,缺少自动对账和续跑闭环。
|
||||
- game-chat 当前首个可玩版本软预算为 4200 秒、硬上限为 4500 秒;固定图和重复猜错会把简单任务拖到一小时以上。
|
||||
|
||||
直接 Codex 能在数分钟内生成明显更完整的可运行雏形,说明首要瓶颈是 Runtime 的路由、反馈和验收控制,而不是基础模型完全不具备实现能力。
|
||||
|
||||
@@ -37,13 +35,11 @@
|
||||
### 3.1 本次必须完成
|
||||
|
||||
1. **默认单主生成路由**
|
||||
- 普通 AGC 项目工作台的新建/修改游戏请求默认使用 `project-supervisor-game-chat`。
|
||||
- 持久路由前零 child;持久路由后只启动 `code-prototype`。
|
||||
- 美术只在 `asset.list` 证明精确缺口后动态委派,且一次只处理一个依赖槽。
|
||||
- 保留 `project-supervisor-gui` 给显式专业 DAG/开发诊断入口,不再作为普通生成默认值。
|
||||
|
||||
2. **无人值守安全策略**
|
||||
- 对可信 game-chat autonomous root 及其绑定 child,项目内可恢复写入、受限静态验证、真实试玩、任务路由和严格边界内的动态委派自动执行。
|
||||
- 该模式不得进入普通 `waiting-for-confirmation` 或 `waiting-for-user-input`;模型信息不足时先采用目标合同允许的安全默认值。
|
||||
- 越界路径、任意命令、发布、凭据、系统设置和未列入白名单的外部副作用继续失败关闭,不能为了“无人值守”扩大权限。
|
||||
|
||||
@@ -66,7 +62,6 @@
|
||||
- 对账与恢复必须幂等,同一 run 不产生重复 child、重复消息或重复付费生成。
|
||||
|
||||
6. **有界端到端验收**
|
||||
- 新增一个从普通 GUI 提交到 game-chat 单主路由的回归入口。
|
||||
- 用确定性 Provider/工具夹具覆盖“首次 smoke 失败 -> 同主 Run 取得具体诊断 -> 修复 -> smoke 通过 -> 双视口试玩通过 -> completed”。
|
||||
- 覆盖 owner 中途消失后新 boot 自动续跑,最终只产生一个根终态。
|
||||
- 任何人工确认、人工澄清、固定专业 DAG 等待、旧 revision 验证复用或 console error 都使 E2E 失败。
|
||||
@@ -124,11 +119,9 @@ completed with missing artifacts or stale validation
|
||||
- `apps/ai-game-creator-shell/src/App.tsx`
|
||||
- `apps/ai-game-creator-shell/src/features/agent-runtime/model.ts`
|
||||
- `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/task_start.rs`
|
||||
- `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/game_chat_fast_path.rs`
|
||||
|
||||
实施内容:
|
||||
|
||||
- 把普通项目工作台的 autonomous build source 改为 game-chat 单主来源。
|
||||
- 把 source 选择抽成可测试的纯函数,避免 UI 分支再次漂移。
|
||||
- 保持显式专业/CLI 调试来源不变。
|
||||
- 调整工作台状态投影,不再向默认用户展示固定专业 DAG 和无效“严格审批”承诺。
|
||||
@@ -145,7 +138,6 @@ completed with missing artifacts or stale validation
|
||||
|
||||
实施内容:
|
||||
|
||||
- 为可信 game-chat autonomous binding 建立窄白名单自动策略。
|
||||
- 对该来源的确认型动作做“安全自动执行或明确拒绝”二分,不能挂起等待。
|
||||
- 为 `command.run_limited/game.static_smoke` 定义稳定的 safe detail schema。
|
||||
- 保证同 owner 的下一轮 Provider context 能读取失败项,公共 UI 仍只拿安全摘要。
|
||||
@@ -182,7 +174,6 @@ completed with missing artifacts or stale validation
|
||||
|
||||
实施内容:
|
||||
|
||||
- 固定普通 GUI -> game-chat 的来源契约。
|
||||
- 增加无确认、失败自修复、artifact 真实性和 owner-loss 恢复测试。
|
||||
- 增加确定性 E2E;真实 Provider smoke 作为现场验收,不把 mock E2E 说成真实生成已经成功。
|
||||
- 把新的默认路由、无人值守安全边界和复验命令写回权威文档。
|
||||
@@ -191,7 +182,6 @@ completed with missing artifacts or stale validation
|
||||
|
||||
| 场景 | 预期结果 |
|
||||
|---|---|
|
||||
| 普通工作台提交单 HTML 游戏需求 | source 为 `project-supervisor-game-chat`,只启动 `code-prototype` |
|
||||
| 素材完整 | 零美术委派、零额外扣费 |
|
||||
| 缺少规范图和图集 | 先规范图后图集,一次一个 delivery,主 Run 认领后继续 |
|
||||
| 项目内文件修改、static smoke、preview validate | 在可信 autonomous binding 下不等待人工确认 |
|
||||
@@ -211,7 +201,6 @@ completed with missing artifacts or stale validation
|
||||
```bash
|
||||
npm --prefix apps/ai-game-creator-shell run typecheck
|
||||
npm run test -- apps/ai-game-creator-shell/tests/agentRuntimeModel.test.ts apps/ai-game-creator-shell/tests/appSurface.test.ts --run
|
||||
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml game_chat_ -- --nocapture --test-threads=1
|
||||
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml autonomous_completion_contract -- --nocapture --test-threads=1
|
||||
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml action_receipt -- --nocapture --test-threads=1
|
||||
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml project_execution_owner -- --nocapture --test-threads=1
|
||||
@@ -246,9 +235,7 @@ git diff --check
|
||||
在 `codex/agc-runtime-generation-reliability` 分支完成:
|
||||
|
||||
- 可信 `code-prototype` 父 Run 可认领并观察直属美术 delivery、按 `delegationId` 精确读取合同;错误 Agent/Run、未知合同与身份篡改统一失败关闭。父 task/chain 无法证明但仍有活跃或已认领 delivery 时 completion 必须 blocked;Suppressed 且未形成 child 的失败前置记录不参与 capability、claim 与 completion barrier。
|
||||
- 普通失败或不合法安全默认 marker 认领后立即收束;合法 `game-chat-safe-default-repair.v1` marker 由 Runtime 直接生成唯一一层、同目标、同合同 `agent.delegate`,repairRequired 状态下重复 route/read/query 被 liveness 门拒绝。
|
||||
- Windows `.agent/project.lock` 不再对最终 `create_new` 目标做 metadata 预检,delete-pending 的 5/32/33 统一进入有界竞争等待;新增 delete-pending 回归,复现真实 `create_new` ACCESS_DENIED 后证明等待可收束。
|
||||
- 验证结果:`game_chat_` 113 通过、`autonomous_completion_contract` 107 通过、`safe_default` 4 通过、`static_smoke` 9 通过、`action_receipt` 10 通过、`project_execution_owner` 8 通过、runner 重启恢复与 Windows 锁回归通过;串行全量 Rust `1856 passed / 0 failed / 15 ignored`(含新增 HTML 内联语法 fail-open 回归);`platform-llm` 与 `agent-runtime-core` 全绿;前端 typecheck、`check:encoding`、`git diff --check`、变更文件 `rustfmt --check` 通过。
|
||||
- 真实 `gpt-5.6-sol / reasoningEffort=max` 隔离轮次:14 个 Provider 请求全部完成并闭合,无确认、追问、steer、路径/密钥/正文泄漏,Runner 与后代进程清理为零残留;在未配置 External Editor 的边界下 art-director 失败后由主 Run 认领并快速明确收束,未再次空转。
|
||||
- 待完成:用有效 External Editor 配置跑一轮完整 playable 真实验收;当前结果不能宣称现场完整生成已通过。
|
||||
- 2026-08-15 后续修复:Runtime 配置保存成功或失败均显示可见 toast;默认 `gpt-5.6-sol / reasoningEffort=max` 已同步到启动配置门禁,`check-config`、AGC typecheck 和运行时设置定向测试(6 项)通过。
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
## 范围与边界
|
||||
|
||||
- 删除 Tauri setup 中仅 debug 生效的自动 developer 窗口调用,以及已无调用方的 developer 窗口构造代码与专属路由测试。
|
||||
- 保留普通 `client` 窗口、`--game-chat` 独立入口和显式 `supervisor-chat` 开发调试入口。
|
||||
- 不删除前端 `?agent-chat` 调试页面;它不再是 `npm run agc` 的自动入口。
|
||||
- 同步原生壳静态门禁、技术方案和长期决策记录,防止自动双窗口回归。
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -43,25 +43,19 @@
|
||||
- 现象:`agent_runtime_supervisor_source_is_trusted`(`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver.rs:113`)读起来像一个「谁能启动 Project Supervisor」的入口白名单,实际早已是多条互不相干的授权判据的共同开关。2026-08-11 合入动态目标验收图后,它的非测试消费者从 2 个文件涨到 10 个文件 18 处调用:run 启动(`commands.rs:698`)、steer(`commands.rs:876`、`steering.rs:763`)、Goal Contract 创建权限(`goal_contract.rs:496`)、根控制面工具是否被剥离(`provider_request_builders.rs:134` 的 `root_control_authority`)、验收图完成门(`acceptance_graph.rs:595`)、run configuration、lifecycle_control、task_start、project_gates、autonomous_completion。
|
||||
- 陷阱:这些判据**全都不看 Run Profile**。`goal_contract_acceptance_completion_blocker_at_locked`(`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/acceptance_graph.rs:568-611`)只要求「`agent_id` 是 `project-supervisor` + binding 是无 parent 的 root + source 可信」,未冻结 Goal Contract 就返回 `blocked`,并被 `main_loop.rs:213`、`main_loop.rs:1803`、`finalization.rs:398` 消费。因此给一个**用途完全不同**的新 source(例如立项策划的 plan chat)加进白名单,会让它的根 Run 立刻背上「必须先调 `agent.goal_contract`」的义务;如果该 source 的工具面按 exact allowlist 设计、不含这个工具,根 Run 就永远无法完成——而且症状是 run 卡在完成门,不是启动失败,排查方向容易跑偏。
|
||||
- 更坏的一半:把新 source 排除出白名单**并不能**脱身。同一协议还有一道入口门 `validate_root_goal_contract_control_plan_at`(`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/autonomous_policy.rs:171`),由 `provider_tool_plan.rs:434` 在通用 tool-plan 解析路径上无条件调用,判据只有「`agent_id` 是 `project-supervisor` + binding 的 root 是自己 + 存在 run profile binding」——**连 source 都不看**。合同不存在时它强制本轮恰好一个 `agent.goal_contract` 动作且 `plan_update`/legacy plan/`response` 全为空,于是「第一轮先问用户一个问题」或「第一轮先回复」的 Agent 会被直接判协议错误。三处判据里只有 `agent_id == GAME_CREATOR_PROJECT_SUPERVISOR_AGENT_ID` 是共同项,改 `agent_id` 是唯一能一次性解耦的做法。
|
||||
- 为什么现役 Agent 没事:工具面是 **deny-list** 模型。`agent_runtime_tool_policy_snapshot_at`(`tool_policy_snapshot.rs:130-178`)的 `allowed_tools` 直接等于全量 `agent_runtime_executable_tools()`,`agent.goal_contract` 天然在内;`standard` profile 在 `agent_runtime_tool_policy_snapshot_for_run_at:198` 提前返回、不做裁剪;只有 `!root_control_authority && goal_contract_participant` 的后代才在 `provider_request_builders.rs` 被剔除。所以 gui/cli/game-chat 根 Supervisor 默认就握着这个工具,两道门对它们是「照着做」而不是「过不去」。**按 exact allowlist 设计工具面的新 source 才会撞上**,而 allow-list 正是更安全的那个方向——这条陷阱专门惩罚更严格的设计。
|
||||
- 处理:新增 trusted source 前,先逐个确认这些调用对新 source 的语义是否成立,尤其是 Goal Contract 创建、验收图完成门与 steer 三处,再单独确认不看 source 的入口门;需要区分时,应当拆出「可信入口」与「Goal Contract 参与者」两条判据,而不是继续复用同一个函数。立项策划已按第 23.1 节裁决进 matcher 并参与 Goal Contract;steer 用独立于 matcher 的显式否决(`reject_supervisor_plan_root_steer`),不得用「不进 matcher」实现。复核结论见 decision-log 2026-08-13 `M1A-1` 条。
|
||||
- 双向提问:调用点**既是判据又是构造器**时,只问「会不会误得不该有的语义」不够,还要问「落到通用兜底会不会丢掉该有的语义」。`resolve_game_creator_agent_runtime_retry_configuration_at` 因此在 `M1A-1` 漏出,由 `M1A-3` 补强判据与保源;拒绝继续用弱判据,授予必须用强判据。
|
||||
- 相关:`requiredEvidence` 只接受 `tool:<Runtime 工具名>` 且必须命中 `agent_runtime_acceptance_evidence_tools()`(`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/tool_policy_snapshot.rs:74-96`,当前 18 项)。确定性收束的任务和 Runtime 内部产物验证都不产生 Provider 回执,因此无法为验收节点提供证据——不要指望「让 Runtime 自己验一下」能满足验收图。
|
||||
|
||||
## 2026-08-12 给 manifest 加"新鲜度门控"或身份字段的两个陷阱
|
||||
|
||||
- 现象:想给 game-chat 投影里的 manifest 读取加保护时,两条看起来最自然的路都会失效,且失效方式都是静默的——代码跑得通、测试也能编出来,但保护根本没生效。
|
||||
- 陷阱一(时间戳单位):`AgentRuntimeState.updatedAt` 来自后端 `unix_timestamp()`,返回的是**秒**(`apps/ai-game-creator-shell/src-tauri/src/project/filesystem.rs:725-730` 的 `as_secs()`),全链路透传到前端不做任何换算。任何 `observedAt >= main.updatedAt` 形式的新鲜度门控,若 observedAt 取 `Date.now()`(毫秒),两侧相差约 1000 倍,判定恒为真、拒绝不掉任何陈旧读数,等于死代码。前端已有 `gameChatMessageTimestampMilliseconds`(`apps/ai-game-creator-shell/src/features/project-workspace/SupervisorChatOnlyView.tsx:130-143`,`< 1_000_000_000_000` 则 ×1000)专门处理这个换算,任何新增的跨端时间比较必须复用它,不要重新裸比。
|
||||
- 陷阱二(补身份字段只堵一条路):改写 `task.status` 的写入路径有两条互相独立的。除 `update_manifest_task_status_at`(`apps/ai-game-creator-shell/src-tauri/src/project/manifest.rs:590-608`)外,还有毫无秩序守卫的 `set_task_status`(同文件 `580-588`,直接 `task.status = status`),其调用方 `record_draft_task_progress`(同文件 `387-413`)把 `code-prototype` 列进批量置 `Completed` 的清单,由用户可随时触发的 `game.generate_draft` 命令调用。只给前者补 `statusRunId` / `statusSource`,后者会原样保留上一次写入的旧身份印记,于是污染写入反而通过校验,比不校验更危险。对照组是 `apps/ai-game-creator-shell/src-tauri/src/agent/generation/trace.rs:613-637` 的 `set_task_status_if_current`,它有 `should_replace_task_status` 秩序判定——两者的不对称本身也是一个待处理项。
|
||||
- 处理:本阶段不加机制,manifest 明确降级为 lineage 判定通过后的补充信号(见 decision-log 2026-08-12 条)。将来要做,必须同时覆盖两条写入路径,并统一走毫秒换算 helper。
|
||||
- 验证:`apps/ai-game-creator-shell/tests/agentRuntimeModel.test.ts` 的「keeps an unbound manifest out of the verdict until the current main is terminal」钉住了现有边界与残余风险;该用例最后一条断言即为已记录的残余风险,改动它就意味着重新裁决,必须同步更新决策记录。
|
||||
|
||||
## 2026-08-11 game-chat 阶段归档不能只保存 current-by-agent map
|
||||
|
||||
- 现象:前端 Runtime map 以 Agent ID 保存当前记录。新一轮仍会复用 `code-prototype`、`art-director`、`art-asset-plan` 这些 Agent ID;若旧 root 已终态但 main/美术 child 或 manifest 仍在收口,直接从 live map 归档会在新 root 接管后丢失旧后代,或把新轮证据误接到旧阶段记录。
|
||||
- 原因:Agent ID 只是当前视图索引,不是跨 root 的运行身份。game-chat 的正式投影身份至少需要 `agentId + sessionId + runId + source + parentAgentId + parentRunId`,而阶段记录还必须绑定 source-bound root。
|
||||
- 修复:根进入终态时按完整 `agent/session/run` 身份保存 root-scoped Runtime 快照,后续只合并同一稳定身份的更新;manifest 快照只在该 root 仍为当前 root 时捕获。归档前重新执行严格 lineage、全终态、单 main/单 active art 与 reconciliation 门禁,并用 root run 派生稳定 message ID。
|
||||
- 防回归:测试必须覆盖 root 先终态、main 或 child 仍 active、main 仍等待 delegate receipts、manifest hydration 滞后、initial hydration 和历史阶段记录去重。完整 DAG 继续使用自己的投影,不能把 game-chat selector 反向推广为全局任务图真相。
|
||||
|
||||
> 用途:记录已验证、未来很可能再次遇到的问题。每条都应包含现象、原因、处理方式和验证方式。
|
||||
|
||||
@@ -79,9 +73,7 @@
|
||||
|
||||
## 严格 delegated 授权失败不能把 retry 回落为普通美术权限
|
||||
|
||||
- 现象:game-chat 动态美术 child 以通用 retry 创建 `source=agent-delegate-retry` 的新 run 后,严格 Canvas/delivery 授权只接受首次 `agent-delegate`,返回 false;调用方却把 false 解释为“不是受限动态美术”,使 retry 回落到普通 autonomous 美术权限并可能写入 `game/**`、`.agent/**`,调用 preview 或继续委派。
|
||||
- 原因:代码混用了“是否声称动态美术 lineage”和“是否已证明当前首次委派授权”两个事实。retry 使用新 run 和新 delegationId,但没有与之绑定的 durable delivery,结构上无法满足现行 exact lineage;授权失败应表示不可信候选,而不是普通 Agent。
|
||||
- 处理:game-chat 动态美术 child 在通用 retry 入队前以终态可用的结构身份分类并返回 `kind=game-chat-dynamic-art-retry-unsupported`,引导用户继续 game-chat 对话,由下一轮 main `code-prototype` 重新 `asset.list` 后建立新委派。同一 main run 的同 target 重委派继续遵守“每个缺口最多一次”,不为失败 child 开豁免。对遗留/伪造的 retry source,美术分类入口只允许诊断性只读工具,全部 mutation fail closed;严格首次委派 predicate、delivery 和 Canvas 凭证不换绑、不续发、不放宽。完整 DAG、非美术委派和顶层 retry 不受影响。
|
||||
- 验证:覆盖 failed/cancelled child 重试零 successor run、遗留 retry 的 file/patchset/Canvas/command/preview/再委派拒绝、失败回执认领后同 run 同 target 重委派拒绝、下一轮 main 重新审计后同 target 新委派放行且 delivery 全链一致并恢复 `assets/**`,同时对完整 DAG 与非美术 retry 做非回归。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/lifecycle_control.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools/file_ops.rs`、`docs/project-memory/shared-memory/decision-log.md`。
|
||||
|
||||
@@ -91,8 +83,6 @@
|
||||
- 原因:初始化 `game/index.html` 只是无 `<canvas>` 的占位页,真正游戏要到下游 `code-prototype` 才生成。把所有 mutation verification 都等同于可玩游戏 smoke,会让上游 artifact-only owner 在依赖顺序上自锁;预写 fake game 的夹具提前完成了下游职责,掩盖了真实新项目路径。
|
||||
- 处理:四个 pre-code 固定 owner 在最终收束门由 Runtime 内部验证 canonical 产物:普通文件有界读取、非空,JSON 可解析,无 incomplete marker,且相对根完成合同 baseline 已变化。该能力不进入 Provider 工具目录,不新增 commandId;凭证类型为 `runtime.owner_artifacts_validate`,只写普通 `verifiedRevision`,不得写 `staticSmokeVerifiedRevision` 或制造 smoke / preview trace。文件路径门与验证必须复用同一 canonical owner 映射。`code-prototype` 和 `preview-readiness` 继续执行真实 `game.static_smoke`,`preview-playtest` 继续独立浏览器验收;`publish-package` 不借本修复扩入内部验证。
|
||||
- 身份与恢复:只允许完整 GUI / CLI 16 任务 DAG 的 `agent-ready-task-scheduler` 确定性直接 child、当前活跃根和正确 parent/binding;错误 source、delegated run、历史/终态根、非当前 root、跨 Agent/run 一律失败关闭。owner 再次 mutation 必须令旧凭证失效;相同身份恢复时可按当前磁盘事实确定性重验。
|
||||
- Canvas 补充:未配置 External Editor API Key 时 `art-director` 是只读协调;配置 Key 时它是条件 Canvas owner,只广告并执行 `canvas.asset_generate`,拒绝 `project.verify`、`command.run_limited` 和 preview。game-chat 临时 `art-asset-plan` 必须同时满足当前 `code-prototype -> agent-delegate`、durable delivery 与 binding 身份,并只认本人 Canvas 生成凭证,不能借普通验证。四个 fixed owner 配置 Key 后仍须满足既有图片、Canvas 登记和视觉门;内部文件验证不替代这些证据。
|
||||
- 可玩凭证补充:完整 DAG 的 `code-prototype` 不能用已通过的 `project.verify` 代替本人 `game.static_smoke`;完成门要求 `staticSmokeVerifiedRevision >= mutationRevision`。GUI / CLI 的 preview 回执只能由确定性 `preview-playtest` child 生成,game-chat 只由唯一主 `code-prototype` 生成;回执必须冻结 executor Agent/run/source/binding,旧 v1 回执按缺失处理并重跑。
|
||||
- 并发恢复补充:自主根任务 journal 写入后建立或重建 completion contract 时,初始 manifest reset 与 continuation reconciliation reset 不能重新使用 fail-fast 项目锁。异步 child finalization 可以合法插入两次取锁之间,使已入 journal 的新根被误记为 `completion-contract-failed`。这两条 reset 必须使用现有有界等待项目锁,超时仍失败关闭;只验证 scheduler 合同的测试应预占 child Runtime lane,不能真实启动后台 worker 后再手工改 manifest。确定性回归要显式持锁,分别证明初始合同与 continuation 合同等待释放后成功落盘。
|
||||
- 验证:夹具必须从 `init_local_game_project_at` 开始,先断言无 `package.json` 且占位入口 smoke 失败,再证明产物不齐阻断、齐全后内部验证通过、无 smoke trace、再次 mutation 失效;另覆盖四个 owner 路径矩阵、错误身份、恢复、跨 run 凭证、`art-director` 有/无 Key、动态美术借凭证拒绝、`code-prototype` project.verify-only 阻断和试玩 executor 身份。
|
||||
- 关联:`docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`、`docs/technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md`。
|
||||
@@ -196,7 +186,6 @@
|
||||
|
||||
- 现象:用户提交长任务后只看到运行失败或任务直接消失,聊天里一条有用消息都没有;另一些失败又同时出现 Runtime event 和 conversation 两条近似提示。
|
||||
- 原因:启动确认依赖实际 `turn.started`,任务只入队或 Runner 在 start transition 前失败时没有公开回执;终态失败先写 task/event/state,最后才由各 main-loop 分支尽力追加 assistant。坏掉的若正是状态文件,流程会在公开消息前返回;散落的 `let _` 又无法提供幂等身份。
|
||||
- 处理:用户直接投递的 Project Supervisor 根任务先落为不可执行的 `preparing / public-status-pending`,持久化同 run 的 `runtime-public-status-* / accepted` 后才转为 `pending / queued`;恢复 preflight 只验证业务状态,不改写 task/conversation,仅 resume 持有 Agent 锁后才可持久提升。根 Supervisor 通过正式失败 / 预算耗尽收束或 game-chat 绝对硬期限进入 reconciliation 时,先写相同协议的终态消息,再处理 Runtime 其它投影。专业 Agent 命中全局硬期限时,应由权威根 task 在项目 conversation 中幂等写根终态,child 仅在身份完整匹配时写私有 Session;根 agent/run 的 session 或两个 parent 冲突时必须失败关闭。消息正文只能来自封闭脱敏映射,prompt 构建必须按稳定前缀排除;前端按前缀标记 Runtime-owned,只过滤根 Supervisor 的 `turn.started / turn.failed / turn.budget_exhausted`,不吞掉专业 Agent 启动进度。模型仍负责业务 commentary/final,Runtime 的两条硬门不扩展成业务判断器。
|
||||
- 恢复补充:不能把“accepted 还没写完”等同于“用户从未投递”。用户消息已持久时,真实 resume 必须补写 accepted 后才入队;用户消息或 accepted conversation 已存在时,后续审计失败不得留下“正在启动”但永不执行的假状态,但同 message ID 的 role/content 冲突必须把 task 明确收束为 `conversation-write-failed`。根终态首次公开写入的瞬时失败必须在终态投影后用相同 message ID 重试。带 parent 的 Supervisor continuation 不得同时产生 Session 终态和 Runtime 事件两条公开消息;秒级时间戳下必须以 task/status message ID 共享的 run 关联摘要排序,不能用不同消息类别的计数猜测顺序。
|
||||
- 验证:任务 journal 必须显示 `preparing -> pending`,仅有 accepted 时恢复才可提升;破坏项目 conversation 时断言任务为 `public-status-write-failed` 且无可运行 pending;破坏 Runtime state 路径时断言公开失败已经存在;重复写同一 run/status 只有一条 message ID;渲染实际 prompt 断言不包含 Runtime 公开状态;AppSurface 证明根启动/失败事件不重复,专业 Agent 启动仍可见。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_state.rs`、`agent/runtime_driver/task_start.rs`、`src/features/agent-runtime/model.ts`、`src/features/project-workspace/SupervisorChatOnlyView.tsx`。
|
||||
@@ -213,9 +202,7 @@
|
||||
|
||||
- 现象:用户只说“现在没有用到任何美术资源”,Graph 就在 Supervisor 输出任何计划前自动打开美术节点;或者用户想复用现有素材,Runtime 直接按关键词预完成节点。Supervisor 无固定计划时随即 `fixed-task-graph-stalled`,看起来像模型不理解意图,实际上模型根本没有获得决策机会。
|
||||
- 原因:同一套关键词函数同时承担 prompt hint、Graph reset、baseline 豁免和历史试玩类型继承,启发式信号越过 Supervisor 成为了控制面真相;main loop 又在 Provider 请求前优先调度 ready task。
|
||||
- 处理:启发式结果只序列化成 `advisoryOnly=true` 的 Supervisor context。Scheduler 以持久 `GameChatWorkflowDecision` 为首轮前置门;Supervisor 只持久化用户 intent,随后由唯一 `code-prototype` 用成功 `asset.list` 和 Runtime 复核的覆盖合同选择复用或精确补缺。Runtime 可以拒绝过期、伪造、遗漏或重复 route/delivery,但不得替 Supervisor 补写决定或固定生成美术。
|
||||
- 验证:直接使用用户原句,断言 hint 命中但 manifest 全部保持 pending、决策前零 child、Provider request 包含路由工具;决策后只启动 code-prototype,它未完成 asset.list 时不得委派美术;再分别覆盖完整复用、真实缺口和显式重做。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/game_chat_fast_path.rs`、`runtime_driver/main_loop.rs`、`runtime_driver/task_start.rs`、`runtime_protocol/autonomous_completion.rs`。
|
||||
|
||||
## 既有正式产物不能同时被快车道视为已完成、被本轮 baseline 门视为未变化
|
||||
|
||||
@@ -223,7 +210,6 @@
|
||||
- 原因:Graph reset 无差别重新打开稳定的美术 owner 节点;快车道按“当前产物有效”判断完成,owner 完成合同则按“本轮必须修改 baseline 产物”判断完成,两套语义互相冲突。增加 loop 预算、伪造版本号或机械改写 manifest 都不能消除冲突,还会引入 verification loop、字段丢失或错误复用旧主题。
|
||||
- 处理:关键词和资产探测只作为 Supervisor 的 advisory context,不能直接修改 Graph。根 Run 先以 `audit-existing-first` 持久化用户 intent;即使用户提出整体视觉重做,这也不授权强制重生成。决策后只启动 `code-prototype`,由它在成功 `asset.list` 后提交或建立权威覆盖/缺口 delivery。Runtime 验证合同后才允许已有资产复用,或只打开精确缺口 owner;根完成门继续要求主 Agent 认领回执并完成接入、Canvas、私有回执、切片、可见使用和试玩验收。
|
||||
- 验证:先断言 Supervisor 决策前零 child、固定关键词不会预完成节点,再覆盖完整复用、仅缺图集和明确重做。还要直接经过父完成门,证明合法持久 route/delivery 不再出现 art baseline gap,并证明删除切片后覆盖合同拒绝复用;旧 root、错误 fingerprint、虚构或遗漏缺口、重复委派以及 child 写入 `game/**` 都应失败关闭。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/game_chat_fast_path.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/autonomous_completion.rs`。
|
||||
|
||||
## 单主 Graph 升级不能只迁移 sidecar,必须同时处理活跃旧 Run
|
||||
|
||||
@@ -231,7 +217,6 @@
|
||||
- 原因:迁移测试只手工构造了非确定性主 Run,未经过真实 ready scheduler;资源 route 的迁移也没有自动让已启动的旧责任链失效。硬截止处理若仍只接受根的直接 child,还会把新的嵌套美术 child 留在 running,而丢失 reconciliation 投影。
|
||||
- 处理:确定性主 Run 只白名单兼容已知 canonical task 文本版本,所有其它身份字段继续精确校验;旧 fixed-graph 美术 child 及沿 isolated instance 父链可证的历史后代在计划和所有非只读工具入口失败关闭,只允许当前 `code-prototype` 经 `asset.list` 后重新委派。新美术 child 同样使用显式只读白名单,写工具只允许可证明落在 `assets/**` 的文件/patchset 与 `canvas.asset_generate`,不能借 `memory.write` 或 `task.create/update` 修改 memory 和 manifest;会认领 delivery 并写 observed 状态的 `agent.run_status` 也不是只读。绝对硬截止显式验证根、主 Agent、delegated art child 的完整 task/binding/delegation 链。
|
||||
- 验证:用真实 scheduler 恢复确定性 v1 主 Run;把旧 scheduler 美术 child 置为 running,断言 `canvas.asset_generate`、`memory.write`、`task.create`、`task.update` 和 `agent.run_status` 均被拒绝;再持久化其历史 `game/**` writeScope isolated 后代,断言恢复执行写操作仍失败且项目未变。对当前合法美术 child 同样验证 memory/manifest 零写入,再让它带在途外部生成命中硬截止,断言状态进入 `needs-reconciliation` 且 pending/batch/外部生成账本原样保留。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/task_start.rs`、`runtime_driver/game_chat_fast_path.rs`、`runtime_driver/main_loop.rs`、`runtime_tools/file_ops.rs`。
|
||||
|
||||
## 委派幂等与 child 写入测试不能和真实后台 worker 抢状态
|
||||
|
||||
@@ -259,7 +244,6 @@
|
||||
|
||||
## ready-task 对账取消后不能让 successor 永久继承 failed Graph
|
||||
|
||||
- 现象:未知工具结果按安全边界进入 `needs-reconciliation`,人工核对后取消原 child;manifest 随即把该节点投影为 failed,父 game-chat 固定任务图明确失败。随后重试父 Run 虽创建同源 successor,却原样继承 failed manifest,几秒内再次失败,原项目无法继续。
|
||||
- 原因:取消原 reconciliation Run 只负责安全释放 Agent 队列屏障,并不等于 manifest 任务完成;continuation 完成合同保留既有 Graph 进度,却没有区分“普通失败”和“已经人工核对、保留 cancel tombstone 的 reconciliation 取消”。
|
||||
- 处理:旧 action 继续禁止重放或伪造 observation;旧 child 与父 Run 先真实终态。新 Supervisor continuation 仅扫描同 Session、同 source、同有效任务合同的历史根 Run,并要求对应 ready-task 同时存在 `failed / needs-reconciliation` 记录、最终 `cancelled` 记录和 durable cancel tombstone,才把当前 manifest 的同一 failed 节点恢复为 pending,让 scheduler 创建新 child Run。manifest 的读取、筛选、child 证据重验和写回放在同一项目写锁内;每个 task journal 只读取一次并按 parent Run 建索引。较新的无 child Run 默认阻断旧凭证,只有其 root journal 精确证明为旧 failed Graph 在进入 scheduler 前即失败时才允许向前查找;scheduler 自身失败不得被当成该兼容场景。
|
||||
- 验证:构造 reconciliation child、人工 cancel tombstone、failed manifest 和终态父 Run,证明同源 continuation 只重排该节点;并列普通 failed 节点保持 failed,完成合同继续继承原任务 SHA 与项目 baseline,旧 pending action 不恢复。追加覆盖“旧 failed Graph 未调度”的中间 Run 可以跨过,而较新的 scheduler failure 即使没有 child journal 也会阻断更老 tombstone。
|
||||
@@ -4001,7 +3985,7 @@
|
||||
- 原因:试玩失败 liveness 先执行“协作后必须委派”,没有先检查同一父 run 的 ready 未认领回执和 active delivery 容量;生成合同又只要求提供固定 `data-playtest-id`,没有明确每个值必须唯一、可见和启用。
|
||||
- 处理:旧失败仍存在但 ready 回执可认领或 active delivery 已满时,只允许 `agent.run_status` 原子认领/观察既有委派;认领后验证当前 revision,再由父 run 重跑固定试玩。只有当前 revision 自身的新失败且没有待收束交付时才创建后续专业修复。固定试玩控件必须唯一匹配、可见、启用且真实可点击。
|
||||
- 验证:构造 `failed preview@旧 revision + ready delivery@新 revision`,断言顺序为 `agent.run_status -> verification@当前 revision -> preview.validate@当前 revision`,委派总数不超过 3;分别以缺失、重复、隐藏和 disabled 的固定控件验证浏览器失败关闭。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol.rs`、`apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/planning_strategy/autonomous_build.rs`。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol.rs`、`apps/ai-game-creator-shell/src-tauri/src/tests/runtime_actions/planning_strategy/autonomous_game_build.rs`。
|
||||
|
||||
## 隔离 AppData 的长 TMPDIR 会让 Chrome SingletonSocket 超限
|
||||
|
||||
@@ -4161,7 +4145,6 @@
|
||||
- Provider action 安全持久化补充:pending / provider action 的泄密检测不能因裸自然语言短语 `api key` 直接拒绝,否则 `agent.delegate` 中“不要暴露 External Editor API Key”等安全约束会被误报并阻断首批协作。赋值形式只允许完整匹配受控的“未配置 / 不可用 / 禁止读取”等状态或固定无密钥降级说明,不能用 `starts_with` 放行 `none-but-secret`、`not configured; actual value ...` 等安全前缀后的凭据;`**API Key**:`、`` `API Key`: ``、`API Key(生产):` 等装饰或限定标签也必须识别为赋值。结构化字段标记 `apiKey / api_key`、`Authorization / Cookie`、`token / Bearer` 以及已知 secret token 形状仍必须检测并失败关闭。
|
||||
- Windows retry 扫描补充:`Path::strip_prefix(root)` 在 Windows 上得到的相对 `Path` 转字符串后使用反斜杠,不能直接传给只接受 portable `/` 的 Runtime JSON sidecar 读取器;否则 Runner 重启或显式 `--agent-resume` 扫描已到期 retry 时会报“项目文件路径不能包含反斜杠”,任务持续停在 `waiting-for-provider-retry`。目录扫描应按路径组件重组成 `/` 分隔的 UTF-8 相对路径,不要放宽全局路径校验。
|
||||
- 恢复交互:`needs-reconciliation` 即使没有 `pendingToolAction`,也必须提供显式“已核对,结束旧任务”;它只取消旧 run,不直接 retry。若取消后仍有 pending task,由 Runner 自动继续;只有队列为空且旧 run 已取消时,才允许创建新的 retry run,避免重复执行同一用户输入。自主构建 Supervisor 的 retry 不能改写为普通 `agent-background-task` source,必须从已验证的原 Run Profile 绑定恢复 `project-supervisor-gui / project-supervisor-cli` 可信来源;不得只信可追加的 task journal。
|
||||
- Steer source:前端选择可 steer Runtime 时不能只比较 Agent、Session 和 Run Profile,还必须在调用方声明 source 时精确比较持久 `source`。例如 game-chat 只能 steer `project-supervisor-game-chat`,不能把同 Session/Profile 的 `project-supervisor-cli` run 当成目标;source 不一致时应按当前入口新建或排队自己的 run,不能先调用后端再把“steer source 与当前 Run 不一致”暴露给用户。
|
||||
- 验证:前端回归同时覆盖零历史、无 Session 的初始空态、无 active Session 索引但存在持久 `needs-reconciliation` 总控 Runtime 的恢复展示,以及“先取消、队列为空后才重试”;真实 Windows 运行全部 tool-plan handoff 测试,确保相对句柄 rename、覆盖安装、回读和清理均通过。Responses 回归覆盖 system / user / assistant 文本分别序列化,并保留 user `input_text + input_image`;Runtime 回归覆盖“无效计划 → repair transport 等待 → steer → 新 cursor 再修复”,断言 cursor `0 / 1` 各有一条审计且不冲突。
|
||||
|
||||
## 固定画布产物返工不能变成任意覆盖,design-foundation 不能越权修程序
|
||||
@@ -4380,7 +4363,6 @@
|
||||
- 处理:历史花费只累计 `asset_operation_consume` 负向流水绝对值,退款不冲减;通过 `profile_wallet_consumption_total` 在已有投影时按主键 O(1) 累加。首次上线必须在停写维护窗口由 owner 执行全量初始化,为每个已有钱包流水的用户建立投影,不能让所有存量用户的首次正常消费各自扫描历史;维护遗漏或新用户缺行时才在首次消费或详情读取中按用户索引兜底重建一次。手动对账扫描是独立高风险操作,member 必须单独持有 `profile-wallet-consumption-reconcile`,不能因为能打开共享用户详情就自动获得。
|
||||
- 验证:构造消费、退款、充值退款追回和赠送混合流水,断言只累计消费;维护初始化后正常消费只按主键累加;重复详情读取不得重复扫描或重复累计;任意 Tab 权限不能调用手动对账,同时确认充值订单列表的通用钱包快照没有新增历史流水扫描。
|
||||
|
||||
## AI 游戏 game-chat 自动预览不能在调用前消费授权(2026-07-29)
|
||||
|
||||
- 症状:`code-prototype` 首次完成后 `.agent/logs/command.log` 已出现 `permission.confirm preview.start`,但客户端没有 iframe,`.agent/logs/preview.log` 也没有新的 running 记录;后续即使父 run 完成也不再启动。
|
||||
- 根因:旧实现调用 `start_local_game_preview` 前就把“项目 + parent run”的授权加入 attempted 集合并清空;首版完成投影与后续专业任务仍在写项目时,启动恰逢项目写锁竞争,catch 只显示错误却无法重试。
|
||||
@@ -4474,12 +4456,9 @@
|
||||
## “继续”不能成为新游戏主题或触发首版整文件覆盖(2026-08-03)
|
||||
|
||||
- 现象:原根 run 已经写出并验证目标玩法,但父 Runtime 因预算、上下文或 Provider 失败;用户在同一项目输入“继续”后,页面标题变成“继续”,玩法被默认收集/点击模板替换,美术规范总览图被直接铺进游戏画面。
|
||||
- 原因:终态失败 run 不能 steer,提交层因此创建 task 只有继续短语的新 root;每个新 autonomous 根合同又无条件 reset seed manifest;game-chat fallback 从当前 root task 取主题并直接 `file.write game/index.html`。同时快车道把 `icon-spec` 误当运行素材,要求整图背景和象限裁剪实体。通用 smoke/generic playtest 只验证结构与最小交互,无法发现玩法目标已经漂移。
|
||||
- 处理:严格继续意图必须在同一 Supervisor Session、同一持久 source 内继承最近失败根 run 的原始目标和 baseline,但保持新的 run/Provider/sidecar 身份;纯继续词表只能有一个权威实现,中英文短语都走同一入口,真正新需求仍独立 reset。非占位入口禁止 fallback 整体覆盖,也不能反复运行只读 smoke;当前 `code-prototype` 必须先读取并实际 patch,取得本人 mutation 后才能验证和交付。占位 fallback 只支持具备真实语义的显式模板,俄罗斯方块必须实际实现棋盘、下落、旋转、锁定和消行,未知玩法失败关闭。`art-spec.png` 只作规范参考,核心运行时位图必须来自独立派生的透明 `art-spritesheet.png` 及其 `iconImageSrcs` 本地切片;切片清单绑定当前图集 resourceId,Canvas 分别使用玩家、目标、场景和反馈四类素材。不得猜测图集是 2×2 等分、把规范板塞进画面或以纯代码核心实体绕过派生素材。
|
||||
- 验证:覆盖失败根任务“水晶俄罗斯方块”后输入“继续”、连续 successor、跨 Session、跨 source、正常完成后新输入、带具体新需求、既有非占位入口先 patch 后 smoke、初始化占位的俄罗斯方块真实语义、未知玩法失败关闭、纯继续目标缺失、规范图不在运行 DOM/Canvas、真实动作前后 `sequence` 与 RAF 空转。浏览器验收必须同时比较 baseline 玩法关键文本/控件/状态和当前 revision,不能只看 Canvas 非空与三个固定按钮。
|
||||
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/autonomous_completion.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/game_chat_fast_path.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/provider_request_builders.rs`。
|
||||
|
||||
## game-chat 的固定图不能替代主 Agent 对已有美术的理解(2026-08-07)
|
||||
|
||||
- 现象:用户要求把已有美术资源接入游戏时,固定 `code-director -> art-director / art-asset-plan -> code-prototype` 图会在缺少主 Agent 审计的情况下启动美术生成,或把“整体重做”错误实现为无条件生图;美术完成后又换了 Run,代码接入、静态检查和试玩无法形成连续责任链。
|
||||
- 原因:固定节点把“是否需要美术”的语义判断编码为 Runtime 前置流程,`code-director` 成为另一个主控,而不是让真正接入游戏的 `code-prototype` 基于权威资产事实决策;如果再把固定审计策略塞进用户意图字段,Supervisor 的理解也会被 Runtime 规则覆盖。两个素材槽都缺失时若先消耗不可重试的 `art-asset-plan` 委派,其 child 又必然因缺规范图失败,整个 Run 会进入无法补救的死路。
|
||||
@@ -4488,9 +4467,7 @@
|
||||
|
||||
## Tauri beforeDevCommand 失败不等于已启动客户端会自动退出(2026-08-03)
|
||||
|
||||
- 现象:旧 worktree 的 AGC Vite 长期占用 `127.0.0.1:3080`,marker 仍指向旧 API;新 worktree 启动 game-chat 后,配套后端在新端口 ready,随后 `beforeDevCommand` 因代理 target 不匹配返回非零,终端已经回到提示符,但原生客户端和它启动的 Runner 仍存活。客户端 WebView 实际加载旧 Vite,因此当前 master 的界面优化看起来全部缺失。
|
||||
- 原因:Tauri 的字符串 `beforeDevCommand` 默认 `wait=false`。只要固定 `devUrl` 上已有可访问页面,Tauri CLI 可以在配套启动脚本完成前创建原生窗口;旧实现又直接从 npm 启动 Tauri CLI,没有在 CLI leader 退出后继续持有其 PGID / Windows 进程树。`start-dev-stack.mjs` 虽会在后端 ready 后识别 marker/API 错配,但检查时机已经晚于窗口创建,且只清理自己登记的后端和 Vite。
|
||||
- 处理:`dev` 与 `game-chat` 统一先进入 `start-tauri-dev.mjs`,在启动 Tauri CLI 前无副作用检查 3080。现有 marker 只有 API target,不能证明监听器属于当前 worktree,因此任何已存在的 3080 都失败关闭,不主动杀不能证明归属的旧服务,也不因 target 看似匹配而复用。Tauri CLI 使用独立 POSIX 进程组,任意退出后按负 PGID 先 TERM、有界等待、再 KILL;Windows 固定调用 `taskkill /PID <pid> /T /F`。`start-dev-stack.mjs` 自己的后端 / Vite 独立组也在返回前有界收束。
|
||||
- 2026-08-08 后续统一:上述 `3080` 是事故发生时的历史实现,不再是当前 Linux 启动口径。AGC Vite 已纳入系统级用户端口段,首选 `start + 5`,占用时只在本用户段内漂移;外层启动器把最终端口写入 Tauri CLI 动态 `build.devUrl` 和子进程 `GENARRATIVE_AGC_VITE_PORT`,并用 Vite CLI `--port` 启动严格监听。`beforeDevCommand`、配套后端预留、WebView 与 Vite `strictPort` 必须使用同一值。Windows / macOS 仅把 `3080` 保留为兼容首选并允许统一漂移。未知归属监听器仍不得复用或主动终止,但其它用户固定 `3080` 不再阻塞 Linux 当前用户启动。
|
||||
- Linux 容器边界:最小化 CI 容器的 PID 1 可能不回收孤儿后代,进程组在所有可执行成员退出后仍只剩 `Z` 僵尸;此时 `kill(-pgid, 0)` 仍成功,不能据此把已经完成的收束误报为失败。Linux 等待逻辑在 signal 探活后必须核对 `/proc/<pid>/stat`,只把同 PGID 的非 `Z / X` 成员视为存活;`/proc` 不可读时继续使用原保守判断,macOS 等其它 POSIX 平台仍只走 signal 探活。
|
||||
- 验证:定向测试必须覆盖用户段 `start + 5` 映射、同段占用漂移、父子启动器严格复用最终端口、动态 Tauri `--config`、marker 与预检地址一致、未知归属监听器拒绝复用、CLI leader 先退出后同 PGID 客户端仍收到 TERM、忽略 TERM 时升级 KILL,以及 Windows taskkill 的 `/PID /T /F` 参数。正常启动后退出,确认 Tauri 客户端、Runner 和本轮自有后端 / Vite 均按生命周期收束。
|
||||
@@ -4500,7 +4477,6 @@
|
||||
|
||||
- 现象:源码已经移除项目页常驻路径输入框,Windows 客户端却仍显示 `/tmp/genarrative-ai-game-draft`,新“打开项目 / 新建项目”交互也没有出现。
|
||||
- 原因:`apps/ai-game-creator-shell/dist/` 是 Git 忽略的本地构建产物,可能跨提交保留旧 JS;复用旧 `dist`、旧 EXE 或旧安装包时,Tauri 会继续嵌入旧前端。测试模式曾把 `/tmp` 同时当作产品初值,也让旧构建和测试夹具的边界难以辨认。
|
||||
- 处理:产品前端项目页不持有默认路径;首页回车自动工作区仍只由原生 `document_dir()` 决定目标根,测试必须在 harness 内显式注入 `/tmp` fixture。普通与 game-chat release 在 Vite 构建后、Tauri 嵌入前扫描实际 `frontendDist`,命中精确旧路径、缺失产物或链接绕过时失败关闭;不能用仓库级源码扫描误伤合法测试 fixture。
|
||||
- 验证:运行 frontend dist guard 定向测试、AGC AppSurface 的双主按钮 / picker 防重复 / 首页回车自动创建回归、Tauri release `--no-bundle` smoke,并确认新 `dist` 不含旧路径;Windows 实机项目组不得出现常驻路径框或 `/tmp`,原生 picker 从系统默认位置打开。视觉验收检查 `1280×720` 最小横屏与 `1280×800` 默认窗口的紧凑项目表格和原生 picker。
|
||||
- 关联:`apps/ai-game-creator-shell/src/app/constants.ts`、`apps/ai-game-creator-shell/src/features/app-shell/useHomeProjectCreation.ts`、`apps/ai-game-creator-shell/src-tauri/src/commands.rs`、`apps/ai-game-creator-shell/src-tauri/build.rs`、`apps/ai-game-creator-shell/src-tauri/tauri.conf.json`。
|
||||
|
||||
@@ -4512,7 +4488,6 @@
|
||||
- 验证:DOM 与截图不得出现外部品牌或 unsupported 列;AppSurface 覆盖 populated / invalid / empty、搜索与菜单;Playwright 在 `1280×720` 测量无页面级溢出。视频控制在有用时长内,清楚展示搜索、清除、菜单、状态反馈和项目打开结果,每一段都有可观察变化。
|
||||
- 关联:`apps/ai-game-creator-shell/src/features/app-shell/ProjectCreation.tsx`、`apps/ai-game-creator-shell/src/features/app-shell/model.ts`、`apps/ai-game-creator-shell/src/features/app-shell/useRecentProjects.ts`、`apps/ai-game-creator-shell/tests/appSurface/home.suite.ts`。
|
||||
|
||||
## game-chat 快车道首波与已提交回复不能被后续 revision 破坏(2026-08-03)
|
||||
|
||||
- 现象:首波从单个美术任务扩展为三个 Director 后,hydration 若仍只容忍 seed lane 的第一个任务在 manifest 短暂恢复 `Pending` 时收束,另外两个已启动 Director 会被卡住。另外默认 `llm.stream=false` 下的专业 final reply 虽已由 finalization 提交,但后续阶段推进项目 revision 后,早期回复会从 Runtime 查询中消失。
|
||||
- 原因:hydration 例外把“首波”错误收窄成了单个固定或数组第一项任务;`visible_game_creator_agent_runtime_response_stream_at` 又把未提交流的 revision 新鲜度门误用到了已终态提交的 durable final reply。
|
||||
@@ -4524,7 +4499,6 @@
|
||||
|
||||
- 现象:生成提交发生客户端超时、连接中断或响应丢失后,调用方创建新的 `Idempotency-Key` 再提交一次;原任务其实已经入队,最终造成重复生成、重复扣费和重复画布 / 素材库写入。
|
||||
- 原因:把“客户端没有收到结果”误判为“服务端没有受理”,又没有持久保留逻辑请求的幂等键和服务端返回的 `operationId`。托管 MCP 若绕过 External REST router 直接调用 worker 或 SpacetimeDB,也会形成第二套去重与状态语义。
|
||||
- 处理:一次逻辑生成只分配一个稳定幂等键。桌面 Runtime 在 POST 前先把 endpoint、精确请求体字节、SHA-256 和幂等键原子写入私有生成账本并回读一致;收到 `202 + operationId` 后先把账本升级为 `accepted` 再轮询。`accepted` 只恢复 GET;`prepared` 或提交响应丢失时,只允许校验账本身份、配置指纹和请求 SHA 后,以账本保存的原 endpoint、原始正文与同一键恢复同一逻辑 POST,不得重建画布上下文、重组正文或换键。恢复 `202` 后继续 GET,恢复再次 transport 失败仍保留原账本;轮询超时只保留既有 operation 并恢复 GET。game-chat 的 4500 秒硬截止可以结束本轮、关闭预览和客户端,但 executing 的 `canvas.asset_generate` 必须保留 pending action、provider batch 与生成账本;旧 `200` 图集的 `spritesheetResource` 允许为空,此时只在顶层 `spritesheetImageSrc` 是有效下载引用时优先使用,否则回退可用 `objectKey`。`202` 缺 operationId、状态损坏与 `postprocess-failed-source-preserved` 仍进入对账边界;其它 non-blocking warning 继续消费成功结果并单独展示。旧 `200` 兼容不改变权威 External v1 的异步契约。MCP 生成工具必须把 `idempotencyKey` 映射到同一 REST header,并复用同一 External router、owner 和任务账本。这是 External v1 的专用幂等恢复,不是通用副作用自动重放。
|
||||
- 补充:不能把“accepted 分支里没有生成 POST”误当成 GET-only 恢复。若读取账本前仍重做项目/素材目录准备、输出路径预检或请求正文构造,恢复仍可能创建远端资源或在查询 operation 前失败。恢复必须直接使用 durable snapshot;清理必须最后删除 pending 身份锚点,活动 orphan 不得自动删除。完整恢复 future 还要在默认 Tokio worker 栈下验证,不能靠测试环境调大 `RUST_MIN_STACK` 掩盖栈溢出。
|
||||
- 加固:durable snapshot 必须绑定不含明文凭据的规范 base URL 服务身份指纹;服务地址漂移时恢复 POST 和 GET 都必须阻断,Developer API Key 轮换则必须继续原 operation。accepted operation 明确 failed 也不能在 observation 持久化前删账本。旧 `200` durable result 只保留允许字段与安全 objectKey/相对路径,签名 URL、query/fragment 和未知字段不落盘。只有首次提交直接返回契约明确的 `400 / 401 / 403` 才可证明未入队并清理 prepared 账本;首次结果已经未知后,恢复请求的临时鉴权错误、超时、冲突、限流、网关错误及其它意外状态均保留同一账本。账本根目录、扫描和删除必须通过受控路径解析逐级拒绝符号链接,不能让项目内链接把清理目标指向项目外。
|
||||
- 代理 DNS:Clash 等透明代理可能把公网对象存储域名解析到 RFC 2544 的 `198.18.0.0/15` fake-IP。下载器只对已通过鉴权 `objectKey` 或受控 legacy path 换签得到的 URL 接受“全部地址均位于该 benchmark 段”的窄例外;直接 URL、其它本机/私网地址、公私混合解析和重定向仍必须失败关闭,不能为了兼容代理整体移除 SSRF 校验。
|
||||
@@ -4630,7 +4604,6 @@
|
||||
## 2026-08-05 不要把 static smoke 当作完整专业交付
|
||||
|
||||
- 现象:code-prototype 已通过 `game.static_smoke`,但完成门明确报告 `missing-visible-art-slice-use`;随后每轮 thinking summary 都是“已取得验证证据”,没有新 action,最终 loop-budget-exhausted。
|
||||
- 根因:game-chat 快车道只看 verification gate 就返回确定性交付,完整 autonomous completion blocker 直到空 action 的最终收束阶段才被发现;Provider 因而永远拿不到下一轮修复机会。失败的 `file.patch` 也会因验证凭证保守失效而推进 revision,若快车道只比较 `mutationRevision`,会把“文件未修改”误认成本 Run 已修改。已有未完成计划收到 steer 后若再追加一整套新步骤,还会与 retained completed 步骤合并成超过 8 步,随后稳定重复 `runtime.plan_update blocked`。
|
||||
- 处理:确定性交付与自动 plan completion 都必须先通过完整 completion gate,并要求当前 Run 最后一条同 mutation 工具调用与 Agent DB 中严格绑定当前身份的 `status=ok` receipt 一致;pending action 的 steer cursor fingerprint 也必须一致,失败 patch 或旧 Run receipt 不能取得交付资格。新 blocker 不回退旧 completed 步骤:已有非终态步骤时用明确 repair step 替换首个非终态步骤,其余保持 pending;只有全 completed 且仍有容量时才追加。8 步已满时进入外部 repair lane;计划已有 failed 步骤时立即失败关闭。回归同时覆盖失败 patch、跨 Run receipt、非零 steer cursor、8 个 completed 与 blocker,以及 failed plan 在 ownership/blocker 不同组合下都不会继续空转。
|
||||
|
||||
## 2026-08-05 Runtime 时间戳必须验证 Date 范围并保持来源身份
|
||||
@@ -4646,14 +4619,12 @@
|
||||
|
||||
## 2026-08-05 Canvas 可达性不能在扇入调用图中回退 visited
|
||||
|
||||
- 现象:game-chat 的 code-director 长期显示 queued,Runner 单核持续高 CPU,durable cancel 也无法被事件循环处理;manifest 已提前显示 running,用户看起来像“稳定卡死”。
|
||||
- 根因:大 classic script 虽使用了 bounded direct-call graph,但 `javascript_named_function_is_reachable` 在递归返回时删除 visited,只阻止当前环,不记忆已经遍历的祖先。render/update 图的大量重复调用让同一节点指数重算;父完成门又在 code-prototype 未完成时提前深验四个 Canvas 切片,使第一次 wake 就同步阻塞,200 次外层重试预算完全没有机会推进。
|
||||
- 处理:单次可达性查询每个 function node 最多访问一次;全 `None` alias 历史直接返回,稳定外层初始化使用有调用前置证明的快路。父完成门只深验 Completed seed task,wake 预算耗尽写入 reconciliation。格子游戏的符号坐标只在唯一数值 `COLS / ROWS / CELL` 与画布范围能共同证明时接受,普通无界动态坐标继续拒绝。
|
||||
- 验证:永久 fixture 至少包含 48 层重复扇入调用、IIFE 外层素材初始化、格子常量绘制、无界坐标反例和整画布尺寸引用;真实项目的全部四个切片还要在同一轮秒级返回 true。禁止用延长 queued timeout、Tokio timeout 或 synthetic 小脚本通过来替代真实大脚本复验。
|
||||
|
||||
## 2026-08-05 Canvas clamp 与 parent wake 不能走字符串或易失兜底
|
||||
|
||||
- 现象:通用 game-chat fallback 明明把玩家坐标限制在当前 Canvas 内,完成门仍报 `missing-visible-art-slice-use`;反向放开任意动态坐标又会让离屏绘制或错误 Canvas 假通过。
|
||||
- 根因:Canvas owner 收紧后正确禁用了含尺寸成员的字符串兜底,但 AST 数值区间器尚不认识嵌套 `Math.min / Math.max` clamp。若只查源码包含 `canvas.width`,无法证明该 Canvas 创建了当前 context,也无法排除局部伪造 `Math`。
|
||||
- 处理:只在 semantic 证明未遮蔽全局 `Math`、上界读取当前 context 所属 Canvas、下界为 `0` 时生成有限区间;加入错误 Canvas、遮蔽 Math 和无界坐标负向回归。不要用字符串包含、变量名白名单或把未知动态值当 `0`。
|
||||
- 现象:parent wake 的 200 次瞬态预算耗尽后 Runtime 仍长期显示 running,或 lane 忙、取消、child 前进、manifest 损坏时 reconciliation 被静默丢弃或覆盖新状态。
|
||||
@@ -4986,7 +4957,6 @@
|
||||
- 现象:用户明确要求重做美术或切换游戏主题,工具仍立即返回 `assets/art-spec.png`、`assets/direct-game-background.png`、`assets/art-spritesheet.png`;新需求没有 Provider operation,游戏继续使用旧图。切片虽然已经落盘,也可能不出现在资源管理或工具结果中。
|
||||
- 原因:旧 Direct 工具只有 `brief`,完整包校验成功后无条件短路;固定阶段账本恢复又未比较本次生成 prompt。切片只写文件和切片清单,未作为顶层 manifest asset 投影;工具桥只返回三条主路径并丢失切片与 warning。
|
||||
- 处理:显式重做使用 `mode=regenerate`,普通请求使用 `reuse-or-create`。重生成必须由当前最新 User 消息明确授权并绑定客户端稳定 `clientTurnId`。授权先对完整原文做 Unicode NFKC 与撇号规范化,随后整串必须完整匹配审核过的独立立即执行指令,只允许句号/感叹号收尾;不得剥离引号、方括号或代码片段,动作前后也不得携带 brief、条件、否定、选择、确认、费用、延迟或其它文本。风格需求先单独描述,再由下一条独立“请重新生成美术”消息确认;不要靠扩充 deny 同义词推断付费同意。同一调用完成回包丢失只从 `completed` 持久结果等值重放,不能因重试再次扣费。App 必须在 Direct 调用前落盘原始 User 消息和回合 ID,Tauri 必须在成功返回前幂等落盘同 ID assistant 终态;同进程重复水合若命中“回合仍在运行”,只能显示瞬时占用提示,不得以稳定 assistant messageId 写成终态并抢占原执行的成功回复。恢复扫描与启动前置恢复必须发现 `resetting / compensating / anchored in-progress` 并在专用锁内恢复,重开项目只续跑真正未回答的原身份。整条付费链必须持有专用跨进程执行锁;换新回合时先持久化 `resetting` 再清理旧阶段账本,不得通过删除 workflow 留出无主窗口。崩溃补偿只恢复旧文件并清 replacement CAS 锚点,已 `prepared / accepted` 阶段账本、原 `Idempotency-Key / operationId` 必须保留,同冻结意图续跑复用旧请求;未知账本在文件 mutation 前失败关闭。只有没有任何阶段账本和替换锚点的孤立 workflow 空壳可原子接管;旧 schema 和其余冲突失败关闭。遇到 prompt 或当前 art-spec 身份不一致的未决账本必须保留原 operation 并返回对账错误。Direct app-server 可写边界只限真实 canonical `game/`,canonical 项目根的原生 OS 路径字节与权威 manifest `projectId` 经域标签和独立长度前缀编码后共同绑定连接池和 thread 身份,不得写项目根、`assets/`、`.agent/`,也不得获得网络、命令、MCP 或权限扩权;受控工具如果需要项目级客户端状态,只能从同一真实 `game/` cwd 经相同校验内部反查项目根,不能扩大模型可写根。标准图集首次创建和重生成都要求四张透明、可见、像素及平台身份唯一的 canonical 切片;工具只回传通过私有回执、公开清单、源图和顶层登记交叉验证的 `slicePaths` 与安全 `resources`。部分/opaque/重复/缺回执切片必须告警,不能把公开清单或顶层自述身份当作 Canvas 权威。
|
||||
- 验收:不要把规范图当运行态素材,也不要用 prompt 证明图片内容。程序门检查透明/可见像素、唯一性、来源、登记和源码/双视口渲染;背景排除实体、无缝地面、管道或角色尺寸等仍需观察返回图与真实试玩截图。Direct 修复不能外推为 game-chat 已支持有效旧包强制替换。
|
||||
- 同进程恢复补充:命中“同一 stable turn 仍在运行”后除禁止写 assistant 终态外,还必须删除当前 App 实例的恢复 claim。这样原调用随后成功时显式刷新能读取其终态,随后失败时也能按相同 `clientTurnId` 再次续跑;不要靠重载 WebView 清理进程内 claim,也不要用无界定时轮询制造并发调用。
|
||||
- 严格图集崩溃补充:规范图和背景图的两文件 rollback 不覆盖严格图集事务已经整体修改的 `.agent/manifest.json`、私有回执、公开清单、主图集、四切片和切片清单。必须在严格调用前持久化 pending 及九项旧合同身份;重启恢复先对账底层严格事务,完整新合同直接收口完成,完整旧合同才补偿前两阶段,混合或漂移状态失败关闭。不要在严格提交成功后局部恢复前两张图。
|
||||
- 部分旧包补充:rollback 的规范图/背景图必须保存旧字节与旧 manifest entry,不能把这两项缺失隐式当成空内容;显式 `regenerate` 因此只在这两项可信可回滚时开放。历史主图集、私有回执、公开清单或 canonical 切片可以缺失,但八个严格路径与受管顶层 asset identity 必须逐项冻结其真实 `Present/Some` 或 `Missing/None` 状态,补偿也必须恢复相同存在性。不要因为旧美术包缺切片而阻断重生成,也不要把本轮新建的严格文件误记成旧文件。
|
||||
|
||||
@@ -1085,7 +1085,6 @@ Runtime 只在以下客观条件同时满足时写 `contractStatus=evidence-read
|
||||
|
||||
### 单层 repair
|
||||
|
||||
当前可信父 Run 只有在已认领同一父 Run 的原 delivery,且原回执为 `needs-repair` 或父 Run 明确判定语义未满足时,才能发出新的 `agent.delegate`,并把 `repairOfDelegationId` 指向该原 `delegationId`。可信父 Run 包括原 `project-supervisor`,以及通过 `project-supervisor-game-chat` 根绑定、父 binding fingerprint 和 task/session/run/delegation 身份链完整证明的唯一 `code-prototype` 主 Run;仅凭 Agent ID、task 文案或错误关键词不得获得该权限。被引用记录必须属于当前可信父 Run、状态为 `claimed-by-parent`,且自身不是 repair;返工目标必须与原 delivery 的专业 Agent 完全一致。
|
||||
|
||||
repair 深度固定为 `1`;同一原 delivery 同时最多存在一个非 `suppressed` repair。相同 durable action/身份重放必须幂等复用已预留或已创建的 repair;不同 action 的重复或并发竞争必须在 delivery 锁内发现既有非 suppressed repair 后拒绝,不能创建第二个活跃目标 run、第二份可认领回执或 `-dup-*` repair。repair 结果继续唤醒、认领并收束到原可信父 Session/run;它不能创建第二条面向用户的 assistant。repair 再次 `needs-repair` 时不得继续嵌套委派,当前可信父 Run 只能基于现有证据裁决或由根 Supervisor 走用户输入门禁。`suppressed` repair 不视为已完成返工,原 `repairRequired` 门禁必须继续阻断 finalization;同一 durable action 可以在无终态字段时把原 delivery 恢复为 `dispatched`,若该 action 已持久失败,新 action 也只可在既有 repair 全部 suppressed 时创建替代的基础设施投递,不能形成第二轮语义返工。已 suppressed 且未形成 child task 的旧 delivery 不再参与 capability、claim 或 completion barrier 的身份验证,避免恢复入口被失败前置记录永久堵死;所有非 suppressed delivery 仍必须逐条通过完整可信链校验。
|
||||
|
||||
@@ -1095,7 +1094,6 @@ repair 深度固定为 `1`;同一原 delivery 同时最多存在一个非 `sup
|
||||
|
||||
- 专业 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 门禁。
|
||||
- 当前可信父 Run 的 prompt 必须明确:不得把 `evidence-ready` 当作自动语义通过,不得忽略或吞掉 `needs-repair`。game-chat `code-prototype` 发现 ready delivery 时必须先以确定性 `agent.run_status(scope=self)` 认领并观察;普通失败或不合法安全默认 marker 在认领后立即失败收束,不得再发 Provider 请求。只有完整合法的 `game-chat-safe-default-repair.v1` marker 允许一次同合同返工;该返工由 Runtime 直接按原 `targetAgentId / acceptanceCriteria / expectedArtifacts / delegationId` 生成确定性 `agent.delegate`,不再请求 Provider 决策。repairRequired 存在时重复 route、读取、查询或其它计划全部由 liveness 门拒绝;第二层返工、目标 Agent 变化、合同扩大或身份漂移全部失败关闭。对无法自行裁决的冲突、缺失决策或用户偏好,只能由根 Supervisor 汇总后通过既有 `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。可信 `code-prototype` 只能管理其绑定的内部 delivery 并收束自身 Run;只有根 `project-supervisor` Session/run 可以写入唯一正式用户 assistant 和根 completed 投影。
|
||||
|
||||
### Provider 多 action 原批次门禁
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -119,7 +119,7 @@ git diff --check
|
||||
干净安装验收必须在没有历史根或子 App `node_modules` 的隔离工作树执行。平台补充门禁:
|
||||
|
||||
- Linux:根、后台、预览部署器、Spine 工具构建,Desktop/AGC Tauri release smoke。
|
||||
- Windows x64:根 `npm ci` 后执行 AGC game-chat release,核对 Codex sidecar 完整性。
|
||||
- Windows x64:根 `npm ci` 后执行 AGC Tauri release smoke,核对 Codex sidecar 完整性。
|
||||
- Android:Expo config/export,并在可用 EAS 环境执行一次本地 Android build。
|
||||
- macOS/iOS:在可用 runner 执行 simulator build;缺少 runner 时必须标记未验证。
|
||||
|
||||
|
||||
@@ -58,7 +58,6 @@ apps/ai-game-creator-shell/src/features/asset-canvas/tauriImageCanvasHostAdapter
|
||||
- `image-canvas-core` 只含纯 TypeScript 的画布模型、几何、选择、图层命令、历史、序列化、防御校验和状态机;不得依赖 React、DOM、Tauri、HTTP、账号、钱包或浏览器存储。
|
||||
- `image-canvas-react` 只含 React 视图、hooks、交互控制器和通用 UI,依赖 core 和注入的 Host Port;不得直接 import Tauri API、站点请求客户端、账户 store 或钱包 store。
|
||||
- 网站 adapter 可以依赖账户、钱包、现有服务端 editor project、云端素材库、OSS/asset object 和生成 API。
|
||||
- Tauri adapter 可以依赖 `invoke/listen`、本地项目上下文、受控媒体命令、manifest、项目 revision、草稿 sidecar,以及宿主进程内的陶泥儿账号会话快照。普通模式的服务 origin 由构建环境固定;网站 Access Token 延续现有 WebView 客户端存储,GUI 与 Runner 只接收当前 `userId + Token + authGeneration` 内存快照,不把 Token 写入 Rust AppData 配置、共享画布或项目事实。仅独立 standalone game-chat release 或显式高级自定义模式可以读取其隔离 AppData 中的 External v1 Developer API Key 配置。
|
||||
- 依赖方向只能是“宿主 adapter -> React/UI -> core”。core/react 不得反向 import 任一宿主。
|
||||
|
||||
### 3.2 禁止复制的验收门
|
||||
@@ -200,7 +199,6 @@ interface ImageCanvasHostPort {
|
||||
- `hostRevision` 是宿主权威提交版本的字符串表示:Tauri 使用十进制项目 mutation revision,网站使用现有服务端 editor project revision。共享 UI 只透传/展示,不比较不同宿主的 revision。
|
||||
- `commitId/idempotencyKey` 由共享流程在第一次正式保存前生成;响应未知时两宿主都复用原完整请求。`expectedHostRevision` 由 adapter 从已加载的权威宿主快照提供,Tauri 必须无损解析为本文的安全整数 `expectedRevision`。
|
||||
- Web adapter 把草稿、导入、生成、导出和提交映射到现有服务端 editor project、云端素材库及账户/钱包链路。
|
||||
- Tauri adapter 把草稿、导入、导出和提交映射到本文第 7 至 11 节的本地合同;普通模式远端媒体编辑固定使用官方 origin 下的 `/api/editor/*`、`/api/assets/*` 与 `/api/runtime/external-generation/jobs/*`,后端从网站 Access Token 解析 owner 并进入统一生成队列与泥点预扣/退款。普通 Launcher、开发工作台和已认证 game-chat 均不显示或维护 Base URL / API Key。仅独立 standalone game-chat release 或显式高级自定义模式使用隔离 AppData 的 `editorApi.baseUrl/apiKey` 调用 `/api/external/v1/*`;两种模式的凭据都不能进入共享画布、项目 sidecar、manifest、事件或错误正文。
|
||||
|
||||
### 3.4 主站 UI 对齐与共享画布 chrome
|
||||
|
||||
@@ -962,7 +960,6 @@ confirmation-required
|
||||
|
||||
### 14.4 首版请求范围与恢复
|
||||
|
||||
- 主站网页画布与普通 AI 游戏创作 Tauri 客户端统一使用 `POST /api/editor/images/generations`、`POST /api/editor/images/edits` 与 `GET /api/runtime/external-generation/jobs/{operationId}`。普通 AGC 使用登录后的平台 Access Token 和稳定 `Idempotency-Key`;提交同时兼容站内 `200 + queueState.operationId` 与 inline 完成响应,队列状态读取 `job` 包装。官方 origin 由构建环境固定且不可由普通用户修改。第三方 Agent/CLI、独立 standalone game-chat release 或显式高级自定义模式仍走 `/api/external/v1` 与 Developer API Key。
|
||||
- 普通模式图片生成和编辑支持相同 prompt、`1:1 | 2:3 | 3:2 | 9:16 | 16:9`、`0.5K | 1K | 2K`、合法 `assetKind` 与参考资源约束。refine 的 `sourceReferenceId` 必须是当前账号已登记的服务端项目 resourceId 或素材 assetId;`objectKey`、URL、本地 `local-asset:*` 与 `assetObjectId` 都不能冒充该业务引用。本地独有图片在用户确认后先走 `/api/assets/direct-upload-tickets` → OSS form → `/api/assets/objects/confirm`,再创建当前账号拥有的项目资源或素材记录,取得正式 ID 后才可进入编辑请求。额外参考最多 8 个。高级 External v1 模式使用同一业务引用约束,但走其独立外部路由与 Developer Key 鉴权。
|
||||
- 客户端参考媒体直传固定复用 `legacyPrefix=generated-character-drafts`,不得把内部用途目录作为新 legacy prefix,也不得扩大服务端白名单。图片画布的 `pathSegments` 固定为 `editor / asset-canvas-references / <projectId> / <draftId> / <generationId>`;全类型资源编辑的本地视频、音频等源媒体固定为 `editor / resource-editor-references / <projectId> / <operationId>`。两条路径都只持久化 confirm 后的稳定 objectKey,不持久化 ticket 或签名 URL。
|
||||
- 图片参考资源准备失败按阶段投影安全错误码:本地读取/校验为 `reference-material-invalid`,票据为 `reference-ticket-failed`,OSS 表单上传为 `reference-object-upload-failed`,对象确认为 `reference-confirm-failed`;`401` 进入当前账号代际的单飞刷新,刷新失败或重试后仍未授权才返回 `authentication-required`,`403` 直接按权限不足处理。任一阶段失败都必须保持 `operationId=null`、生成 endpoint/request body 未建立,不得进入扣费或生成提交。普通错误不得包含 ticket host、formFields、policy、signature、Token、API Key、Provider 响应正文或本机绝对路径。
|
||||
@@ -993,7 +990,6 @@ confirmation-required
|
||||
- 资源聚焦态的所有现役资源均提供“编辑资源”,覆盖 manifest asset、已完成任务产物、已导入附件、Agent 文本回执和项目版本。后端必须按 manifest、任务完成态、上传登记或回执身份重新核验来源;没有唯一来源身份的本地媒体不得仅凭前端路径进入编辑。
|
||||
- 静态 PNG / JPEG / WebP 继续使用 `AssetCanvasSurface + intent=refine`,自动加载唯一源图片,并把源资源身份作为图片编辑请求的必选引用。任务产物或附件中的静态图片必须先正规化为正式 manifest asset,再进入现有图片画布。
|
||||
- refine 入口不能只在 WebView 进程内缓存 `draftId`。每次打开先在正式 draft sidecar 中按 `projectId + intent=refine + sourceAssetId + active status` 有界发现:唯一命中沿用原 `draftId` 并生成新 `sessionId`,零命中才创建,多命中进入 `reconciliation-required`;`committed/cancelled` 不属于 active 候选。
|
||||
- 普通客户端确认编辑后固定调用 `POST /api/editor/images/edits`;提示词、比例、尺寸、资源用途、泥点计费和原 operation 恢复继续复用现有生成合同,请求凭据来自当前平台登录态的 native 内存快照,不进入资源编辑账本。独立 game-chat/高级自定义模式保留 `/api/external/v1/editor/images/edits`。
|
||||
- SVG、UTF-8 文档、代码和 Agent 文本回执使用文本差异派生:把源内容当作不可信数据交给当前客户端 LLM,响应必须是完整、唯一的结构化内容 envelope;JSON、SVG 等可校验格式必须在落盘前重新校验。结果写入新的本地路径和 manifest asset,不能直接写回源文件。Agent 回执原记录不转写、不删除,新 asset 以回执资源身份登记血缘。
|
||||
- 文本、SVG 与 Agent 回执在 Provider 调用前必须先持久化 request-issued;成功响应必须先原子安装到与原 operation、请求指纹和内容摘要绑定的私有 durable handoff,再做 envelope 解析、格式校验和 staging。issued 后缺少可信 handoff 只能对账;handoff 已存在且校验通过时恢复只消费该正文,两种情况都禁止再次调用 Provider。
|
||||
- 普通客户端视频使用 `POST /api/editor/videos/generations`。有稳定远端引用时直接作为 `referenceVideoSrcs`,只有本地文件时先走 `/api/assets/direct-upload-tickets`、OSS 表单上传和 `/api/assets/objects/confirm`,再提交同一逻辑生成;结果必须下载到新的本地文件并登记远端稳定身份。
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
# 立项策划 Agent(Fast GDD)技术方案
|
||||
|
||||
- 日期:2026-08-10
|
||||
- 状态:2026-08-12 **M0 代码工作包全部完成**(`M0A-2`、`M0B-1`、`M0B-2` 已合入 M0 集成分支并通过各自门禁,见第 23.4 节);同日 **D6 作废、拓扑改变**,`M0A-1` 交付的文档基线随之失效,需以工作包 `M0A-3` 修订,**修订完成前 M0 不计完整完成**(见第 1.1 节)。2026-08-13 **D9 二次作废、D10 作废,由 D11 取代**:立项策划节点改为 Project Supervisor 通过 `agent.delegate` 发起的静态委派子 Agent,问询复用 PR #165 中转链路(见第 1.1 节「D11 新拓扑」);D11 依赖 WP1(静态委派澄清轮次与返工深度拆分)为强制前置,**该前置已于 2026-08-13 落地并合入**(`WP1` 生产代码 + `WP2` 回归,完成状态与门禁见第 23.5 节),澄清轮次上限现为 3(game-chat source 仍为 1)。随后 `M1A-1`、`M1A-2`、`M1A-3`、`M1A-4` 已分别落地:`M1A-2` 仅收口两层工具面、`project-planning` role brief 注入和 fail-closed 拒绝边界,`M1A-4` 收窄 plan 根 run 的子 Agent 创建面。**2026-08-14 `M1B-1` 已通过门禁并合入本分支**:已落地 `.agent/planning` storage module、strict schema/typed 指纹/canonical parser、GDD 版本链、session 原子恢复、Runtime 写入身份及只挡写门禁;golden vector 与 11 个定向 storage 测试通过,writer/index/recovery 门禁已完成。**2026-08-15 `M1B-2` 工作包已通过本包门禁并以 `27c3eb847` 合入本分支**:已落地 `plan.submit_gdd`、exact planning Provider binding/structured injection、专用提交点与崩溃恢复;本包不包含 `gdd-approval` planning pending、审批等待、receipt、审批命令或 UI。**2026-08-14 `M1C-0` 已合回本分支**:仅新增用户修订状态及 lineage 分类,不包含审批写入方。**2026-08-15 `M1C-0b` 已通过定向门禁并完成**:只改静态委派 durable status 的前向兼容读路径,未知字符串显式保留为 `Unknown(raw)` 并最大化阻塞;不含审批写入方。`M1C-1` 与 `M1C-2a` 已提供审批核心、固定 Goal Contract、完整分页 `file.read` evidence、claim 后三态 acceptance gate、审批 pending 恢复及 completion/finalization 门。**`M1C-2b` 已完成本包实现并通过门禁,现已快进合回 `feat/five_min_design`**:planning 澄清中转、确定性 continuation/session 投影、审批后用户修订谱系、Provider 活跃时间预算与末次 submit usage fold 已实现,11 条 `planning_clarification_*` 回归及关联 Rust 门禁通过。审批 UI、hydrate、构建准入与下游完整构建仍后置,M1 整体不可交付(见第 23.6、23.8 节)。
|
||||
- 适用范围:AI 游戏创作独立 App、Project Supervisor、Agent Runtime、本地项目策划 sidecar 与后续完整构建准入
|
||||
- 当前实现边界:本文件是后续详细设计与实现的仓库内阶段基线;M0 工作包冻结 Fast GDD 合同并修复现有 owner 验证、game-chat retry 与前端投影边界,`M1A-1`~`M1A-4` 已提供 plan source、两层工具面、角色 brief 与子 Agent 创建面收窄的 Runtime 基础,`M1C-0` 已提供用户修订 lineage 分类,已合入的 `M1B-1` 提供 storage 基础与写入隔离;`M1B-2` 已提供提交点与恢复,`M1C-0b` 已补齐静态委派未知 durable status 的前向兼容读路径,`M1C-1` 已提供 receipt/审批核心、投影恢复和 plan 根完成门,`M1C-2a` 已补齐固定 Goal Contract、验收图证据与生产 acceptance gate。`M1C-2b` 已实现 planning 澄清中转、三轮确定性 session/continuation 投影、审批后修订谱系和 Provider 活跃时间预算,并已合回 `feat/five_min_design`;`M1D-1` 已提供 hydrate/read model 与审批卡,`M1D-2` 已接入新项目入口分流、阶段进度和实际项目总控页面挂载;`M1E` 已完成 submit 连续拒绝的有界收束、重启恢复边界与既有回归覆盖审计。M1 策划闭环完成;approved GDD 构建绑定与完整下游留给 M2。
|
||||
|
||||
## 1. 背景与目标
|
||||
|
||||
@@ -16,7 +14,6 @@
|
||||
1. 一句需求经过不超过 3 轮关键澄清,形成包含一个完整可玩闭环的 Fast GDD。
|
||||
2. 策划阶段没有构建、委派、生成、预览或通用文件写能力。
|
||||
3. GDD 版本、用户决定和构建引用都有确定提交点、强身份绑定、幂等重放和崩溃恢复合同。
|
||||
4. 老项目与“直接开建”保持现行行为;是否策划不成为 game-chat 的强制前置条件。
|
||||
5. 后续 M1 无需任何仓库外材料即可实现 source、Prompt、工具、schema、审批与恢复。
|
||||
|
||||
非目标:
|
||||
@@ -25,7 +22,6 @@
|
||||
- M0/M1 不修改现行 16 任务 DAG,不新增第 17 个任务。
|
||||
- 本期不实现知识图谱;只保留强类型可空槽,v1 必须为空且 UI 不渲染。
|
||||
- 不提供引擎选择字段。平台只有自包含 Web 运行事实,由 Runtime 注入并校验。
|
||||
- 不修改现役 game-chat 单主 `code-prototype` + 按需美术 child 结构。
|
||||
- 不修改 SpacetimeDB、HTTP API、OpenAPI 或 `shared-contracts` 中的正式作品数据合同。
|
||||
- M1 不实现 300 秒硬停;以 3 轮硬上限和 240 秒 Agent 活跃时间软提示收束。
|
||||
|
||||
@@ -61,8 +57,6 @@
|
||||
| --- | --- | --- |
|
||||
| `M0A-1` 文档基线 | **需修订**,即本工作包 `M0A-3` | 是 D6 的唯一载体 |
|
||||
| `M0A-2` owner 产物验证 | **不受影响,但不可复用** | 见下 |
|
||||
| `M0B-1` game-chat 美术边界 | **不受影响** | 只处理 game-chat 单主谱系 |
|
||||
| `M0B-2` game-chat 前端投影 | **不受影响** | 只认 game-chat root → 单主 `code-prototype` 谱系 |
|
||||
|
||||
M0 三个代码工作包无一行按 D6 编写,**不需要为新设计回退或修改任何已合入代码**。在本次 M0A-3 文档修订时,全仓库检索 `fast_gdd`、`.agent/planning`、`project-supervisor-plan-chat`、`is_exact_supervisor_plan_run_at` 均零命中,M1 代码尚未落地,因此改文档没有迁移成本;后续 M1A 工作包的落地状态以本文当前状态行和第 23.6/23.8 节为准。
|
||||
|
||||
@@ -126,7 +120,6 @@ D9/D10 描述的「manifest ready-task 调度器在 Supervisor 下游启动策
|
||||
5. **前置依赖:D11 的“最多 3 轮问询”依赖 WP1 先落地,是强制前置,不是并行工作包。该前置已于 2026-08-13 落地,本条改为记录其成立依据与已完成状态。** WP1(澄清轮次 `clarification_round` 与返工深度 `repair_depth` 拆分,语义见下方,权威定义见 decision-log 2026-08-13 条)与其回归工作包 `WP2` 已合入本分支,完成状态与门禁见第 23.5 节。作为对照记录改造前的事实:改造前 `repair_of_delegation_id.is_some()` 即拒绝(`apps/ai-game-creator-shell/src-tauri/src/delegation.rs:1119-1121`),澄清 continuation 与质量返工共用同一条「深度最多为 1」判据,D11 描述的多轮问询实际上限只有 1 轮,且这 1 轮一旦用掉,同一条委派链就再也做不了任何质量返工;该结论由 `clarification_continuation_chain_supports_multiple_rounds` 走真实 `agent.delegate` 生产路径实证(改造后该用例的断言方向已按预期行为变更反转,见第 23.5 节)。本条不因 WP1 完成而降格:D11 的 3 轮问询能力**只在 WP1 语义生效的前提下成立**,任何回退 WP1 的改动都同时回退 D11 的问询上限。
|
||||
6. **登记机制已定稿(原「未决前置」,2026-08-13 处置完成):`project-planning` 的编译期 agentCatalog 登记方式,不会撞上 `build.rs` 一致性校验。** `project-planning` 目前不在编译期 agentCatalog 里;`build.rs` 的 `validate_seed_task_catalog`(`apps/ai-game-creator-shell/src-tauri/build.rs:23-46`)要求编译出的 `(taskId, groupId, role)` 集合与 `shared_contracts::game_creation_app::new_game_creation_app_seed_tasks()` 逐项相等,不等直接 `panic!`;但该集合只来自 `manifest.agent_catalog.groups[].roles[]`(`build_support/runtime_prompt_bundle.rs:387-398`),不遍历 `agentCatalog` 其它顶层键。结论:`project-planning` 登记为与 `supervisor` 平级、不进 `groups` 数组的独立条目(先例即 `supervisor` 自己——它是 catalog 成员但不是种子 DAG 任务,`runtime_adapter.rs:4-38`),`new_game_creation_app_seed_tasks()` 不需要新增条目,该 catalog 本身也不需要拆分。完整机制、descriptor 元数据取值与编译链路改动清单见第 3.1 节。**但登记只解决 catalog 成员资格,不解决可执行性**——第 3.1 节调研同时发现一个新的、真正阻塞可执行的缺口:`prompt.rs` 的 `game_creator_agent_role_definition`(`prompt.rs:661-679`)硬编码「非 supervisor 即 group 角色」二分,不认识 `project-planning`,需 M1 补一个平行分支;这才是仍然待处置(M1 范围)的前置,不是本条描述的 catalog 登记方式本身。
|
||||
|
||||
WP1 定稿的澄清轮次/返工深度语义(供 D11 依赖,权威定义见 decision-log 2026-08-13 条,不在本节重复展开):`repair_depth` 上限维持 1 不放松,`clarification_round` 上限按 source 区分——`source == AGENT_RUNTIME_SUPERVISOR_GAME_CHAT_SOURCE`(`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver.rs:109`)时取 1,其它 source(含 D11 的 `project-planning` 委派链)取 3;两个维度都是运行时沿 `repair_of_delegation_id` 链上推断的派生值,不新增 `StaticDelegateDeliveryRecord` 持久字段。
|
||||
|
||||
## 2. 已锁定决定 D1~D11
|
||||
|
||||
@@ -136,7 +129,6 @@ WP1 定稿的澄清轮次/返工深度语义(供 D11 依赖,权威定义见
|
||||
| D2 | 仅首页“做方案”新建项目进入“立项策划”;“做游戏”和“做素材”保持直接开建,等价于当前无 GDD 基线的完整构建路径。 |
|
||||
| D3 | 阶段、source、composition、工具、schema、审批命令和 UI 名称按第 3 节注册表冻结。 |
|
||||
| D4 | M1 使用 `.agent/planning/` sidecar,不改 `shared-contracts`;是否把 `approvedGddRef` 提升进 manifest 留给 M2,不能在 M1 临时决定。 |
|
||||
| D5 | game-chat 只在 M3 可选只读消费有效批准 GDD;没有批准 GDD 时继续走现役快车道。 |
|
||||
| ~~D6~~ | **2026-08-12 作废**,由 D9 取代。原文:“立项策划 Agent”是 Project Supervisor 通道的第三 persona,以持久 source 区分,复用 `standard` profile,不注册新的 agentCatalog 身份。作废理由见第 1.1 节;其中“复用 `standard` profile”这一结论方向被 D9 继承,但成立理由完全不同。 |
|
||||
| D7 | 本期不实现知识图谱;`basis`、知识 provider trait、composition 槽位可以预留,但 v1 数据必须为 `null`,空字段不渲染。 |
|
||||
| D8 | GDD 不含引擎字段;平台事实固定由 Runtime 注入,Agent 不得向用户提问或修改。 |
|
||||
@@ -153,7 +145,6 @@ WP1 定稿的澄清轮次/返工深度语义(供 D11 依赖,权威定义见
|
||||
| 策划 Agent 称呼 | `立项策划 Agent`(2026-08-12 起不再是 persona;2026-08-13 起也不再是「工作流节点」,改为 Supervisor 的静态委派子 Agent,见 D11) |
|
||||
| **策划节点 agentId** | `project-planning`(登记 agentCatalog;`project-` 前缀标明项目级、不属任何专业组,故不与 design 组的 `design-director` / `design-foundation` 混淆;登记机制定稿见第 3.1 节,本轮只冻结机制、代码留给 M1) |
|
||||
| **策划子 Agent durable source** | `agent-delegate`(**2026-08-13 按 D11 取代原值 `agent-ready-task-scheduler`**。字面量见 `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools/delegation.rs:1063`;不新增 source,复用现役静态委派族。该 source 同时是 `validate_user_input_action_owner` 拒绝直接提问的判据之一,见第 19 节第 2 条) |
|
||||
| **Supervisor 入口 durable source** | `project-supervisor-plan`(与 `-gui` / `-cli` / `-game-chat` 同族;2026-08-12 取代原预留值 `project-supervisor-plan-chat`,**旧字符串作废不得沿用**,避免字面未变而语义已改导致接错代码路径) |
|
||||
| Rust source 常量 | `AGENT_RUNTIME_SUPERVISOR_PLAN_SOURCE` |
|
||||
| run profile | `standard`(Supervisor 根 run 与策划子 Agent 必须同为此值。**2026-08-13 按 D11 更正成立理由**:不是 ready-task 调度的约定,而是委派通用的父子继承——`bind_game_creator_agent_runtime_run_profile_at` 强制子 Run 等于父 Run 已绑定的 profile,「子 Run 不能切换父 Run 的 Run Profile」) |
|
||||
| Prompt composition | **不新增**。策划子 Agent 复用现役 `runtime` composition(委派/孤立子 Agent 通用模板),Supervisor 入口沿用现役 supervisor composition。**2026-08-13 按 D11 取代原冻结值 `projectPlanning`**:`manifest.json` 的 `compositions` 只有 `runtime`/`supervisor`/`supervisorChat` 三个固定字段,校验不遍历 `agentCatalog`,新增子 Agent 不需要也不能配第四套(依据见第 3.1 节) |
|
||||
@@ -265,7 +256,7 @@ composition/brief 相关的强制要求:
|
||||
- **needs_change(2026-08-13 对抗性复核补记)**:`task_start.rs` 的 `collect_game_creator_agent_runtime_agent_ids`(`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/task_start.rs:3-28`)与 `game_creator_agent_role_definition` 是同构的二分硬编码——只显式插入 supervisor id(8 行),再无条件遍历 `GAME_CREATOR_AGENT_GROUP_DEFINITIONS` 插入全部 16 个组角色 task_id(19-23 行,不看当前是否有活跃任务),`project-planning` 既不是 supervisor、也不是组角色、也不是 `agent.spawn_isolated` 产生的动态孤立实例,天然不进入这个集合。此函数是核心 Runtime 推进/恢复驱动 `read_game_creator_agent_runtimes_at`(`entrypoints.rs:756`,被 `commands.rs`/`swarm_cli` 调用)与三处安全网的枚举来源:崩溃恢复扫描(`recovery_scan.rs:448`、`:687`)、root run 被 steer 时的级联取消(`steering.rs:800` 的 `cancel_goal_contract_root_descendants_at`)、委派回执兜底对账(`delivery.rs:1287` 的 `reconcile_game_creator_agent_delegate_receipts_at`,由 `recovery_scan.rs:1102` 触发)。经追踪 `agent.delegate` 派发路径(`delegation.rs` 里对 `start_game_creator_agent_background_task_with_link_at` 的调用),委派首轮任务是同步直接起跑的,不依赖这个集合,因此不属于「首轮即挂」的 blocking 类;但一旦应用重启、Supervisor 根 run 被 steer、或首轮结果的直接投递失败需要兜底对账,`project-planning` 的委派状态都不会被这三处安全网发现和处理,会静默变成孤儿任务,且与第 23.1 节「plan run 是否允许 steer」这条既有待裁决项直接相关(提供了其未验证交互的具体机制证据)。M1 需要给这个函数补一个与「group 角色无条件收录」对称的第三条分支;`runtime_adapter.rs` 里 `game_creator_runtime_agent_catalog_matches_the_existing_role_directory` 测试(同文件 91-121 行)断言 catalog 成员集合与 `{supervisor} ∪ 16 组角色` 精确相等,`project-planning` 登记后这条测试会立即失败,M1 需同步更新其期望集合,不能靠这条测试的失败倒逼才发现遗漏。
|
||||
- **benign(不阻塞,仅记录)**:前端 `projectProfessionalAgentLabel`(`apps/ai-game-creator-shell/src/features/agent-runtime/model.ts:1496-1529`)的关键字匹配落不到 `project-planning`,会退化成直接显示原始 `agentId`。纯展示层缺口,不影响功能,M1 顺手补一条分支即可。
|
||||
- 未来提醒(写入代码前必须核对,本轮不改):`pass_artifacts.rs` 的 `agent_role_memory_relative_path_for_task`(`apps/ai-game-creator-shell/src-tauri/src/agent/generation/pass_artifacts.rs:335-347`)也是「先特判 supervisor、再遍历 group」的同构硬编码,若不加第三条 `project-planning` 分支,运行时对它调用会落入 346 行的 `Err("未知 Agent 任务")`。
|
||||
- 排雷提示(供未来维护者,非本轮改动项):全仓库检索确认,当前没有任何生产代码枚举 runtime `AgentCatalog`(`.iter()` 零生产调用),前端「团队」清单(`agentPresentation.ts` 的 `groupConfigs`)与 `agent.route_manifest`(`delivery.rs`)都是硬编码字面量/精确字符串判断,结构上不会把 `project-planning` 带进「做游戏」团队清单或路由清单。但**未来如果有人写「遍历 AgentCatalog 生成 UI 团队卡片/prompt 团队成员清单/任何 route 白名单」这类代码,必须显式按 `groupId ∈ {design, balance, art, audio, code, publishing}` 六个真实组过滤,或显式排除 `project-planning`(和 `supervisor`)这两个组外单节点**——这也是坚持 `groupId` 必须自引用为 `"project-planning"`、不能复用 `"design"` 的根本原因。
|
||||
- 排雷提示(供未来维护者,非本轮改动项):全仓库检索确认,当前没有任何生产代码枚举 runtime `AgentCatalog`(`.iter()` 零生产调用),前端「团队」清单(`agentPresentation.ts` 的 `groupConfigs`)都是硬编码字面量/精确字符串判断,结构上不会把 `project-planning` 带进「做游戏」团队清单。但**未来如果有人写「遍历 AgentCatalog 生成 UI 团队卡片/prompt 团队成员清单/任何 route 白名单」这类代码,必须显式按 `groupId ∈ {design, balance, art, audio, code, publishing}` 六个真实组过滤,或显式排除 `project-planning`(和 `supervisor`)这两个组外单节点**——这也是坚持 `groupId` 必须自引用为 `"project-planning"`、不能复用 `"design"` 的根本原因。
|
||||
|
||||
**本轮范围声明**:以上登记机制与代码改动清单均属 **M1 实现范围**,本轮(`M0A-3` 文档工作包)只冻结机制、不落地任何代码——不改 `manifest.json`、不改 `runtime_prompt_bundle.rs`、不改 `runtime_adapter.rs`、不改任何 `.rs` 文件。理由:`project-planning` 目前没有 prompt、没有任何路径能调用它,现在就注册 catalog 而不同步处理上面的 blocking 项,等于给发布产物加死重(一个「看似已登记、实则一调用就硬失败」的 Agent 身份),注册代码应与 M1 的 prompt/source 一起落地。
|
||||
|
||||
@@ -277,7 +268,6 @@ flowchart TD
|
||||
subgraph SUP["Project Supervisor 顶层 root run(三个入口 source)"]
|
||||
SPLAN["做方案入口<br/>source=project-supervisor-plan<br/>profile=standard"]
|
||||
BUILD["完整构建 Supervisor<br/>source=project-supervisor-gui 或 project-supervisor-cli<br/>profile=autonomous-game-build"]
|
||||
CHAT["game-chat Supervisor<br/>source=project-supervisor-game-chat<br/>profile=autonomous-game-build"]
|
||||
end
|
||||
U <-->|"唯一对话对象;问答物理落 Supervisor 会话文件"| SPLAN
|
||||
SPLAN -->|"agent.delegate 静态委派(profile 由父 run 继承)"| PLANAGENT["立项策划子 Agent<br/>agentId=project-planning<br/>source=agent-delegate<br/>profile=standard<br/>composition=runtime(复用)"]
|
||||
@@ -318,7 +308,6 @@ flowchart TD
|
||||
|
||||
**「同一条策划链路」的判定不能只看子 run 的 `agentId`。** 委派子 run 的身份权威是 `(parentAgentId, parentRunId, delegationId)` 三元组加上 delivery 记录本身;多轮 continuation 每轮都是新的 `delegationId` 与新的 `targetRunId`,靠 `repair_of_delegation_id` 串成链。判定「这是不是当前策划链路的一环」必须沿该链上溯到根 delegation 并核对根 delegation 的 `parentRunId` 等于当前 plan 根 run,不得用「`agentId=project-planning` 即认为属于本链路」这种弱判据——否则跨 run 的旧策划残留会被误纳入当前轮。
|
||||
|
||||
M1 不能把新 source 直接塞进一个被 autonomous 语义复用的总 matcher。source predicate 必须拆成三种语义:top-level Supervisor trusted matcher 接受 gui/cli/game-chat/plan;autonomous-build trusted matcher仍只接受现役 gui/cli/game-chat;plan binding matcher只接受 top-level `project-supervisor + standard + project-supervisor-plan`。现有 run configuration、completion gate 和恢复调用点逐个改用正确 predicate,确保 `plan + autonomous-game-build` 永远非法。前端已有 `runProfile + source` 提交链只能作为请求;后端必须重新验证,不能信任页面选择。
|
||||
|
||||
2026-08-12 复核:上述三分法在 2026-08-11 动态目标验收图合入后**已不足**。原文把 plan 归入「top-level Supervisor trusted matcher」,而该 matcher(`agent_runtime_supervisor_source_is_trusted`)如今同时是 Goal Contract 创建权限、根控制面工具授权与验收图完成门的判据,plan 一进入即被当作 Goal Contract 参与者。至少需要第四种语义「Goal Contract 参与者」,且它与 top-level trusted 的关系必须显式冻结,不能靠默认相等。此外 Goal Contract 的入口门只按 `agentId=project-supervisor` + root binding 判定,与 source predicate 无关,因此拆 matcher 本身解决不了它。完整处置见第 23.1 节待裁决项;该裁决可能反过来影响本节已冻结的 `agentId=project-supervisor`(方案 D)。
|
||||
|
||||
@@ -337,7 +326,6 @@ M1 不能把新 source 直接塞进一个被 autonomous 语义复用的总 match
|
||||
1. **Supervisor 根 run** 沿用现役 supervisor composition。做方案入口不需要专用 persona 稿:它的 Provider 不生成策划内容,只做委派、认领回执、代为提问与审批收束;这些能力现役 supervisor composition 已经具备。差异化只体现在 Prompt 的任务描述与工具面上,不体现在 composition 选择上。
|
||||
2. **策划子 Agent** 复用现役 `runtime` composition(委派/孤立子 Agent 通用模板)。其角色专属内容由 agentCatalog 条目的 brief 承载,而不是由 composition 承载——这与所有专业 Agent 的组织方式一致,见第 3.1 节。
|
||||
3. 因此本方案**不新增 Prompt Bundle 的编译期 source kind**。原 `SourceKind::SupervisorPlanChat` 不再需要。
|
||||
4. 现有 role overlay 仍只服务 autonomous 路径。策划链路的两个 run 都不伪装成 game-chat overlay,也不注入知识图谱 overlay。
|
||||
5. 策划子 Agent 的每一轮 continuation 都是**新 run、同 session**,其 Provider 请求的历史来自该 session 的既有对话,不需要也不应该由 Prompt 层去拼接「前几轮问答」。需要显式传递的只有用户的**答案**——它物理落在 Supervisor 会话文件而非子 Agent 会话文件,只能由 Supervisor 写进新一轮委派的 task 文本;该转述的保真依赖 Supervisor 侧 Provider,Runtime 只校验 `questionsSha256` / `answersSha256` 的哈希绑定,不校验转述语义(残留风险,见第 1.1 节「D11 新拓扑」第 3 条)。
|
||||
|
||||
### 4.3 两层工具面与两项协议控制函数
|
||||
@@ -366,7 +354,7 @@ action 工具广告与执行双门都必须是 exact allowlist,MCP catalog 为
|
||||
|
||||
`update_agent_plan` 与 `respond_to_user` 是 Runtime 协议控制函数,不计入上述清单,但仍受现有结构、轮次和终态门禁约束。
|
||||
|
||||
明确禁止:通用写入、patch/delete、command、process、preview、canvas、asset generation、确认型副作用、`agent.delegate`、`agent.route_manifest`、isolated child、任务图调度和所有 MCP 工具。
|
||||
明确禁止:通用写入、patch/delete、command、process、preview、canvas、asset generation、确认型副作用、`agent.delegate`、isolated child、任务图调度和所有 MCP 工具。
|
||||
|
||||
`user.input_request` **不在允许清单内**。委派子 Agent 天然带 `parent_agent_id`/`parent_run_id`,该调用被执行层 `validate_user_input_action_owner`(`apps/ai-game-creator-shell/src-tauri/src/user_input.rs:367-394`)兜底拒绝;M1A-2 同时让它从 planning 的函数目录消失,避免模型浪费轮次。广告层过滤、Provider parser 原始身份校验、batch/pending/recovery 再验证和执行层兜底必须并存,不能只测其中一层。
|
||||
|
||||
@@ -1516,15 +1504,12 @@ type PlanningBaselineInput =
|
||||
|
||||
确定性收束与动态 Acceptance Graph 是两套证据体系,M2 不能混用。`design-director` 变成确定性 GDD 准入门后不再启动 LLM,因此**不产生任何 Provider 动作回执**;M0-3 的 Runtime 内部固定产物验证同样不产生 Provider 可见回执。而 Acceptance Graph 的 passed 节点必须引用当前根任务树中真实成功动作回执,`requiredEvidence` 只接受 `tool:<Runtime 工具名>` 且必须命中 Runtime 允许的持久证据工具集合(`agent_runtime_acceptance_evidence_tools()`,当前 18 项,既不含 Runtime 内部 owner 产物验证,也不含任何控制面或纯协调工具)。结论固定为:确定性 completed 投影与内部产物验证都不构成验收证据;涉及 GDD 落地的验收标准要么由根 Supervisor 用允许的证据工具自行取证,要么不写成 required 节点。不得为了让确定性节点“可验收”而把内部验证工具暴露成 Provider 可见工具——那会直接推翻 M0-3 已冻结的 owner 验证边界。
|
||||
|
||||
## 17. M3 game-chat 只读复用
|
||||
|
||||
game-chat 不强制先策划、不改变单主结构。项目存在有效 approved GDD 时,M3 可把 `title, oneLiner, coreLoop, mvpSystems 摘要, version, fingerprint` 作为只读上下文注入当前 `project-supervisor-game-chat` 根 run;没有时完全保持现状。
|
||||
|
||||
注入前仍从不可变 GDD/receipt 验证,不能读取 index 或 Markdown 当信任源。唯一 `code-prototype` 主 Agent、按需美术 child 与 `audit-existing-first` 执行安全策略不变;后续用户要求与 GDD 冲突时由 Supervisor 明示差异,不自动产生新批准版本。
|
||||
|
||||
2026-08-11 合入的动态目标验收图改变了本节的两条前提,M3 必须按新事实设计。
|
||||
|
||||
第一,game-chat 根 Supervisor 现在有强制前置动作。根 Run 尚无 Goal Contract 时,本轮唯一动作必须是 `agent.goal_contract`;冻结之后才轮到 `agent.route_manifest`。`intentSummary` 的语义随之改变——它不再概括用户原话,而必须忠实概括**已冻结的 Goal Contract**。因此 M3 的 GDD 只读上下文必须在 Goal Contract 冻结**之前**就对根 Supervisor 可见,否则冻结下来的目标看不到已批准策划,后续整轮都建立在缺失前提上。
|
||||
|
||||
第二,approved GDD 不得自动 seed Goal Contract。GDD 是一次历史批准事实,Goal Contract 是 Supervisor 对**当前这一轮用户意图**的理解;由 Runtime 用 GDD 字段直接物化合同,等于让旧策划静默冻结新一轮目标,并且绕过了「Agent 必须自行理解用户真正要做的事」这条约束。GDD 只能作为上下文进入理解过程,合同内容仍由 Supervisor 产出。
|
||||
|
||||
@@ -1682,18 +1667,12 @@ receipt 永远压过 stale pending:一旦该版本存在有效 receipt,pendi
|
||||
| 完整 16 任务 DAG | `code-prototype` | 对真实可玩入口执行 `game.static_smoke` | 代码原型写入与本人可玩静态自检 |
|
||||
| 完整 16 任务 DAG | `preview-readiness` | 以自己的 child run 对最终 project revision 执行 `game.static_smoke` | 正式最终静态验收 |
|
||||
| 完整 16 任务 DAG | `preview-playtest` | 独立执行 `preview.validate` | 正式浏览器试玩验收 |
|
||||
| game-chat 单主 | 根 `code-prototype` | source-bound 固定 smoke + desktop/mobile `preview.validate` | 对当前单主可玩 revision 负责 |
|
||||
| game-chat 动态美术 child | `art-director` / `art-asset-plan` | 只在 `assets/**` 范围交付,不得执行 command/preview | 只交付美术回执,无根最终验收权 |
|
||||
|
||||
四个固定 owner 的 canonical 路径分别是 `memory/project.md + game/game_design.md`、`game/balance.json`、`assets/manifest.art.json`、`assets/manifest.audio.json`。同一映射必须同时驱动写入边界、完成检查与内部验证;验证要求有界读取、非空、JSON 可解析、无 incomplete marker,并相对根完成合同 baseline 已变化。内部验证不新增 Provider 可见 tool / commandId,不写 `staticSmokeVerifiedRevision`,不产生 smoke / preview trace;错误 source、delegated run、错误或终态 root、错误 parent/binding、跨 Agent/run 和非当前活跃根全部失败关闭,再次 mutation 必须使旧凭证失效。本阶段明确不扩到后置 `publish-package`;配置 Key 时的 UI 原型、透明图集、Canvas 登记和视觉验收仍是附加必需证据,不能被固定文件验证替代。
|
||||
|
||||
Canvas 是条件外部能力,不是 M0-3 四个固定 owner 的通用前置:没有 Editor Key 时,固定 owner 仍按 canonical 文件由 Runtime 内部验证;有 Key 时,`art-director` 只获得 `canvas.asset_generate` 的规范图职责,Provider 广告与执行 policy 均拒绝 `project.verify`、`command.run_limited` 和 preview 工具。game-chat 临时 `art-asset-plan` 只有在当前根 `code-prototype -> agent-delegate`、durable delivery 与 Run Profile binding 全链一致时才可沿用 Canvas 路径,并且完成门只认本人 `canvas.asset_generate` 的通过凭证,不能借用 smoke 或 `project.verify`。完整 DAG 的 `code-prototype` 即使已经通过 `project.verify`,仍必须保留覆盖本人 `mutationRevision` 的 `staticSmokeVerifiedRevision`;后续 preview 更新 last verification tool 不删除这份 smoke 凭证。GUI/CLI 的试玩回执必须绑定确定性 `preview-playtest` child 的 agent/run/source/binding,game-chat 则继续绑定唯一主 `code-prototype`;上游代码节点、根 Supervisor 或旧 v1 回执均不能替代当前执行 owner,旧 v1 回执按缺失处理并要求重新试玩。
|
||||
|
||||
正式任务 M0-4 的 PR 工作包 `M0B-1` 还必须让 `agent-delegate` 与 `agent-delegate-retry` 共用严格动态美术 lineage predicate;当前 retry source 不能绕过 `assets/**`。该修复不属于本文档 PR 的功能实现,但在 `M0B-2` 收敛 game-chat 前端投影前必须完成。
|
||||
|
||||
2026-08-11 裁决进一步冻结:game-chat 动态美术 child 不允许使用通用 Agent Runtime retry。原 child 的 delivery 同时精确绑定父动作派生 delegationId 与 targetRunId;通用 retry 产生的新 run/new delegationId 没有合法 delivery,禁止通过换绑、续发、复制凭证或放宽 strict predicate 赋权。`retry_game_creator_agent_runtime_task_at` 必须在任何 successor durable 副作用前,以不要求 child 仍为 running 的结构身份识别该类终态 child,并返回稳定类型 `kind=game-chat-dynamic-art-retry-unsupported`,引导用户继续 game-chat 对话,由下一轮 main `code-prototype` 重新 `asset.list` 后按仍存在的缺口创建新的首次委派。委派去重以 parent run 为键;同一 main run 内每个缺口最多委派一次,终态失败或取消 delivery 不为同 run 开豁免,跨轮以新 parent run、新 delegationId、targetRunId 与 delivery 自然放行。遗留/伪造的 `agent-delegate-retry` 美术 run 只保留诊断性只读白名单,全部 mutation fail closed;现有 Tauri String error wire、其它 delegated retry、完整 DAG 和顶层 retry 不变。
|
||||
|
||||
2026-08-12 裁决补充:manifest 不是 game-chat 轮次身份的权威源。`GameCreationAppManifest` / `GameCreationAppTaskState` 在 TS 与 Rust 双侧都不含 run/root/agent 身份字段,且 manifest 是项目级单例文件并跨轮复用同一份,因此任何任务状态都无法从数据本身归属到具体轮次。轮次结论的权威事实只有 Runtime lineage(`agentId + sessionId + runId + source + parentAgentId + parentRunId`);manifest 只能作为 lineage 判定通过后的补充信号,不得单独裁定当前轮结论,也不得单独解锁阶段归档。阶段归档快照的全部写入点都必须校验被归档 root 仍是当前 root,终态会话同步中的异步捕获同样适用——该读取若在下一轮接管后才 resolve,会把掺入新轮活动的清单冻结成旧轮快照;跳过捕获不会饿死归档,因为开下一轮前的阻塞门在快照未冻结时直接失败要求重试。本阶段明确不为 manifest 或其投影新增 `statusRunId` / `statusSource` 等身份字段:补字段必须同时覆盖 `update_manifest_task_status_at` 与无秩序守卫的 `set_task_status` 两条写入路径,只改前者会让后者原样保留上一次写入的旧身份印记,制造“校验通过”的假象而比不校验更危险。
|
||||
|
||||
2026-08-12 记录一处尚未裁决的不变量冲突。本节第 2 条(plan source 的工具广告与执行双门只有四项)与 2026-08-11 合入的动态目标验收图存在结构性冲突。现行工具面是 deny-list 模型,可信 root Supervisor 默认持有 `agent.goal_contract`;而 plan source 按 exact allowlist 设计,不持有该工具。由此卡在两道独立的门:入口门 `validate_root_goal_contract_control_plan_at` 在通用 tool-plan 解析路径上强制「合同不存在时本轮必须是唯一的 `agent.goal_contract` 动作、且无 plan/plan_update/response」,判据**既不看 source 也不看 Run Profile**;出口门 `goal_contract_acceptance_completion_blocker_at_locked` 在 root project-supervisor + 可信 source 且合同不存在时返回 `blocked`,卡住完成、finalization 与恢复。同一批判据还决定 Goal Contract 的创建权限和 `agent.goal_contract` / `agent.acceptance_update` 是否被剥离。四个处置方案与代价见第 23.1 节的待裁决项;在裁决冻结前,本节第 2 条按「设计意图」保留,不得据此认为现行代码已经满足它。
|
||||
|
||||
@@ -1733,7 +1712,6 @@ Canvas 是条件外部能力,不是 M0-3 四个固定 owner 的通用前置:
|
||||
| Prompt | **2026-08-13 按 D11 改写**:不新增 composition,Supervisor 根 run 沿用现役 supervisor composition、策划子 Agent 复用 `runtime` composition(见第 4.2 节);`decision-checkpoint` 请求 kind 随 D10 作废(见第 5.1 节)。仍冻结:3 轮/单题/固定选项;回答后设计解释与 prototype item;平台事实;恢复摘要;direct-out 条件 |
|
||||
| frontend | 首页“做方案”目录提交与 Enter 自动创建均为 `standard + project-supervisor-plan`;“做游戏/做素材”均保持 `autonomous-game-build`;项目页新建/打开不首次注入 planning;stable approvalRequestId/responseId;busy;stale card;hydrate strict input/view;无目录空态;receipt 隐藏 stale pending;corrupt authority typed error;project open/reload/resume/submit/decision 刷新;recovery pending;批准并开建两命令顺序 |
|
||||
| M2 integration | explicit approved/direct mode;锁内重验 receipt;ref 贯穿 task/run/completion/context;无 ref 非回归;恢复不换稿 |
|
||||
| M3 integration | 有批准 GDD 的只读注入;无 GDD 零差异;不改变 game-chat 单主 lineage |
|
||||
|
||||
关键强杀点逐项覆盖:
|
||||
|
||||
@@ -1756,7 +1734,6 @@ M0 文档 PR 本身最低验证:Markdown 结构与三张 Mermaid 图可解析
|
||||
| 主题 | 当前证据 | M1/M2 要点 |
|
||||
| --- | --- | --- |
|
||||
| **`project-planning` 身份登记(已落地)** | `apps/ai-game-creator-shell/src-tauri/prompts/runtime/manifest.json`(`agentCatalog.planning`)、`build_support/runtime_prompt_bundle.rs`、`src/agent/runtime_adapter.rs`、`src/agent/prompt.rs`、`src/agent/generation/pass_artifacts.rs`、`src/agent/runtime_driver/task_start.rs`、`src/agent/runtime_tools/task_ops.rs`、`src/agent/runtime_tools/delegation.rs` | **2026-08-13 已合入**。登记为与 `supervisor` 平级、不进 `groups` 的独立条目,`build.rs`/种子 DAG/`new_game_creation_app_seed_tasks()` 一行未动。同批修掉「非 supervisor 即专业组成员」二分假设的四个受害点:角色身份合成(blocking,不修则委派第一轮即硬失败)、内存路径解析、恢复枚举漏收、`task.create` 静默兜底成 Design 组;并把 `project-planning` 排除出 `agent.spawn_isolated` 的合法模板集。回归见 `project_planning_is_a_delegatable_identity_outside_the_seed_dag` |
|
||||
| Supervisor trusted source | `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver.rs`(`AGENT_RUNTIME_SUPERVISOR_PLAN_SOURCE` + matcher) | **2026-08-13 `M1A-1` 已落地**:matcher 现为 gui/cli/game-chat/plan。`plan + autonomous-game-build` 由独立组合门拒绝(`kind=plan-autonomous-profile-unsupported`)。做方案链路正常参与 Goal Contract 协议(见第 23.1 节) |
|
||||
| trusted matcher 消费者 | 2026-08-12 复核为 10 个非测试文件、18 处调用:`commands.rs`(2)、`agent/runtime_actions/project_gates.rs`、`agent/runtime_protocol/acceptance_graph.rs`(2)、`agent/runtime_protocol/goal_contract.rs`(2)、`agent/runtime_protocol/run_configuration.rs`、`agent/runtime_protocol/steering.rs`、`agent/runtime_driver/lifecycle_control.rs`、`agent/runtime_driver/task_start.rs`(2)、`agent/runtime_actions/provider_request_builders.rs`、`agent/runtime_protocol/autonomous_completion.rs`(5) | 2026-08-10 记录的两个消费者已过期。`agent_runtime_supervisor_source_is_trusted` 现在同时是 run 启动门、steer 门、Goal Contract 创建权限、验收图完成门与根控制面工具授权的共同判据,**都不看 Run Profile**。M1 只拆 autonomous-only matcher 已不够。**2026-08-13 裁决:plan source 进该 matcher**;**`M1A-1` 已逐点复核并落地**:适用者保留 matcher、steer 独立否决(`kind=plan-root-steer-unsupported`)、autonomous 消费点已由 profile 挡住本包不改函数。复核表见 decision-log 2026-08-13 `M1A-1` 条。2026-08-13 复核调用数已增至 19 处,以当时源码为准 |
|
||||
| Run Profile | `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_adapter.rs:48-75`、`apps/ai-game-creator-shell/src-tauri/src/main.rs:1243-1244` | 复用 `standard`,不新增 profile |
|
||||
| Supervisor start 校验 | `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/task_start.rs`、`apps/ai-game-creator-shell/src-tauri/src/commands.rs` | **`M1A-1` 已落地**:plan 必须 `standard`;`plan + autonomous-game-build` 拒绝 |
|
||||
@@ -1783,14 +1760,10 @@ M0 文档 PR 本身最低验证:Markdown 结构与三张 Mermaid 图可解析
|
||||
| 16 任务 DAG | `server-rs/crates/shared-contracts/src/game_creation_app.rs:263-425` | 2026-08-12 复核 seed 仍是 16 个,M0/M1 不改拓扑;但固定 DAG 已不是完成语义的唯一来源,见下一行 |
|
||||
| standard 路径 owner 产物验证 | `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/autonomous_completion.rs:416-441` | 2026-08-12 复核:`autonomous_owner_artifact_validation_available_for_run_at` 四重绑死——owner agent 白名单、`profile == autonomous-game-build`、`source == agent-ready-task-scheduler`、**且要求 `parent_agent_id` 为 Project Supervisor**。standard ready-task 节点无 parent,第 436 行即不通过。做方案链路不能扩展该函数。**2026-08-13 按 D11 收窄结论**:策划 Agent 改为静态委派子 Agent 后,「产物是否交付」这件事已被静态委派内建的 `expectedArtifacts` 校验覆盖(存在性 + 非符号链接 + sha256),不需要再造一套;仍然缺的是**语义级**校验(JSON 可解析、非空、无 incomplete marker、相对 baseline 已变化),而 GDD 的内容正确性本就该由 `plan.submit_gdd` 的 strict schema 在落盘时把关,不由委派产物验证兜底。故本项范围收窄,不是整体另建 |
|
||||
| 问询与直投 | `apps/ai-game-creator-shell/src-tauri/src/user_input.rs:367-394,494-530,595-623,803-807`、`apps/ai-game-creator-shell/src/App.tsx` 的 `handleProjectSupervisorUserInput`、`apps/ai-game-creator-shell/src/project/conversation.rs:42` | 2026-08-12 复核:`validate_user_input_action_owner` 拒绝任何带 parent 的 run;会话文件按 `agentId` 分目录,消息归属完全由 pending owner 决定;一份 record 已经两路投影(会话消息 + observation)且有「observation 重算冲突」校验。直投只需让两路投影分别落到 Supervisor 与策划节点,**前端可直接复用现有 Supervisor 问答通道**。**2026-08-13 补记:本行「直投」是 D9/D10 旧机制记录,已被 D11 取代**(见第 1.1 节「D11 新拓扑」)——D11 不新造直投,改为复用 PR #165 已实现的 `AGC_NEEDS_USER_INPUT_V1` 终态信封 + Supervisor 中转链路;本行列出的 `validate_user_input_action_owner` 等机械证据本身仍成立,「前端复用现有问答通道」这一结论方向也不受影响,只是不再由「直投」这个已作废的机制名承载,本行未随批二重写,读者以第 1.1 节为准 |
|
||||
| Goal Contract / Acceptance Graph | `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/goal_contract.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/acceptance_graph.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/tool_policy_snapshot.rs`(`agent_runtime_acceptance_evidence_tools`)、`apps/ai-game-creator-shell/src-tauri/prompts/runtime/supervisor/game-chat-routing.md` | 2026-08-11 合入。可信根 Supervisor 必须先冻结 Goal Contract 才能路由,验收图未确认则完成门 blocked;合同按 `.agent/runtime/goal-contracts/{rootAgent}/{rootRun}.json` 分 root run 存放并绑定 binding fingerprint 与 source SHA-256。M1 的待裁决项已于 **2026-08-13 全部关闭**(见第 23.1 节:plan source 进可信 matcher;验收图取自固定 Fast GDD 合格标准;plan 根 run 不允许 steer;checkpoint handoff 随 D10 作废)。M2 见第 16.1/16.2 节,M3 见第 17 节 |
|
||||
| design-director 现状 | `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/autonomous_completion.rs:70-85`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/task_start.rs:1480-1506` | mutation owner 清单不含 design-director,因此当前落入只读协调 Prompt;M2 才确定性化 |
|
||||
| scheduler delivery | `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools/delivery.rs:171-185` | 下游不能依赖普通 durable delivery,必须读权威文件/ref |
|
||||
| owner 产物验证 | `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/autonomous_completion.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/project_gates.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools/file_ops.rs` | M0-3 / M0A-2 让四个 pre-code fixed owner 复用 canonical 路径映射,由 Runtime 内部验固定产物;Provider 不见验证工具,code / preview 节点继续真实 smoke |
|
||||
| approvedGddRef | 当前仓库无匹配实现 | M2 从 command 到 task/run/completion/context 全链新增 |
|
||||
| game-chat retry 边界 | `apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools/file_ops.rs:7-39,120-134`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/lifecycle_control.rs:740-772,885-905` | M0-4 / 工作包 M0B-1 统一 delegate/retry assets-only lineage |
|
||||
| game-chat 前端投影 | `apps/ai-game-creator-shell/src/features/agent-runtime/gameChatRuntimeProjection.ts`、`src/features/agent-runtime/model.ts`、`src/features/project-workspace/SupervisorChatOnlyView.tsx`、`src/App.tsx` | M0-4 / 工作包 M0B-2 只认 root → 单主 `code-prototype` → 动态美术 child 的 source-aware lineage;进度、final-reply、可玩 revision、retry 控件与阶段归档共用该身份边界 |
|
||||
| game-chat manifest 权威性 | `packages/shared/src/contracts/gameCreationApp.ts`、`server-rs/crates/shared-contracts/src/game_creation_app.rs`、`apps/ai-game-creator-shell/src-tauri/src/project/manifest.rs`、`apps/ai-game-creator-shell/src/features/agent-runtime/gameChatRuntimeProjection.ts` | manifest 双侧均无 run/root 身份字段且跨轮复用单例文件;只能作为 lineage 判定通过后的补充信号,不得单独裁定轮次结论或解锁归档。M1 的 `.agent/planning/**` 权威事实不得走 manifest,D4 关于 `approvedGddRef` 是否进 manifest 的 M2 决策需一并考虑此约束 |
|
||||
|
||||
## 23. 分期门禁与完成定义
|
||||
|
||||
@@ -1809,7 +1782,6 @@ M0A-1 是 M1 详细设计与技术 spike 的输入,不是功能交付。M1 可
|
||||
|
||||
2026-08-12 新增第二项 M1 合入前置决策:**plan source 与 Goal Contract 协议的关系**。(**2026-08-13 已裁决关闭**:`project-supervisor-plan` 进可信 matcher、正常参与 Goal Contract 协议,原阻塞理由随 D11 拓扑失效;详见本节下方「仍然保留的 M1 入口前置决策」中该条。以下段落保留作推导记录。)
|
||||
|
||||
冲突的根源不是某处判据写错,而是两套工具模型不兼容。现行是 **deny-list 模型**:`agent_runtime_tool_policy_snapshot_at` 的 `allowed_tools` 直接等于全量 `agent_runtime_executable_tools()`,`agent.goal_contract` 天然在内,`standard` profile 在 `agent_runtime_tool_policy_snapshot_for_run_at` 里更是提前返回、不做任何裁剪;`provider_request_builders.rs` 只对 `!root_control_authority && goal_contract_participant` 的后代做剔除。因此现役可信 root Supervisor(gui / cli / game-chat)**默认就持有**这个工具,两道门对它们是「照着做」。而 M1 是第一个 **allow-list 模型**的 source(第 4.3 节 exact allowlist),Goal Contract 协议隐含的「root Supervisor 一定持有 `agent.goal_contract`」前提对它不成立。
|
||||
|
||||
具体卡在两道**互相独立**的门,判据不同,必须分别处置:
|
||||
|
||||
@@ -1825,7 +1797,6 @@ M0A-1 是 M1 详细设计与技术 spike 的输入,不是功能交付。M1 可
|
||||
| C. plan 接纳 Goal Contract 协议 | 把 `agent.goal_contract` 纳入 plan 工具面(等价于放弃 allow-list、改用现行 deny-list 模型) | **只解除入口门,出口门在验收阶段照卡,且更难救。**`validate_goal_contract_acceptance_graph` 强制合同至少一个验收节点、至少一个 `required` 节点、每个 required 节点至少一项 `requiredEvidence`,且 evidence 必须命中 `agent_runtime_acceptance_evidence_tools()` 的 18 项;出口门再要求每个 required 节点在当前 project revision 下有真实成功动作回执。这 18 项全是项目读写/命令/预览/生成类工具,策划 Agent 按第 1 节目标 2 一项都不该有,`.agent/planning/**` 又由 Runtime 写、不产生 Agent 回执,因此合同必然带一个永不 `passed` 的节点。要救须把 plan 工具加进 evidence 集合并追加 `agent.acceptance_update`(独占一轮,与第 12 节 submit sole-action 和第 13 节决策卡流程冲突),且上游已明令禁止「用无关成功动作自证」。此外与第 4.3 节 exact allowlist、第 19 节第 2 条、第 24 节「plan source 无……」直接冲突,GDD 与 Goal Contract 语义大面积重叠。**判定为不可行,保留在表内仅作已排除记录** |
|
||||
| D. plan root 改用独立 `agentId` | 不再复用 `project-supervisor` | 入口门、创建权限与出口门三处**同时**自动不适用(三者都要求 `agent_id == project-supervisor`),是唯一一次性解耦的方案;但直接推翻第 4.1 节已冻结的 `agentId=project-supervisor`,牵动顶层通道假设、前端 hydrate、run lineage 与「每项目最多一个 active plan run」的判定口径,须先重开第 4.1 节 |
|
||||
|
||||
「改用 deny-list」不是独立的第五方案。deny-list 的作用只是让 plan 默认持有 `agent.goal_contract`,即方案 C,代价见上;而且它在本场景还额外不成立——`agent_runtime_effective_tool_policy_at` 按 `agent_id` 取策略,plan run 与完整构建、game-chat Supervisor 共用 `project-supervisor` 这一个 `agent_id`,per-agent deny-list 区分不了它们,仍须写 source-aware 门。deny-list 与 allow-list 的实质差别只剩失败方向:往 `agent_runtime_executable_tools()` 增加工具时,deny-list 让策划 Agent 静默获得新能力(2026-08-11 的 `agent.goal_contract` / `agent.acceptance_update` 正是这样进入全部现役 Agent 的),allow-list 默认不获得。对一个以「没有构建能力」为安全前提的 source,只能取后者。
|
||||
|
||||
因此真正的分岔不是 allow-list 与 deny-list,而是**策划 run 是否应当是一个 root `project-supervisor` run**:三处判据的唯一共同项是 `agent_id == GAME_CREATOR_PROJECT_SUPERVISOR_AGENT_ID`,方案 D 一次性解耦全部三处且不需要在他人协议里挖豁免,方案 B 需要四处豁免并随消费者增加持续维护。
|
||||
|
||||
@@ -1871,7 +1842,6 @@ D9 之后,root 是未变的 Project Supervisor,它在 `standard` 下天然
|
||||
|
||||
*产品侧替代路径*:用户中途要改方向,走既有的两条——本轮问询里回答/自由填写来纠偏;或在 GDD 审批卡上 `revise` / `reject`。都不行时放弃本轮、重开一条 plan lineage(第 4.1 节的 `PLAN_ACTIVE_RUN_EXISTS` 约束保证同一时刻只有一条非终态 lineage)。
|
||||
|
||||
*连带收益*:本裁决同时消解了原条目里「父 Supervisor 被 steer 时下游委派子 Agent 如何收束」这个问题——plan 根 run 不可被 steer,该场景不存在。game-chat 路径的同类问题不受影响,仍按 decision-log 2026-08-11 条的既有结论处理。
|
||||
- ~~**`project-planning` 的编译期 agentCatalog 登记方式与 `build.rs` 一致性校验**~~——**2026-08-13 机制与 M1A 基础代码已落地**(见第 3.1 节):`project-planning` 在 `agentCatalog` 下登记为与 `supervisor` 平级、不进 `groups` 数组的独立条目,`specialist_nodes` 只读 `manifest.agent_catalog.groups[].roles[]`(`build_support/runtime_prompt_bundle.rs:387-398`),因此 `build.rs` 的 `validate_seed_task_catalog`(`apps/ai-game-creator-shell/src-tauri/build.rs:23-46`)、16 任务种子 DAG、`new_game_creation_app_seed_tasks()` 均不需要改动。Prompt Bundle 已登记并注入 planning role brief,`prompt.rs` 已补齐 `project-planning` 角色 overlay;本段只代表身份/brief 基础可执行,不代表 `plan.submit_gdd` 或 GDD 存储/审批闭环已完成。
|
||||
|
||||
### 23.2 M0-3:统一 owner 产物验证与可玩验收边界(PR 工作包 `M0A-2`)
|
||||
@@ -1880,9 +1850,7 @@ D9 之后,root 是未变的 Project Supervisor,它在 `standard` 下天然
|
||||
|
||||
### 23.3 M0-4(PR 工作包 `M0B-1` / `M0B-2`)
|
||||
|
||||
`M0B-1` 先封闭 game-chat 动态美术 delegate/retry 的安全边界:首次 `agent-delegate` 继续按严格 delivery/route/Canvas lineage 只写 `assets/**`;该类 child 的通用 retry 在入队前返回 `kind=game-chat-dynamic-art-retry-unsupported`,遗留或伪造的 `agent-delegate-retry` 只读且全部 mutation 失败关闭。恢复只走跨轮:用户继续 game-chat 对话,由下一轮 main `code-prototype` 重新审计并按仍存在的缺口创建新的首次委派;同一 main run 对同一 target 的第二次委派继续拒绝,新一轮以新 parent run、新 delegationId、targetRunId 与 delivery 全链恢复。`M0B-2` 再以 source-aware lineage 修复单主进度、最终回复、可玩 revision 与归档投影。M0-4 不阻塞 M1 策划闭环开工,但阻塞 M3 game-chat 接入和“M0 全部完成”。M0-1~M0-4 全部合入并通过各自门禁后,才能标记“M0 全部完成”。
|
||||
|
||||
2026-08-11 的 M0B-2 落地固定为 presentation-only:新增纯投影模块,结构身份严格限定为 `project-supervisor-game-chat` root → `agent-ready-task-scheduler` 的唯一 `code-prototype` main → 该 main 下 `agent-delegate | agent-delegate-retry` 的 `art-director | art-asset-plan`;retry source 只作遗留诊断展示,不恢复通用 retry 控件。game-chat 进度只显示主阶段 `0/1`、`1/1`、失败或待核对;final-reply 除角色 allowlist 外还必须匹配精确 run 谱系;可玩 revision 只由当前 main 成功 smoke 后的结构化双视口试玩通过建立,同 revision 后续失败优先;阶段记录须等待 root、main、动态 child 和 manifest 主任务终态且无 reconciliation,并使用 root-scoped Runtime 快照与稳定 root-run message ID 幂等归档。该工作包不修改后端 DTO/schema/delivery/route,不迁移历史 manifest,也不实现 M1~M3。
|
||||
|
||||
2026-08-12 收敛 M0B-2 遗留的唯一挂起项——manifest 无 root/run 绑定,无法安全判定跨轮残留状态的归属。处置为三项:确立“manifest 非轮次身份权威源”的不变量(见 §19);补齐阶段归档中终态会话同步异步捕获缺失的 root 身份校验,使四处快照写入点身份口径一致;以回归钉住“当前 main 未终态时 manifest 不参与裁定”这条既有但零覆盖的边界。明确保留并记录的残余风险是:当前 main 到达 Runtime 终态且非 failed/cancelled 后 manifest 被逐字采信,若本轮 `manifestInvalidated` 尚未落地,跨轮残留的 failed 仍可能被显示为本轮结论;该窗口实际宽度未量化,三条候选机制(时间戳新鲜度门控、root-scoped 永久缓存、manifest 补身份字段)经审查均不可安全落地——分别因跨端时间戳单位错配导致门控恒真、缓存语义与后端“每次重新校验”哲学相悖、以及漏掉第二条 status 写入路径——故本阶段只记录不实现。回归用例中该残余风险的断言即裁决锚点,改动它意味着重新裁决。重新裁决触发条件见 decision-log 2026-08-12 条。该挂起项至此已处置,不再阻塞 M0-4 收口。
|
||||
|
||||
@@ -1914,7 +1882,6 @@ M0 完成不表示完整策划闭环已经上线。`M1A-1`~`M1A-4`、`M1B-1`
|
||||
|
||||
- 分类判据(唯一权威):`parent.structured_result.contract_status == NeedsUserInput` ⟺ 该跳是澄清 continuation;否则是质量返工。
|
||||
- 传播:根节点 `(0, 0)`;澄清跳 `round += 1` 且 **`depth` 不变**;返工跳 `depth += 1` 且 **`round` 重置为 0**。
|
||||
- 上限:`repair_depth` 维持 1 不放松;`clarification_round` 按 source 区分,game-chat source 取 1、其它 source(含 `project-planning` 委派链)取 3。
|
||||
- 单链总跳数上界 `1 + 2 × 3 = 7` 跳、8 条 delivery 记录。**注意是 7 不是 6**——连接两层的返工跳本身也算一跳。
|
||||
|
||||
**为什么不加持久字段**:给 `StaticDelegateDeliveryRecord` 新增 `repair_depth` 并用 `#[serde(default)]` 兜底,会让磁盘上已有的返工记录读出 `0`,深度门失效,「返工的返工」漏洞原样复活——方向是 fail-open,不可接受。链上推断对历史记录是**精确**而非仅保守:PR #165 之前不存在 `NeedsUserInput`,旧记录天然被正确分类为「非澄清」。
|
||||
@@ -2031,7 +1998,6 @@ M0 完成不表示完整策划闭环已经上线。`M1A-1`~`M1A-4`、`M1B-1`
|
||||
| `M1C-0` | 新增 `StaticDelegateContractStatus::UserRevisionRequested` 与分类分支 | `M1A-1` | **已落地**:无审批写入方、是惰性路径;用户修订跳不增 `repair_depth` 也不重置 `clarification_round`,连续修订可通过;做游戏链路返工仍在 `depth=1` 被拒;原有三种状态与 `UserRevisionRequested` 的已知行为保持不变,未知 durable status 的前向兼容由已完成的 `M1C-0b` 显式承接,不在本包静默降级或改变 |
|
||||
| `M1C-0b` | 静态委派 durable enum 的前向兼容粒度:未知 `contract_status` 解析为显式 `Unknown` 并最大化阻塞 | `M1C-0` | **已完成**:纯读路径、无写入方、审批状态、pending、receipt 或 UI(不含 `M1C-1`)。四种已知 durable 值保持原 serde;未知字符串解析为 `Unknown(raw)`,非字符串仍拒绝,`Serialize` 及读-改-写均原样保留 raw。`Unknown` 计入 completion barrier 与 waiting blocker,返工入口无条件拒绝(含 `depth=0`),lineage 按“其它”最保守分类(`depth + 1`、`round = 0`);planning Provider、自治 liveness、终态扫描等既有读路径同步 fail closed。截断、非法 JSON、非 UTF-8、超过 128 KiB 的 sidecar 仍按整目录 fail closed,不做单条跳过。**不新增或改变 `M1B-*` 功能依赖(仅复核其既有读路径);不包含 `M1C-1` 的审批写入、receipt、UI 或构建准入** |
|
||||
| `M1C-1` | `gdd-approval` pending、审批命令、receipt;receipt 写入上述 status 与 plan 根完成门 | `M1B-2`、`M1C-0`(前向兼容粒度另见 `M1C-0b`) | **已落地并合入**:三动作幂等、版本/指纹竞态防护、receipt 后 index/Markdown/audit/terminal observation/session 投影与恢复、generic v5/v4 anchor 精确消费、terminal summary 完整性校验,以及仅作用于 exact plan 根的只读 completion blocker;生产 acceptance-gate pending caller 与验收前置取证门按拆包纪律由 `M1C-2a` 承接。审批 UI / 澄清中转 / 构建准入仍未完成。连续修订 barrier 与 `UserRevisionRequested` 规则按第 23.7 节执行 |
|
||||
| `M1C-2a` | Goal Contract 接线:turn 1 冻结、固定验收图、审批前置门取证 | `M1C-1`、`M1A-3` | **当前隔离 worktree 已完成并通过本包门禁,尚未合回**:turn 1 的 request-scoped schema 与格式修复都只允许一个固定 `agent.goal_contract`;按项目变化的四项之外,`preferences=[]`、唯一验收节点及证据工具均冻结。Fast GDD evidence 只接受当前 Supervisor 根 run 对 `game/fast_gdd.md` 从第 1 行到 EOF 的同 hash 完整分页;无/旧证据先继续读取,显式 failed 才给原 delivery 的 `repairOfDelegationId`,passed 且 delivery 已认领才建 pending。pending/recovery/completion/finalization 均按同 identity 幂等,审批后 Markdown 改写不损坏 Graph。格式、Provider 强判据、M1C-2a、Acceptance Graph、planning submit/approval、finalization、all-targets、编码与 diff 门禁均通过;扩展 autonomous completion 整组的无关 game-chat 并行超时及精确复跑结果见 decision-log 同日条,不改该路径。不包含 `M1C-2b`、UI 或构建准入 |
|
||||
| `M1C-2b` | 澄清中转接线、轮次派生、预算注入 | `M1C-2a` | **实现与本包门禁已完成并已快进合回 `feat/five_min_design`**:首 child 的 revision 1 session、`NeedsUserInput → awaiting_user_input`、回答绑定后 continuation 的确定性 session 投影、审批后 `revise/reject` 用户修订谱系及 Provider 活跃时间 usage fact/fold 已接线;末次 `plan.submit_gdd` usage 在 receipt/session successor 落盘且 standalone/v4 anchors 精确消费后于同一项目锁内折叠,真实 receipt 回归证明累计值恰好推进一次,重复审批与 recovery reconcile 不二次推进。`planning_clarification_*` **13 passed / 0 failed**(M1C-2c 语义回归另见本包),另有 static deliveries 44、planning storage 13、planning submit 53、Provider usage 4、末次 usage receipt 1、barrier detail 3 条定向回归通过;格式、offline all-targets、编码与 diff 门禁通过。锁序承诺只适用于 **M1C-2b 新增的 planning 澄清写投影路径**;`main_loop` 既有通用 completion blocker 的 execution→project 路径不在本包。第 4 轮信封在正常路径不可达:`agent.delegate` 已在工具边界按血缘上限硬拒并返回 failed observation;coordinator 的超三轮 reconciliation 仅用于损坏血缘纵深防御。审批 UI、hydrate、构建准入和下游完整构建不在本包范围 |
|
||||
| `M1C-2c` | 决策卡 A/B 语义(第 23.9 节,2026-08-18 实现完成并合回):选项 → 台账映射改为 A/B 均 `confirmed/user_option`、信封 label 形状校验、planning role brief 与 Supervisor playbook/final-reply 文案(B 必须是真实岔路、第 3 项恒定且 description 须给出可执行验证方式、改口转述规则、提问纪律) | `M1C-2b` | **实现与门禁完成,已由 `6e4bd9703` 合回 `feat/five_min_design`**:Runtime 已实现 A/B/固定第三项校验、B 不再生成 `default_pending`、`answerSummary` 逐字保真;非法 C/缺项 fail-closed,A/B/自由填写回归已通过。`planning_clarification_*` 13、`project_planning` prompt 5、`planning_submit` 定向回归、prompt bundle、格式、编码、diff、offline all-targets 均通过;不含 M1D-1 前端、hydrate、构建准入或下游完整构建 |
|
||||
| `M1D-1` | 前端 hydrate 与 GDD 审批卡;决策卡按第 23.9 节实现(label 动态渲染、默认焦点 A、Other 槽不变) | `M1C-2b` | **已完成并合入 `feat/five_min_design`(落地 `0052a80da`,其后 ESLint 修正 `5b11a0530`)**:新增严格 `{projectPath}` hydrate command、`plan-gdd-state-view.v1` Rust read model、审批卡与独立 GDD 正文详情弹层;页面只消费 hydrate,决定 responseId 按审批请求/动作复用,`recoveryPending` 仅提供恢复重试;审批前置 pending 与错绑 session 继续 fail-closed。 |
|
||||
|
||||
@@ -54,11 +54,11 @@ npm run dev:api-server
|
||||
npm run dev:bgfilter-worker
|
||||
```
|
||||
|
||||
Linux 本机多用户并发开发时,`npm run dev`、`npm run dev:*` 单模块命令和 `npm run agc` / `npm run agc:game-chat` 会先在系统级端口段注册表里给当前用户分配一个端口段,再把该段映射为 `web = start`、`api = start + 1`、`spacetime = start + 2`、`admin-web = start + 3`、`bgfilter-worker = start + 4`、`agc-vite = start + 5`。默认注册表目录是 `/var/tmp/genarrative-dev-port-ranges/`,其中 `registry.json` 记录各用户的活跃段,`registry.lock` 负责串行化分配;可以用 `GENARRATIVE_DEV_PORT_RANGE_REGISTRY_DIR` 覆盖目录。系统自动分配时从 `10000-10099` 开始,每次占用 100 个端口块,后续块按 `10100-10199`、`10200-10299` 递增;同用户已有 worktree 占用首选 AGC 槽位时,AGC 只在本用户段内继续漂移。`GENARRATIVE_DEV_PORT_RANGE` 或 `--port-range` 只在 Linux 上生效,Windows 仍按原来的 3000 / 8082 / 3101 / 3102 / 8083 与 AGC 兼容优先端口 3080 统一探测并漂移,不读这个系统级注册表。父 API 与 worker 始终使用解析后的实际 `GENARRATIVE_BGFILTER_WORKER_BASE_URL`,不能写死 `8083`。
|
||||
Linux 本机多用户并发开发时,`npm run dev`、`npm run dev:*` 单模块命令和 `npm run agc` 会先在系统级端口段注册表里给当前用户分配一个端口段,再把该段映射为 `web = start`、`api = start + 1`、`spacetime = start + 2`、`admin-web = start + 3`、`bgfilter-worker = start + 4`、`agc-vite = start + 5`。默认注册表目录是 `/var/tmp/genarrative-dev-port-ranges/`,其中 `registry.json` 记录各用户的活跃段,`registry.lock` 负责串行化分配;可以用 `GENARRATIVE_DEV_PORT_RANGE_REGISTRY_DIR` 覆盖目录。系统自动分配时从 `10000-10099` 开始,每次占用 100 个端口块,后续块按 `10100-10199`、`10200-10299` 递增;同用户已有 worktree 占用首选 AGC 槽位时,AGC 只在本用户段内继续漂移。`GENARRATIVE_DEV_PORT_RANGE` 或 `--port-range` 只在 Linux 上生效,Windows 仍按原来的 3000 / 8082 / 3101 / 3102 / 8083 与 AGC 兼容优先端口 3080 统一探测并漂移,不读这个系统级注册表。父 API 与 worker 始终使用解析后的实际 `GENARRATIVE_BGFILTER_WORKER_BASE_URL`,不能写死 `8083`。
|
||||
|
||||
后端日志默认写入 `logs/api-server/`,独立 BgFilter worker 日志默认写入 `logs/bgfilter-worker/`。后端 API smoke 使用 `npm run dev:api-server`,先检查 BgFilter worker `/readyz`,再检查 API `/healthz`;需要确认 API 实例可接生产流量时检查 API `/readyz`。不要使用旧 `api-server:maincloud` 或任何 `GENARRATIVE_SPACETIME_MAINCLOUD_*` 口径。
|
||||
|
||||
AI 游戏创作客户端使用 `npm run agc`,开发态 game-chat 使用 `npm run agc:game-chat`。两个入口都先由 `apps/ai-game-creator-shell/scripts/start-tauri-dev.mjs` 解析 AGC Vite 实际端口:Linux 默认取当前用户端口段的 `start + 5`,占用时只在本用户段内漂移;Windows / macOS 保留 `3080` 为兼容首选并允许统一漂移。最终端口通过 `GENARRATIVE_AGC_VITE_PORT` 传给 `beforeDevCommand` 和配套后端端口解析器,通过 Tauri CLI 动态 `build.devUrl` 配置传给 WebView,并通过 Vite CLI `--port` 启动严格监听;Vite 继续使用 `strictPort`,任何一层都不得自行改到另一个端口。启动器在创建原生窗口前预检最终地址;若竞态中该地址被 AGC Vite、无响应监听器或其它服务占用,一律失败关闭,不复用、也不擅自终止无法证明归属的进程。
|
||||
AI 游戏创作客户端使用 `npm run agc`。该入口由 `apps/ai-game-creator-shell/scripts/start-tauri-dev.mjs` 解析 AGC Vite 实际端口:Linux 默认取当前用户端口段的 `start + 5`,占用时只在本用户段内漂移;Windows / macOS 保留 `3080` 为兼容首选并允许统一漂移。最终端口通过 `GENARRATIVE_AGC_VITE_PORT` 传给 `beforeDevCommand` 和配套后端端口解析器,通过 Tauri CLI 动态 `build.devUrl` 配置传给 WebView,并通过 Vite CLI `--port` 启动严格监听;Vite 继续使用 `strictPort`,任何一层都不得自行改到另一个端口。启动器在创建原生窗口前预检最终地址;若竞态中该地址被 AGC Vite、无响应监听器或其它服务占用,一律失败关闭,不复用、也不擅自终止无法证明归属的进程。
|
||||
|
||||
Tauri `beforeDevCommand` 默认与客户端构建并行,不能把上述检查只放在 `beforeDevCommand` 内:选定地址上若已有旧 Vite,Tauri 可能先创建加载旧前端的窗口,随后配套后端才因代理不匹配退出。外层启动器会把 Tauri CLI 放入受控进程树;CLI 正常退出、启动失败或收到终止信号后,POSIX 先向保留的 PGID 发送 `SIGTERM`、有界等待后升级 `SIGKILL`,Windows 使用 `taskkill /PID <pid> /T /F`。Linux 容器中的孤儿后代退出后可能暂时保留为 zombie,`kill(-PGID, 0)` 仍会返回成功;启动器必须结合 `/proc/<pid>/stat` 判断同组是否还存在非 zombie 成员,不能把等待 PID 1 回收误报为清理失败。配套后端和 Vite 仍由 `start-dev-stack.mjs` 各自持有,退出时同样有界收束,避免只剩客户端、Runner、Cargo 或旧订阅进程。排障时同时核对控制台输出的 AGC Vite 实际地址及其 marker、`.app/dev-stack.json` 的实际 API URL 和进程 cwd;不要把“终端已返回”当成客户端及其 Runner 已退出的证据。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user