合并远端主分支并融合角色动作契约

合并游戏创作条件任务图路由与恢复逻辑
保留正式角色动作序列契约并融合逐帧稳定引用
移除 frameIndex 缺失式断言并保留正向契约验证
修正后台动作预览测试中的过期签名地址
合并画布素材导出分片读取修复
This commit is contained in:
2026-08-06 13:19:00 +08:00
40 changed files with 2314 additions and 232 deletions
@@ -67,19 +67,35 @@
---
## 2026-08-06 game-chat 固定规则只提供上下文,Supervisor 决定条件 Graph
- 背景:用户要求把已有美术接入当前俄罗斯方块时,Runtime 在 Supervisor 首次 Provider turn 之前按关键词重置 Graph、选择是否复用美术并自动调度 child;Supervisor 没有固定快车道计划时又直接 `fixed-task-graph-stalled`。结果是模型没有理解和决策机会,`art-asset-plan` 在已有资产与 baseline 门互相冲突时重复空规划直至耗尽预算。
- 决策:关键词、否定/重做信号、占位状态和当前资产探测统一降级为 `advisoryOnly=true` 上下文。game-chat 根 Run 在持久 `GameChatWorkflowDecision` 前禁止启动任何 manifest child,并允许 Supervisor 正常请求 Provider;Supervisor 通过 auto-safe `agent.route_manifest` 选择 `audit-existing-first` 或 `regenerate-art`。审计路线首波只启动 `design-director + code-director`;已登记但无效的旧派生视觉不得在这两项审计启动前截断 scheduler。code-director 必须先成功 `asset.list`,并在 Provider 请求中读取 Supervisor 已持久化且经校验的 `authoritative=true` 决策,再提交绑定当前 root/completion contract/revision 的覆盖合同与 `use-existing-art / generate-missing-art / regenerate-art` 路由。Runtime 只校验身份、正式资产、Canvas、私有合同、切片、manifest、缺口和 fingerprint,并执行条件分支,不从关键词替 Supervisor 作决定。
- 资产边界:首版缺口槽位固定为 `art-spec` 与原子 `core-spritesheet`。art spec 缺失若使图集的引用/Canvas 合同同时失效,则两个槽位都是真实缺口;仅图集缺失时复用 art spec,只运行 `art-asset-plan`。完整覆盖零生成;显式重做只授权当前 root 下两个正式 owner 原位替换。已登记但校验失败的固定资产按真实缺口交回其 canonical owner,并只在持久路由绑定当前 root 时授权原位替换。art manifest baseline 豁免只读取持久路由,不重新运行关键词分类。
- 连续性边界:正式 failed continuation 继续继承原完成合同;普通美术措辞不再按关键词跨历史根 Run 借用具体试玩类型,避免新项目误继承旧 `tetris-v1`。code-prototype 仍须先读取并最小 patch 非占位入口、可见使用四类切片,再经过静态检查和试玩门禁。
- 恢复与权限:`agent.route_manifest` 在共享 Rust/TypeScript 命令目录中为 `auto`,否则 autonomous profile 会因不能等待人工确认而拒绝唯一决策动作;仅根 Supervisor 和其 code-director 审计 child 可执行,隔离 Agent 与其它角色拒绝。执行中断只允许按 durable pending identity 幂等恢复,同 Run 已持久决策/路由禁止改写。
- 验证方式:覆盖决策前零 child、用户原句只产生 hint、旧无效派生视觉不阻断首波、首波只有设计/程序审计、code-director 收到真实持久策略、完整复用、仅缺图集、无效已登记资产由 owner 原位替换、重做两个 owner、baseline 豁免只认持久 route、code-director 的 asset.list/coverage/route 完成门、自动权限,以及旧 root/错误 binding/fingerprint/缺口/重复 route 失败关闭。
- 关联文档:`docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`、`docs/project-memory/shared-memory/development-workflow.md`、`docs/project-memory/shared-memory/pitfalls.md`。
---
## 2026-08-05 game-chat 当前 ready child 对 manifest Pending 漂移保持活性
> 本条只保留 ready child 的 Pending 漂移处理;历史试玩类型继承与旧三 Director 首波验收已由 `2026-08-06 game-chat 固定规则只提供上下文,Supervisor 决定条件 Graph` 取代。
- 背景:ready scheduler 已为当前根 Run 持久化并启动 `code-prototype`,但并发 hydration 持有的旧 manifest 快照随后把该节点从 running 覆盖回 pending。父 Run 只读取 manifest 时会在 child 仍运行的情况下误判固定 Graph 已停滞并先行失败;child 完成门又因 pending 连续拒绝真实交付,最终耗尽 loop。
- 决策:父 Supervisor 的“是否调度新节点”和“是否等待已存在 child”必须分开。派生视觉需要父规划修复时可以暂停新调度,但只要当前最新且仍活跃的根 Run 下存在确定性 runId、正确父绑定且 durable journal 非终态的 ready child,父 Run 必须保持 `waiting-for-manifest-tasks`。game-chat child 仅在同一当前根 Run、确定性 runId、可信 scheduler source、正确父绑定、journal 仍为 queued/running 且不处于确认、用户输入或 reconciliation 时,容忍 manifest 的 pending 漂移并继续走全部产物、静态检查和试玩门禁。
- 失败关闭:GUI/CLI、旧父 Run child、终态 child、错误/伪造绑定、非确定性 runId、WaitingForConfirmation、WaitingForUserInput 和 needs-reconciliation 都不得借用该容忍;创建更新的根 Run 后,旧 child 立即失去父 DAG 活性与 pending 完成资格。
- 玩法连续性:既有美术增量任务可跨可信 Supervisor 入口回溯同 Session 的最近具体试玩场景;只跳过纯继续和既有美术接入语义,遇到更新的详细 Generic 新目标立即停止,避免从更老项目错误借用 `tetris-v1`。
- 验证方式:覆盖当前 game-chat child 的 running -> manifest pending 漂移仍保持 DAG 活跃并可完成投影;更新根 Run 后旧 child 被拒绝;派生视觉需要修复但已有 child 活跃时父 Run仍持久化等待;GUI child 继续拒绝 pending;GUI 创建俄罗斯方块后从 game-chat 接入既有美术仍使用 `tetris-v1`。
- 玩法连续性:普通美术措辞不再触发历史玩法类型回溯;只有正式 failed continuation 继承原完成合同,纯“继续”沿用现有 continuation 识别边界。
- 验证方式:覆盖当前 game-chat child 的 running -> manifest pending 漂移仍保持 DAG 活跃并可完成投影;更新根 Run 后旧 child 被拒绝;派生视觉需要修复但已有 child 活跃时父 Run仍持久化等待;GUI child 继续拒绝 pending;普通美术措辞使用当前任务分类,不借用旧 `tetris-v1`。
- 关联文档:`docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`、`docs/project-memory/shared-memory/pitfalls.md`。
---
## 2026-08-05 增量接入既有美术时复用已验收 Graph 节点
> 已由 `2026-08-06 game-chat 固定规则只提供上下文,Supervisor 决定条件 Graph` 取代。下述内容保留为问题演进记录,不再作为当前实现依据。
- 背景:game-chat 增量指令“把 UI 和方块替换成美术资源”会重置七项首版 Graph,把已有且已验收的 `art-director / art-asset-plan` 重新打开。`art-asset-plan` 确定性快车道同时因图集已存在而返回零 action,child 完成门又要求 `assets/manifest.art.json` 相对本轮 baseline 发生变化,最终连续六轮得到同一 `unchanged-from-run-baseline` blocker 并耗尽 loop;这不是 Provider 故障。
- 决策:只有 game-chat 用户明确表达替换、接入、使用或复用美术资源,项目已有非占位游戏,且 art spec、透明图集、Canvas 登记、私有图集合同、四类切片与 art manifest 全部通过现有严格验收时,Graph reset 才保留 `art-director / art-asset-plan=completed`,只重新打开设计、代码和试玩节点。根 Supervisor 完成门仅对该合法复用场景豁免 `assets/manifest.art.json(unchanged-from-run-baseline)`;文件存在、JSON、Canvas、私有合同、切片和代码可见使用门禁继续执行,任一证据失效即撤销豁免。普通新游戏、全新/重做美术、否定使用或占位项目一律把美术节点恢复为 pending。
- 玩法连续性:合法增量美术接入从同 Session 的可信 Supervisor 历史根 Run 继承最近一个非 Generic 试玩场景;只跨过纯继续与既有美术接入语义,遇到更新的详细 Generic 新目标立即停止。例如 GUI 创建的俄罗斯方块转入 game-chat 继续使用 `tetris-v1`,不能因为本轮文字只描述 UI/美术而降级成 Generic,也不能跨过后来的新游戏目标借用旧场景。
@@ -6123,6 +6139,8 @@
## 2026-08-03 game-chat 开发态前后端同源与快车道恢复
> game-chat 的旧三 Director 首波、无条件美术生成和对应 Pending 容忍范围已由 `2026-08-06 game-chat 固定规则只提供上下文,Supervisor 决定条件 Graph` 取代;本条其余 GUI / CLI、启动、source 与输出决策继续有效。
- 启动决策:`npm run agc` 与 `npm run agc:game-chat` 统一先经外层 Node 启动器预检 `3080`。在 marker 尚不能证明 worktree 归属时,任何已占用的 3080 都不得复用,并必须在原生窗口创建前失败关闭;Tauri CLI 退出后必须收束已启动的客户端进程树,不允许终端已退出但窗口与 Runner 仍假在线。
- 首波决策:普通 GUI / CLI 的正式 16 节点 DAG 与 game-chat 首版 lane 都只把 `design-director / art-director / code-director` 作为首波 ready Agent。正式 DAG 的 `design-foundation` 等待策划与美术 Director,`code-prototype` 等待程序 Director 及数值、美术、音频三条底层产物链;game-chat 在策划与美术 Director 完成后启动 `art-asset-plan` 生成透明图集,`code-prototype` 必须同时等待三个 Director 与该图集任务,再串行执行静态检查和试玩。首波以外的非 repair 底层 Agent 只能由依赖就绪调度或上层明确返工合同按需激活。
- Runtime 决策:game-chat 七任务 lane、平台美术、单轮收束和自动预览只由持久 `project-supervisor-game-chat` root source 启用。hydration 对 `Pending` 的容忍只适用于当前 source-aware lane 的三个零依赖首波任务。页面进度、阶段记录和 final-reply 白名单统一使用七项任务与 `x/7`。
@@ -6131,6 +6149,8 @@
## 2026-08-03 game-chat 失败续跑与首版产物保护
> game-chat 的无条件美术生成部分已由 2026-08-06 的 Supervisor 条件路由取代;失败 continuation、非占位入口保护和美术产物验收边界继续有效。
- 事故事实:`game01` 的首个根 run 已交付并验证水晶下落方块原型,但父 run 在上下文压缩后因 token 上限失败;用户随后输入“继续”时,客户端创建了 task 仅为“继续”的新 game-chat root,完成合同重置 seed manifest,五分钟 fallback 再把该短语当主题整文件覆盖 `game/index.html`。这不是模型随机换题,而是 root 目标未继承、每新 run 无条件 reset 和 fallback 无条件 `file.write` 叠加形成的确定性缺陷。
- 续跑决策:同一 Supervisor Session、同一持久 source 的最近失败根 run 后,严格继续短语创建 successor root,并继承前序原始任务、baseline revision / artifact 身份;纯继续识别统一由一个精确函数负责,覆盖“继续 / 接着 / continue / go on”等无新约束短语。真正新需求、跨 Session、跨 GUI / CLI / game-chat source、前序正常完成或含具体新约束的输入继续创建独立新任务并重置本轮 manifest。successor 不复用旧网络请求、pending、action、Provider lifecycle 或 sidecar,只继承业务目标和已提交项目事实。
- 覆盖决策:game-chat fallback 只允许初始化缺失/占位入口的首次落盘。非占位 `game/index.html` 必须保留,并由当前 `code-prototype` 先读取和实际 patch,取得本人 `mutationRevision` 后才能运行 `game.static_smoke` 与交付;只读 smoke 不得冒充续作。确定性 fallback 只允许已实现真实语义的显式玩法模板:俄罗斯方块模板必须具备 10×20 棋盘、下落、移动、旋转、锁定、消行和触顶失败,收集模板只用于明确收集类目标,未知玩法失败关闭。纯继续目标未恢复时同样失败关闭。完成门新增 baseline 玩法连续性和 action-driven state 检查,generic Canvas 非空、三个按钮存在或静态 smoke 通过都不能单独证明任务没有换题。
@@ -81,9 +81,9 @@ cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml real_
修改 game-chat release flavor 后,至少执行壳配置门禁、AppSurface game-chat 定向测试、前端类型检查、AppData / 诊断日志 / release flavor 相关 Rust 定向测试、`npm run check:encoding` 和 `git diff --check`。打包 smoke 必须确认:安装信息和产物版本为 `0.1.1`;无参数启动直接进入且只能停留在 game-chat 页面;停止或断开 `api-server` 后本地工作台仍能打开;普通 dev / release 与 debug game-chat 仍走原认证入口;独立 AppData 生效。预览 smoke 应先让当前 run 成功验证 revision N,确认 Tauri registry 启动一个 server 且 iframe 自动出现;在 validate 后、start 取得锁前推进项目 revision,必须确认原子 `expectedRevision` 门禁拒绝启动且授权保留等待新证据;再验证 revision N+1,确认 server 进程和 loopback origin 不变、iframe 显示新版本且响应为 `no-store`。same-run steer 还要覆盖旧验证不消费新授权、旧异步 attempt 不清新 generation;Runner registry 单独 running、失败 / 相同 / 更低 revision 均不能触发用户预览或重复刷新,停止后顶部显示“预览未启动”。独立包退出时必须通过 `runner.shutdown_for_client_exit` 先进入 draining 再结束本 boot,保留 durable sidecar 供下次 reconciliation,不把中断任务写成 completed;Windows Runner 必须 `CREATE_SUSPENDED -> AssignProcessToJobObject -> ResumeThread`,分配或恢复失败时 kill + wait,客户端持有 kill-on-close Job 兜底,关闭主窗口后 Runner、MCP、command、ConPTY 及其后代都应消失。普通 dev / release 和 CLI 继续使用 `runner.shutdown_if_idle`。
game-chat 迭代还必须确认以下行为:Supervisor ready 输出、`design-director / art-director / art-asset-plan / code-director / code-prototype / preview-readiness / preview-playtest` 七个专业 Agent 的 durable `final-reply`,以及 Rust 明确生成 `eventId + publicText` 的每条公开 Runtime 输出都作为独立 assistant 消息逐条固化在项目聊天。消息通过顶层 `messageId` 幂等追加,事件 / 轮询 / hydration 重放不重复。前端禁止从原始 `summary / detail`、tool plan、Provider / Runner 元数据、命令输出或路径自行拼接持久消息;UI 把一个父 Run 统一显示为“本轮生成进度”,最新状态也不得暴露内部“第 N 轮”,完整 GUI / CLI 任务图可显示 `x/14`,首版快车道显示 `x/7`,终态不保留运行中进度卡;可信 `project-supervisor-game-chat` 一轮完成 `preview-playtest` 后直接收束,不请求下一次 Provider tool-plan;所有调度入口均不得暴露或启动 `publish-strategy` / `publish-package`。game-chat 必须配置可用的 External Editor API,按 `art-spec.png -> icon-spritesheet -> art-spritesheet.png + iconImageSrcs 本地切片 -> code-prototype Canvas 使用四类切片` 推进;缺少任一环节都必须失败关闭。
game-chat 迭代还必须确认以下行为:Supervisor ready 输出、本轮实际启动的 `design-director / art-director / art-asset-plan / code-director / code-prototype / preview-readiness / preview-playtest` 专业 Agent 各自产生 durable `final-reply`,条件路由跳过的节点只要求 manifest 正确投影为 completed,不伪造 Agent 回复;Rust 明确生成 `eventId + publicText` 的每条公开 Runtime 输出都作为独立 assistant 消息逐条固化在项目聊天。消息通过顶层 `messageId` 幂等追加,事件 / 轮询 / hydration 重放不重复。前端禁止从原始 `summary / detail`、tool plan、Provider / Runner 元数据、命令输出或路径自行拼接持久消息;UI 把一个父 Run 统一显示为“本轮生成进度”,最新状态也不得暴露内部“第 N 轮”,完整 GUI / CLI 任务图可显示 `x/14`,首版快车道显示 `x/7`,终态不保留运行中进度卡;可信 `project-supervisor-game-chat` 一轮完成 `preview-playtest` 后直接收束,不请求下一次 Provider tool-plan;所有调度入口均不得暴露或启动 `publish-strategy` / `publish-package`。固定关键词与资产探测只进入 Supervisor 的 advisory context;没有持久 Supervisor 路由时不得启动任何 child。只有程序侧审计判定存在真实缺口或 Supervisor 明确选择整体重做时才要求可用 External Editor API,并按 `art-spec.png -> icon-spritesheet -> art-spritesheet.png + iconImageSrcs 本地切片 -> code-prototype Canvas 使用四类切片` 补齐;`use-existing-art` 不得重复生成或扣费,但仍须通过相同正式资产和代码可见使用门禁。
game-chat 素材完整快车道采用七任务口径。父 Run 与全部 child Run 共用 4200 秒软预算和 4500 秒累计硬上限;先确定性生成并登记 `art-spec.png`,再由 `art-asset-plan` 通过专用 icon-spritesheet 路由生成透明 `art-spritesheet.png`,下载并持久化响应中的独立切片,最后才允许 code-prototype 写入或局部修复入口。软预算后只允许使用已登记图集、当前 resourceId 对应切片清单的确定性本地 fallback、`game.static_smoke` 和 `preview.validate`;不得退回普通生图、猜测 atlas 网格或纯代码核心画面。完成门要求活动 Canvas 分别绘制 player、blocks-and-targets、obstacles-and-scene、feedback-effects 四类不同切片;整图 `<img>`、CSS background、完整图集直绘、单个猜测裁切和路径诱饵均失败。对应定向测试至少包括:
game-chat 条件快车道仍采用七任务口径,但执行顺序由持久合同控制。父 Run 与全部 child Run 共用 4200 秒软预算和 4500 秒累计硬上限;Supervisor 首轮先调用 `agent.route_manifest`,决策前零 child。`audit-existing-first` 的首波仅为 `design-director + code-director`,已登记但无效的旧派生视觉不得阻断这两项审计启动;code-director 必须先 `asset.list`,读取 Supervisor 已持久化的 authoritative 决策,再提交正式资产覆盖合同。覆盖完整时跳过图片生成,存在缺口时只开放缺口对应 owner,`regenerate-art` 才强制重新开放两个美术 owner;已登记但校验失败的固定资产只允许当前路由绑定的 canonical owner 原位替换。新生成仍按 `art-spec.png -> art-spritesheet.png + 独立切片` 推进,最后才允许 code-prototype 写入或局部修复入口。软预算后只允许使用已登记图集、当前 resourceId 对应切片清单的确定性本地 fallback、`game.static_smoke` 和 `preview.validate`;不得退回普通生图、猜测 atlas 网格或纯代码核心画面。完成门要求活动 Canvas 分别绘制 player、blocks-and-targets、obstacles-and-scene、feedback-effects 四类不同切片;整图 `<img>`、CSS background、完整图集直绘、单个猜测裁切和路径诱饵均失败。对应定向测试至少包括:决策前零 child、旧无效视觉不阻断首波、首波无美术 child、code-director 收到真实持久策略、完整覆盖零生成、仅缺图集只运行 `art-asset-plan`、无效已登记资产由 owner 原位替换、art spec 缺失导致引用合同失效时同时补齐两个槽位、显式重做原位替换两个正式资产、旧 root/fingerprint/缺口或重复路由失败关闭,以及补齐后恢复 code-prototype。
失败续跑还必须覆盖同 Session 同 source 继承、跨 Session / 跨 source 不继承、首次与连续 successor 的 effective task / contract / scheduler 一致性,以及中英文纯继续短语使用同一识别函数。非占位入口的新 `code-prototype` 必须先产生本人 mutation 再 smoke;连续只读 smoke 不得收束。占位 fallback 只允许显式支持的真实玩法模板,俄罗斯方块必须验证棋盘、下落、旋转、锁定和消行语义,未知玩法必须失败关闭。
@@ -654,7 +654,7 @@ npm run ai-game-creator-shell:agent-runtime:supervisor-swarm-tool-plan-handoff-r
## AI 游戏创作长耗时与退出恢复验证
- 修改 autonomous 调度时,必须证明缺省 policy 不产生 manifest 之外的首波专业委派,Editor Key、已有/损坏视觉资产均不能改变该事实;显式项目 policy 只验证“原样尊重”,不能由 Runtime 隐式扩充。
- 修改 autonomous 调度时,必须证明缺省 policy 不产生 manifest 之外的首波专业委派,Editor Key、已有/损坏视觉资产均不能改变该事实;game-chat 还必须证明持久 Supervisor 决策前零 child,决策后的首波只有 `design-director + code-director`,固定关键词不能直接改 Graph。显式项目 policy 只验证“原样尊重”,不能由 Runtime 隐式扩充。
- 修改预览完成门时,分别覆盖 child `preview-readiness` 当前 revision smoke、child `preview-playtest` 到根 Supervisor 合同的 browser receipt,以及 WebSocket 启动前退出的稳定基础设施分类。基础设施错误必须在一次浏览器调用后让 run 失败,不能只做到后续调用快速失败而继续消耗 Provider 轮次。
- 修改 game-chat Runner 生命周期时,至少覆盖 busy durable sidecar 拒绝 client-exit、拒绝后 `draining=false` 可继续执行、清空后 idle shutdown、重复 shutdown 幂等;Windows target check 继续保留,不能以删除 Job Object 或放任后台继续来规避 reconciliation。
- LLM 配置回归必须穷举全部规范 Agent,校验无遗漏/重复、显式 patch 覆盖默认,并锁定 GUI 展示映射和 Rust resolver 一致;模板与 GUI 初始草稿不得把规范默认持久化成 `agentLlm` 显式覆盖。`--llm-status` 要输出逐 Agent 实际 reasoning/timing/retry 值。运行日志与当前配置冲突时,先区分 durable run snapshot 和后来修改的文件,不能按当前文件反推历史请求。
+20 -4
View File
@@ -22,12 +22,20 @@
- 验证:人工把当前 child 的 manifest 状态回写 pending,断言父 DAG 仍 in progress、父上下文可持久化为 `waiting-for-manifest-tasks`、child 可投影 completed;随后创建更新根 Run,断言旧 child 不再保持 DAG 活性且 completion blocker 恢复 `status=pending`。不要靠增加 loop 次数或伪造 completed 掩盖竞态。
- 关联:`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/autonomous_policy.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/main_loop.rs`、`apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/autonomous_completion.rs`。
## 固定关键词提示不能代替 Supervisor 选择条件任务图
- 现象:用户只说“现在没有用到任何美术资源”,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 先选审计或整体重做,code-director 再用成功 `asset.list` 和 Runtime 复核的覆盖合同选择复用或精确补缺。Runtime 可以拒绝过期、伪造、遗漏或重复 route,但不得替 Supervisor 补写决定。
- 验证:直接使用用户原句,断言 hint 命中但 manifest 全部保持 pending、决策前零 child、Provider request 包含路由工具;决策后首波只有 design/code,code-director 未完成 asset.list/route 时不能完成;再分别覆盖完整复用、真实缺口和显式重做。
- 关联:`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 门视为未变化
- 现象:增量任务已有完整美术图集,`art-asset-plan` 每轮都返回零 action 和“已验证交付”,但 completion gate 每轮都报告 `assets/manifest.art.json(unchanged-from-run-baseline)`;最终 child `loop-budget-exhausted`,随后 Graph 和父 Run 失败。日志中没有本轮 Provider request、tool plan 或 action receipt。
- 原因:Graph reset 无差别重新打开稳定的美术 owner 节点;快车道按“当前产物有效”判断完成,owner 完成合同则按“本轮必须修改 baseline 产物”判断完成,两套语义互相冲突。增加 loop 预算、伪造版本号或机械改写 manifest 都不能消除冲突,还会引入 verification loop、字段丢失或错误复用旧主题。
- 处理:先在 Graph 层区分“复用已验收产物”和“需要重新生成”。仅对明确的既有美术接入意图、非占位游戏和整套严格有效的视觉合同保留美术节点 completed;根完成门只忽略这一路径的 art manifest baseline 相同,所有结构、Canvas、私有回执、切片和可见使用验收继续失败关闭。普通新游戏、全新美术或证据损坏必须重新打开 owner 节点。
- 验证:不要只断言 child 未被调度;还要直接经过父完成门,证明合法复用不再出现 art baseline gap,并证明删除切片后 baseline gap 与视觉合同 gap 重新出现。另覆盖普通新目标和全新美术请求不复用旧美术。
- 处理:关键词和资产探测只作为 Supervisor 的 advisory context,不能直接修改 Graph。根 Run 先持久化 `audit-existing-first / regenerate-art` 决策;前者只启动 `design-director + code-director`,由 code-director 在成功 `asset.list` 后提交权威覆盖合同和精确缺口。Runtime 验证合同后才把已有 owner 投影为 completed,或只打开缺口 owner;根完成门只对持久路由明确复用的 art manifest 忽略 baseline 相同,所有结构、Canvas、私有回执、切片和可见使用验收继续失败关闭。
- 验证:先断言 Supervisor 决策前零 child、固定关键词不会预完成节点,再覆盖完整复用、仅缺图集和明确重做。还要直接经过父完成门,证明合法持久路由不再出现 art baseline gap,并证明删除切片后覆盖合同拒绝复用;旧 root、错误 fingerprint、虚构或遗漏缺口和重复改写路由都应失败关闭。
- 关联:`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`。
## 执行锁移交给未确认启动的异步 future 会制造永久 queued
@@ -395,10 +403,18 @@
- 现象:产品要求画板 `生成角色动作` 返回后按透明序列帧播放和下载,但旧实现或旧测试可能继续把结果当作预览视频处理。
- 原因:后端仍需要先生成 `previewVideoPath` 再抽帧、绿幕去背和落 OSS;如果前端把预览视频当主媒体,就会绕过已经扣绿幕的 PNG 帧,也无法按序列帧打包下载。
- 处理:角色动作结果图层主 `src` 使用 `frames[0].imageSrc`,`mediaType` 固定为 `image-sequence`,`assetKind` 固定为 `character-animation`,完整帧列表写入 `imageSequenceFrames`,`previewVideoPath` 只作为来源信息保留。单图层下载必须生成序列帧 ZIP;画布素材 ZIP 中角色动作写入 `sequences/<编号-标题>/frames/`。不得移除后端原有视频生成、抽帧、绿幕去背和帧落盘流程。
- 验证:`ImageCanvasGenerationLayerModel` 应断言动作结果 `src` 为首帧且 `mediaType="image-sequence"`;画布集成测试应出现 `画布序列帧:角色动作` 图片播放器,不应出现角色动作 `<video>`;导出测试应断言角色动作下载和画布素材导出都包含序列帧 ZIP / frames 目录。
- 处理:角色动作结果图层主 `src` 使用 `frames[0].imageSrc`,`mediaType` 固定为 `image-sequence`,`assetKind` 固定为 `character-animation`,完整帧列表写入 `imageSequenceFrames`,`previewVideoPath` 只作为来源信息保留。生成端确认每帧对象后必须把该帧 `objectKey` 与 `assetObjectId` 一起写入正式 payload 和 `generation_inputs_json.characterAnimation.frames`。单图层下载必须生成序列帧 ZIP;画布素材 ZIP 中角色动作写入 `sequences/<编号-标题>/frames/`。不得移除后端原有视频生成、抽帧、绿幕去背和帧落盘流程。
- 验证:`ImageCanvasGenerationLayerModel` 应断言动作结果 `src` 为首帧且 `mediaType="image-sequence"`;画布集成测试应出现 `画布序列帧:角色动作` 图片播放器,不应出现角色动作 `<video>`;导出测试应断言角色动作下载和画布素材导出都包含序列帧 ZIP / frames 目录;生成测试还应断言首帧与非首帧的稳定引用都被保留。
- 关联:`src/components/image-editor/ImageCanvasGenerationLayerModel.ts`、`src/components/image-editor/ImageCanvasWorldView.tsx`、`src/components/image-editor/ImageCanvasExportModel.ts`、`server-rs/crates/api-server/src/character_animation_assets.rs`、`docs/【编辑器】画板角色形象生成入口设计-2026-06-15.md`。
## OSS 导出兜底必须覆盖响应体读取阶段
- 现象:浏览器控制台显示 OSS `206 Partial Content` 后紧跟 `net::ERR_FAILED`,画布预览或素材导出失败,但没有出现预期的 `/api/assets/read-bytes` 兜底请求。
- 原因:`fetch(signedUrl)` 可能先返回一个 `ok` 的 `Response`,网络、浏览器 Range 缓存或传输错误随后才在 `arrayBuffer()` / `blob()` 消费响应体时暴露;如果直连保护边界只包住 `fetch` 和状态码,响应体失败会绕过 fallback。
- 处理:私有素材字节读取必须在直连 OSS 分支内完整消费响应体并重新构造可重复读取的 `Response`;换签、请求、非成功状态或响应体读取任一阶段失败时统一回退同源 `/api/assets/read-bytes`。Abort 仍应直接上抛,不能转化为额外服务器读取。
- 验证:前端服务测试模拟 OSS 返回 `206/ok`、但 `blob()` reject,断言随后请求 `/api/assets/read-bytes` 并返回 fallback 完整字节;同时保留直连成功、局部分片、直连非成功、请求 reject 和 Abort 边界。
- 关联:`src/services/assetReadUrlService.ts`、`src/services/assetReadUrlService.test.ts`、`src/components/image-editor/ImageCanvasExportModel.ts`。
## 图片画布序列帧播放不要复用普通图片淡入样式
- 现象:角色动作序列帧播放时看起来像每帧之间在渐变或闪烁。
@@ -166,7 +166,7 @@ assetObjectId > objectKey > sourceAssetId > src
4. 对每个素材源读取 Blob:
- `data:image/...` 直接转换为 Blob。
- 同源或可访问 URL 使用 `fetch` 拉取 Blob。
- 私有 generated / OSS 素材先走 `/api/assets/read-url` 换签并由浏览器直接 `fetch` OSS 签名 URL;只有换签或 OSS 字节读取失败时,才 fallback 到同源 `/api/assets/read-bytes`。
- 私有 generated / OSS 素材先走 `/api/assets/read-url` 换签并由浏览器直接 `fetch` OSS 签名 URL;必须在同一保护边界内完整消费响应体,换签、请求、状态码或响应体读取任一阶段失败时,才 fallback 到同源 `/api/assets/read-bytes`,不得在只拿到 `2xx/206` 响应头后提前视为读取成功。
- `mediaType="image-sequence"` 逐帧读取 `imageSequenceFrames`,写入 `sequences/<编号-标题>/frames/`。
- 画布素材 ZIP 内的 `mediaType="image-sequence"` 同步写入 `skeleton.json`,供 Spine Editor 或 runtime 以 slot attachment timeline 方式播放序列帧。
- 单图层普通序列帧导出写入 `preview.gif`,由前端基于成功读取的帧生成动画预览,不依赖压缩包读取时再临时播放 PNG。
@@ -194,6 +194,7 @@ assetObjectId > objectKey > sourceAssetId > src
- 图层的锁定、翻转、分组状态写入元数据。
- `data:image` 图片不经过网络请求即可导出。
- URL 图片 fetch 失败时不中断其他素材导出。
- OSS 返回 `2xx/206`、但响应体读取失败时,自动改走 `/api/assets/read-bytes`,并使用 fallback 的完整字节生成 Blob。
- 动作图层右键菜单把 `导出为` 作为一级入口,二级菜单提供 `序列帧导出(zip)` 和 `Spine 导出(zip)`。
- 单图层普通序列帧 ZIP 包含 `frames/`、`preview.gif`、`metadata.json` 和 `manifest.txt`,且不包含 `skeleton.json`。
- 序列帧导出的 `skeleton.json` 可被独立验证器解析并预览。
@@ -35,7 +35,7 @@
- Supervisor 进度播报:聊天消息流内保留且只保留一条当前 run 的 Runtime-owned 播报卡,由客户端从 manifest 任务图、Supervisor 结构化计划、`loopIteration`、当前动作、直接委派专业 Agent 及其持久事件确定性整理;显示当前轮次、任务 / 计划进度、活跃 Agent、最近试玩与静态检查、返工决定、代码修改和截图检查证据。同一 run 原位更新,切换 run 时替换,不调用额外模型、不追加持久 conversation,也不改变最终 assistant 回复的唯一性;任意详情必须有界且不展示绝对路径、Provider 元数据或内部指纹。
- ready-task 启动活性:`background_task.queued`、`autonomous_ready_task.scheduled`、Runner heartbeat 或执行锁已移交都不等于 child 已启动。实际持有执行权的 Runner 必须在释放项目写锁后同步写入 child 的 running task、`turn.started` 与 started journal,再把已启动 state 和 per-Agent 执行锁交给已确认开始轮询的独立 execution worker;同步启动或 worker 接管失败时,要在仍持有执行锁期间依次把 child 和 manifest Graph 节点明确落为 failed,再释放锁并让 parent 收到调度错误。`autonomous_ready_task.scheduled` 只作诊断审计,其写入失败不能阻断 durable child 启动;external client 只 wake Runner,不在客户端抢占执行。Supervisor 进度卡通过 durable `startedAt`(旧 Run 从完整 task journal 恢复,最新 task-record fallback 保持 0)显示真实持续时间,并以父 Run 与当前关联专业 Agent 的最大事件时间计算运行态活跃度:运行超过 5 分钟无新事件时显示“运行中 · 疑似停滞”和静默时长;等待用户、等待确认、Provider retry、视觉资产、进程会话、pausing 与 paused 不误报。父 Run terminal 后,持续时间冻结在父 Run 自身最后活动,不随 child 晚到收口事件增长。消息时间统一校验为 JavaScript 可表示的 Date;越界值显示“时间未知”且不写无效 `datetime`。实时回复只显示 response stream 自己的 `updatedAt`,缺失时同样显示“时间未知”,不能借用其它 Runtime 活动时间或随前端时钟漂移。该提示只提供可观测性,不改变 Runtime/manifest 正式状态。
- ready-task manifest 漂移:父 Supervisor 必须分别判断“能否调度新节点”和“是否存在必须等待的工作”。派生视觉需要父规划修复时不再调度新 child,但当前最新且活跃的根 Run 下,只要存在确定性 runId、scheduler source、正确父绑定且 durable journal 为 queued/running 的 ready child,父 Run 就保持 `waiting-for-manifest-tasks`,不能因旧 hydration 快照把 manifest running 覆盖成 pending 而提前 fixed-graph-stalled。game-chat child 可在相同严格身份下容忍 pending 漂移;正式产物、Canvas、revision、`game.static_smoke` 与 `preview.validate` 门禁不放宽。GUI/CLI、旧父 Run、终态、确认/用户输入/reconciliation、伪造绑定或非确定性 runId 全部失败关闭;更新根 Run 后旧 child 不得继续维持新 DAG 或投影完成。
- 增量既有美术复用:game-chat 用户明确要求把 UI、方块或当前画面替换、接入、使用或复用美术资源时,只有项目已有非占位游戏,且 art spec、透明图集、Canvas 登记、私有图集合同、四张语义切片和 art manifest 全部通过严格验收,Graph reset 才保留 `art-director / art-asset-plan=completed`,重新打开设计、代码和试玩节点。根完成门只在同一合法复用条件仍成立时忽略 `assets/manifest.art.json(unchanged-from-run-baseline)`,其余产物、视觉合同和代码可见使用验收不放宽;任一切片或私有证据损坏后豁免立即失效。普通新游戏、明确要求全新/重做美术、否定使用旧美术或占位项目必须把美术节点恢复 pending。该增量任务从同 Session 的可信 Supervisor 历史根 Run 继承最近的非 Generic 试玩场景,只跳过纯继续与既有美术接入语义,遇到更新的详细 Generic 新目标立即停止;GUI 创建的俄罗斯方块转入 game-chat 后仍使用 `tetris-v1`,但不能跨后续项目目标借用更老场景。不得以增加 loop 预算、伪造产物 revision、机械改写 manifest 或重放历史图片 action 代替 Graph 语义修复。
- Supervisor 主导的条件美术路由:game-chat 的关键词、用户是否报告“美术未接入”、占位状态和当前资产探测只形成 `advisoryOnly=true` 的补充上下文,不得直接重置 Graph、预完成美术节点、选择复用/生成分支或继承历史试玩类型。当前根 Run 没有持久化 Supervisor 决策时,scheduler 不启动任何 manifest child,Supervisor Provider 必须先通过 auto-safe 的 `agent.route_manifest` 选择 `audit-existing-first` 或用户明确要求整体重做时的 `regenerate-art`。决策后首波只开放 `design-director + code-director`;`code-director` 必须先成功调用 `asset.list`,再以同一工具提交 `use-existing-art / generate-missing-art / regenerate-art` 与精确 `missingAssetSlots`。Runtime 只负责校验 root/child 身份、当前 revision、Canvas 登记、私有图集合同、四张语义切片、art manifest、覆盖 fingerprint 和路由 fingerprint,并据此把 `art-director / art-asset-plan` 投影为 completed 或 pending;缺少 art spec 若同时使图集引用合同失效,两个槽位都属于真实缺口,不能为了少调一个 Agent 伪称图集可复用。只有持久路由明确复用 `art-asset-plan` 时,根完成门才忽略 `assets/manifest.art.json(unchanged-from-run-baseline)`;其余产物、可见代码使用与试玩门禁不放宽。明确 `regenerate-art` 时两个正式图片 owner 使用严格绑定当前 root Run 的原位替换授权。纯“继续”仍走既有正式 continuation 合同;普通美术措辞不得借用更老项目的具体试玩场景。不得以增加 loop 预算、伪造 revision、机械改写 manifest 或重放历史图片 action 代替 Supervisor 决策和程序侧审计。
- ready-task 对账取消续跑:未知工具结果仍停在 `needs-reconciliation` 且禁止自动重放;人工核对后显式取消原 child,保留 cancel tombstone,旧 child 和旧父 Run 按真实终态收口。若随后创建同 Session、同 Supervisor source、同有效任务语义的 continuation,新完成合同只对同时具有历史 `failed / needs-reconciliation`、最终 `cancelled` 和 durable tombstone 的 ready-task,把当前 manifest 对应 failed 节点恢复为 pending,并由 scheduler 创建全新 child Run。manifest 的读取、failed 筛选、每任务一次的 child journal 索引、证据重验和写回必须位于同一项目写锁域;较新的无 child 根 Run 只有在 durable journal 精确表明为旧 failed Graph 在进入调度前即失败时才能跨过,scheduler 自身失败必须阻断借用更老 tombstone。普通失败、无 tombstone、不同 source/Session/任务语义或证据冲突均保持失败关闭;不得复活旧 pending action、补造 observation 或把取消任务标成 completed。
- 完成门静态分析预算:Canvas 视觉门必须先做只会提前拒绝的词法预检。经典或模块脚本同时不含大小写精确的 `import` 与 `export` 字节序列时,不运行模块依赖语义分析;纯 `export ... from` / `export * from` 仍须进入正式模块图分析。当前脚本不含目标文件名或任一已绑定 DOM 图片元素 ID 时,先低成本解码 `\\xNN`、`\\uNNNN`、`\\u{...}`、简单转义和续行;解码后仍无候选才不运行完整 Canvas alias / 函数可达性分析,解码不确定则保守进入 Oxc。存在任一候选时仍执行原 parser、semantic binding、解码后的 computed 属性/StringLiteral 路径、可达 `drawImage`、可见 Canvas、路径大小写和动态 namespace 写入门禁;HTML 中存在某个绑定元素不得使所有无关 JavaScript 单元进入重分析,禁止把词法命中当作通过条件。
- Provider 故障展示:Provider retry 的“是否可重试”继续使用 `upstream-5xx` 等稳定类别判断,但 durable retry record 保留安全的精确 `upstream-<HTTP status>` 身份。等待态必须从真实 record 显示 HTTP 状态、`nextAttempt/maxRetries` 与当前持久退避剩余秒数,例如“Provider 上游返回 HTTP 503,准备自动重试 1/3;预计 8 秒后重试”;不得以动画或前端自增计时伪造 attempt。重试耗尽的 Runtime 私有错误只保存 `kind/httpStatus/fingerprint/chars/retryAttempt/maxRetries/retryState`,前端和持久 conversation 仅在字段顺序、范围、状态一致且无尾随正文时派生“上游服务返回 HTTP 503;自动重试已耗尽(3/3)”;其它错误使用固定安全摘要。Provider 响应正文、URL/query、凭据、本地绝对路径、fingerprint、字符数和 `[redacted ...]` 占位符均不得进入用户可见消息。
@@ -57,26 +57,26 @@
## 2026-07-31 game-chat 输出、单轮预览与平台美术资源
- 对话输出:game-chat 的 Supervisor `ready` response stream 继续以稳定身份显示;`design-director / art-director / art-asset-plan / code-director / code-prototype / preview-readiness / preview-playtest` 的 `requestKind=final-reply` 且 `status=ready|committed` 的非空安全回复也分别以 Agent、Session、run、request slot 和 response revision 形成 durable message ID,并带 Agent 标签逐条追加到项目聊天。每条 Rust `eventId + publicText` 公开输出同样形成独立 durable 消息。所有这些消息通过 `append_local_conversation_message` 的顶层 `messageId` 幂等写入,事件、轮询、React StrictMode 和 hydration 重放不重复;tool-plan、半成品 stream、原始事件 detail、命令正文、绝对路径、Provider / Runner 元数据、哈希和凭据不得进入聊天。普通 `supervisor-chat` 保持原有 transient response 行为。
- 对话输出:game-chat 的 Supervisor `ready` response stream 继续以稳定身份显示;七任务目录中本轮实际启动的专业 Agent,其 `requestKind=final-reply` 且 `status=ready|committed` 的非空安全回复分别以 Agent、Session、run、request slot 和 response revision 形成 durable message ID,并带 Agent 标签逐条追加到项目聊天。条件路由跳过的美术节点只要求 manifest 正确投影为 completed,不伪造 Agent 回复。每条 Rust `eventId + publicText` 公开输出同样形成独立 durable 消息。所有这些消息通过 `append_local_conversation_message` 的顶层 `messageId` 幂等写入,事件、轮询、React StrictMode 和 hydration 重放不重复;tool-plan、半成品 stream、原始事件 detail、命令正文、绝对路径、Provider / Runner 元数据、哈希和凭据不得进入聊天。普通 `supervisor-chat` 保持原有 transient response 行为。
- 单轮收束:game-chat source 只生成至 `preview-playtest` 的 manifest seed task,试玩完成后父 Run 直接进入完成门,不再调度 `publish-strategy` / `publish-package`;`agent.schedule_ready` 必须按当前 Supervisor Run 的持久 source/profile 选择同一 source-aware scheduler,不能绕过该边界。`task.list` 对同一 root source 必须从任务行、readyTaskIds 和统计中排除两个发布节点,`agent.delegate` 也必须按 root binding 拒绝直接委派这两个节点,不能让 Provider 用“读取完整 DAG 后手工委派”恢复已裁掉的发布阶段。完成门满足且 collaboration、Provider batch、进程会话、视觉资源等非验证屏障全部清零后,Runtime 必须用确定性回复直接收束结构化计划并结束父 Run,不再请求下一次 Provider 工具计划。普通 GUI / CLI 仍执行完整发布 DAG。
- 轮次展示:`loopIteration` 只是同一父 Run 内的 Provider / 工具规划循环,用于委派、回执、返工和验收,不是用户发起的游戏生成轮次。game-chat 的进度卡、当前工作和“最新状态”事件统一显示“本轮”,整个页面不向用户显示“第 N 轮”;完整 GUI / CLI pre-publish 任务图仍可显示 `x/14`,但首版只按七项任务显示 `x/7`(详见 2026-08-03 小节),不得把两个发布节点计入任一分母。父 Run 终态后移除运行中进度卡,只保留终态阶段记录与预览。
- 平台美术资源:game-chat 恢复正式视觉 DAG。`art-director` 先通过平台 `images/generations(kind=spec)` 生成并登记 `assets/art-spec.png`;`art-asset-plan` 再以该规范图的稳定 resourceId 调用 `icon-spritesheets/generations` 生成真实透明 `assets/art-spritesheet.png`,并把响应中的 `iconImageSrcs` 下载为本地独立切片,写入 `assets/art-spritesheet-slices/manifest.json`。`code-prototype` 必须等待图集与切片清单,并在活动 Canvas 中分别绘制玩家、方块/目标、障碍/场景与反馈四类切片;规范图只作 reference,纯代码核心画面、猜测图集等分网格、整图 `<img>` / CSS 背景、完整图集直绘或只出现路径均不得完成。
- 平台美术资源:game-chat 保留正式视觉 DAG,但是否进入生成节点由 2026-08-06 的持久条件路由决定。现有正式资源覆盖完整时直接复用;存在真实缺口或 Supervisor 明确选择整体重做时,`art-director` 才通过平台 `images/generations(kind=spec)` 生成并登记 `assets/art-spec.png`,`art-asset-plan` 再以该规范图的稳定 resourceId 调用 `icon-spritesheets/generations` 生成真实透明 `assets/art-spritesheet.png`,并把响应中的 `iconImageSrcs` 下载为本地独立切片,写入 `assets/art-spritesheet-slices/manifest.json`。`code-prototype` 必须等待复用或补齐后的图集与切片清单,并在活动 Canvas 中分别绘制玩家、方块/目标、障碍/场景与反馈四类切片;规范图只作 reference,纯代码核心画面、猜测图集等分网格、整图 `<img>` / CSS 背景、完整图集直绘或只出现路径均不得完成。
- 验证:前端运行时模型定向测试、Rust completion/source/asset 合同测试、`cargo fmt --check`、`npm run check:encoding` 与 `git diff --check` 必须全部执行;Windows 文件锁竞态只可作为既有测试失败单独记录,不得将其改写为本次改动的通过证据。
## 2026-08-01 game-chat 首版七任务素材完整快车道与美术硬门
- 首版任务边界:game-chat 首版只展示 `design-director`、`art-director`、`art-asset-plan`、`code-director`、`code-prototype`、`preview-readiness`、`preview-playtest` 七项任务,进度统一显示为 `x/7`;首波并行激活三个 Director,`art-asset-plan` 依赖 `design-director + art-director`,`code-prototype` 同时等待三个 Director 与 `art-asset-plan`,后续验证串行推进。不把完整 GUI / CLI 任务图的其它节点投影到该页面,也不显示内部 Provider / child loop 轮次。
- 首版任务边界:game-chat 首版只展示 `design-director`、`art-director`、`art-asset-plan`、`code-director`、`code-prototype`、`preview-readiness`、`preview-playtest` 七项任务,进度统一显示为 `x/7`;当前根 Run 在 Supervisor 持久路由前零 child,`audit-existing-first` 决策后的首波只激活 `design-director + code-director`。code-director 审计后,完整资源把两个美术节点投影为 completed;真实缺口或整体重做才按依赖开放对应美术 owner,随后 `code-prototype` 与验证节点串行推进。不把完整 GUI / CLI 任务图的其它节点投影到该页面,也不显示内部 Provider / child loop 轮次。
- 时间预算:从 game-chat 父 Run 接受用户请求开始,素材完整首版使用 `4200` 秒软预算;父 Run 与其全部 child Run、等待和回收阶段共享从 root `bound_at` 计算的 `4500` 秒绝对硬上限。该值来自现有两次串行生成各自最长 35 分钟的客户端等待合同,并为代码兜底、静态检查和双视口试玩保留 5 分钟。整个 Runtime pass 受同一 `timeout_at` 约束;硬上限内未通过完成门必须失败关闭,不得为了守时跳过图集、换普通生图或回退纯代码核心画面。即使完成证据恰好在上限后到齐,单轮确定性收束也必须再次检查累计预算并拒绝写入 `single_round_converged`。
- Provider 次数:首波 `design-director / code-director` 的规划请求与 `art-director` 的确定性规范图生成并行;规范图和设计方向就绪后,Runtime 确定性派发 `art-asset-plan` 的 icon-spritesheet 生成。图集登记后 `code-prototype` 最多执行一次 Provider 首版写入请求;软预算耗尽时只允许生成真实加载并裁切图集的确定性本地兜底。Provider 成功返回后由 Runtime 依次执行确定性的 `game.static_smoke` 与 `preview.validate`。
- Provider 次数:Supervisor 先用一个 Provider turn 理解目标并持久化条件路由;`audit-existing-first` 的首波仅请求 `design-director / code-director`,code-director 成功 `asset.list` 并提交覆盖合同后,Runtime 才确定性派发真实缺口对应的 `art-director / art-asset-plan`。完整复用不得调用图片生成接口;图集复用或登记完成后 `code-prototype` 最多执行一次 Provider 首版写入请求。软预算耗尽时只允许使用已登记图集和当前 resourceId 切片清单的确定性本地兜底,Provider 成功返回后由 Runtime 依次执行确定性的 `game.static_smoke` 与 `preview.validate`。
- 可玩兜底:软预算或首版 Provider 无法及时完成时,只能为已显式实现真实语义的玩法生成完整、自包含、无远程运行依赖的中文 HTML 模板;未知玩法失败关闭,不能只替换标题后套用固定收集游戏。俄罗斯方块模板必须包含 10×20 棋盘、下落、移动、旋转、锁定、消行和触顶失败;收集模板只匹配明确收集类目标。模板必须从 `ready` 开始,包含真实 Canvas 绘制、`requestAnimationFrame`、键盘 / 触控主要操作、唯一可见且启用的 start / primary-action / restart 控件,状态 JSON 只随真实输入、状态迁移或模拟状态变化推进,并能在 primary-action 后保持 `playing`、在 restart 后稳定回到 `ready | playing`;不得在开始前固定进入 `lost`,不得通过固定失败冒充试玩通过,也不得由纯渲染帧空转 `sequence`。兜底只允许写入缺失或精确初始化占位的 `game/index.html`;存在非占位入口时,当前 `code-prototype` 必须读取并实际 patch,取得本人 `mutationRevision` 后再静态检查和试玩,不得反复用只读 smoke 冒充续作。
- 平台图片:`art-spec.png` 只用于约束色板、材质、形状与后续派生,不是运行时背景、角色、目标或图集。`art-asset-plan` 必须以其稳定资源 ID 走专用 icon-spritesheet 路由,透明像素、generation route/kind、同画布归属和 reference resource ID 继续由 Runtime 验证。完整透明图集在编辑器合同中即使产生 `sliceWarning` 仍可登记,但 game-chat 不能据此猜测 atlas 坐标;图集 resourceId 缺失或空白时必须在任何本地写入前失败,四个切片均须保留与整图完全一致的 `sourceResourceId`,切片数量也必须在正式图集登记前严格等于四,多或少都失败关闭。四类唯一性按尺寸与解码后的规范 RGBA 像素摘要判断,不能用不同 PNG 压缩或 ancillary chunk 冒充不同素材。主图、四张 canonical 切片和切片清单必须共同提交,并把主图/切片摘要及 Canvas 身份冻结到 `.agent/runtime/art-spritesheet-contract.json` 私有回执;后续主图安装、回执或登记失败时恢复旧合同,避免出现旧图集绑定新切片。进程在固定主图落盘后崩溃时,保留的 generation 账本只允许按远端预期摘要幂等补齐同一组合同,路径内容冲突继续失败关闭。全部切片下载累计最多 `32 MiB`。完成门重新读取本地素材时仍执行相同文件大小、解码内存、内容摘要、规范像素摘要、可见 alpha 与四类唯一性校验,并要求公开切片清单、当前 Canvas 登记与私有回执完全一致,后续代码 Agent 不能通过同时改写素材和公开清单重定义合同。`postprocess-failed-source-preserved`、无真实 alpha、缺文件或缺登记同样失败关闭。首版只在 `preview-playtest` 后单轮收束,不进入发布节点。
- 关联验收:快车道必须分别验证三 Director 首波并行、`art-asset-plan` 在代码前完成、`x/7` 投影、七个专业 Agent 安全 final-reply、4200 / 4500 秒累计预算、规范图到 icon-spritesheet 的真实引用、`iconImageSrcs` 本地持久化与资源 ID 绑定、失败续跑目标继承、非占位入口禁止整文件覆盖、纯代码核心画面、猜测单个 atlas 裁切与整图展示失败、四类独立切片可见使用通过、action-driven `sequence`,以及当前 revision 的静态 smoke 与浏览器试玩。
- 关联验收:快车道必须分别验证 Supervisor 决策前零 child、审计首波只有 design/code、完整覆盖零图片生成、精确缺口只启动对应 owner、显式重做两个正式 owner、`art-asset-plan` 在代码前完成、`x/7` 投影、实际启动的专业 Agent 安全 final-reply、跳过节点正确终态投影、4200 / 4500 秒累计预算、规范图到 icon-spritesheet 的真实引用、`iconImageSrcs` 本地持久化与资源 ID 绑定、失败续跑目标继承、非占位入口禁止整文件覆盖、纯代码核心画面、猜测单个 atlas 裁切与整图展示失败、四类独立切片可见使用通过、action-driven `sequence`,以及当前 revision 的静态 smoke 与浏览器试玩。
## 2026-08-03 game-chat 开发态同源与持久输出修复
- 开发态启动必须在 Tauri CLI 之前预检固定 `3080`。现有 marker 只包含 API target,不能证明监听器属于当前 worktree;因此只有端口空闲时才允许继续,任何已存在的 AGC Vite、非 HTTP 监听器或其它服务都必须在原生窗口创建前失败关闭。启动器不擅自终止无法证明归属的旧服务,也不得把当前 Rust 壳 / Runner 与其它 worktree 的旧 Vite 前端混用。Tauri CLI 任意退出后,外层启动器必须有界收束已启动的客户端进程树,避免 `beforeDevCommand` 失败后留下假在线窗口。
- game-chat root binding 的 `source` 必须精确为 `project-supervisor-game-chat`。只有该持久 source 才能选择首波并行 `design-director + art-director + code-director`,随后按 `art-asset-plan → code-prototype → preview-readiness → preview-playtest` 推进七任务 lane、规范图派生图集美术门、单轮确定性收束和自动预览;若绑定为 `project-supervisor-gui`,必须视为启动链路错误,不能用完整 16 节点 DAG 的运行状态伪装 game-chat 进度。
- source-aware lane 的首波 ready child 可能在 UI hydration 写回时短暂恢复为 `Pending`。该例外必须从当前 root source 的种子 lane 解析全部零依赖任务,不得硬编码某个 Agent;当前 game-chat 首波是 `design-director / art-director / code-director`,后续 code prototype / preview child 仍严格拒绝 `Pending` 收束。
- game-chat root binding 的 `source` 必须精确为 `project-supervisor-game-chat`。只有该持久 source 才能进入 Supervisor 决策前零 child 的条件 lane;`audit-existing-first` 路由后先运行 `design-director + code-director`,再按覆盖合同选择复用或补齐美术,最后推进 `code-prototype → preview-readiness → preview-playtest`、单轮确定性收束和自动预览。若绑定为 `project-supervisor-gui`,必须视为启动链路错误,不能用完整 16 节点 DAG 的运行状态伪装 game-chat 进度。
- source-aware lane 的 ready child 可能在 UI hydration 写回时短暂恢复为 `Pending`。该例外必须从当前 root source、持久工作流决策和资产路由解析本轮已开放节点,不得硬编码旧三 Director 首波;当前审计首波是 `design-director / code-director`,后续美术、code prototype 与 preview child 仍严格拒绝未授权或不满足依赖的 `Pending` 收束。
- 专业 Agent 的非流式 final reply 继续由既有 finalization journal 重建并提交 `responseStream`。`streaming / ready` 投影仍必须匹配当前项目 revision;已经 finalization 提交的 `committed` 回复以 Agent / Session / run / request slot / response revision 稳定身份为准,不得因后续阶段推进项目 revision 而从 game-chat 查询中消失。
## Runtime 边界