Merge remote-tracking branch 'origin/master' into feat/pixel_art
Project CI / Repository checks (pull_request) Successful in 2m34s
Project CI / Frontend tests (pull_request) Successful in 2m58s
Project CI / Backend tests (pull_request) Successful in 4m2s
Project CI / Native shell tests (pull_request) Failing after 15m56s

# Conflicts:
#	docs/project-memory/shared-memory/decision-log.md
This commit is contained in:
2026-08-19 04:04:41 +00:00
181 changed files with 25076 additions and 3841 deletions
@@ -3681,6 +3681,13 @@
"maxLength": 200
}
},
"sliceLayout": {
"type": "string",
"enum": [
"grid-2x2"
],
"description": "可选固定图集切片合同。省略时沿用全图 alpha 连通域自动拆分;传 grid-2x2 时服务端要求生成四个固定象限,并按左上、右上、左下、右下各持久化一个独立切片。该模式适用于需要恰好四类核心运行时素材的游戏,不会猜测等分裁切。"
},
"screenColor": {
"type": [
"string",
@@ -3958,11 +3965,18 @@
},
"iconImageSrcs": {
"type": "array",
"description": "识别图集中全部有效 alpha 连通域并持久化的独立素材列表,按视觉阅读顺序命名为“素材 N”;数量由图集内容决定,不由 iconDescriptions 数量决定。自动生成与手动拆分图集使用相同识别规则。",
"description": "默认模式识别图集中全部有效 alpha 连通域并持久化的独立素材,按视觉阅读顺序命名为“素材 N”;数量由图集内容决定,不由 iconDescriptions 数量决定。sliceLayout=grid-2x2 时固定返回左上、右上、左下、右下四个格子的切片,各格内的零散视觉细节不会被拆成额外素材。",
"items": {
"$ref": "#/components/schemas/EditorIconSpritesheetIconResult"
}
},
"sliceLayout": {
"type": "string",
"enum": [
"grid-2x2"
],
"description": "仅当请求使用固定切片合同且主图完成透明化、切片持久化后返回。调用方可将该字段与 iconImageSrcs=4 共同作为固定四类素材的来源证明。"
},
"sliceWarning": {
"anyOf": [
{
@@ -109,7 +109,7 @@
- 主站账号、钱包、服务端项目、云端素材库和生成面板仍留在网站宿主;客户端本地项目、manifest、Runtime、审批、草稿、生成与正式提交仍留在 Tauri 宿主。共享视觉组件不得读取这些业务事实。
- 客户端 UI 对齐采用“同视觉、同组件、保留四区布局”,不复制主站整页布局。资源总览、运行视图和 Supervisor 对话继续是 Game Agent 工作台独有语义。
- 客户端正式产品仍只按最小 `1280×720` 横屏合同交付,并保留 `1280×800` 默认窗口与既有基线验收;更窄浏览器样式只负责不崩溃和开发兼容,不改成移动端创作工作台。
- 普通用户界面不默认展示内部错误码或本机绝对路径;External Editor 配置只进入独立“运行时配置”对话框,不与素材画布主要动作并列,确需诊断的信息进入受控详情或开发模式。
- 普通用户界面不默认展示内部错误码或本机绝对路径,也不展示 External Editor Base URL 或 Developer API Key;官方服务地址由客户端构建固定,远端编辑自动使用当前陶泥儿登录态。仅独立 standalone game-chat release 或显式高级自定义模式在隔离配置页维护 External v1 URL/Key,确需诊断的信息进入受控详情或开发模式。
- 素材画布的“素材名称”是用户可编辑的正式输出名称;“资源用途”是 manifest subtype,不向普通用户开放自由文本。新增资源默认“普通游戏美术”,可从普通游戏美术、统一视觉规范、游戏界面原型、核心美术图集四项中选择;精修资源继承源用途且不可改。导出格式继续限定 PNG/JPEG/WebP。工具动作与保存设置分层展示,“保存到项目”在 `1280×800` 和窄容器中都必须完整可见。
### 3.8 现有 Godot 项目
@@ -538,7 +538,7 @@ type ProjectAgentMudPointAttribution = {
### 7.6 素材创作无限画布阶段一至五最终验收
实现状态(2026-08-12):当前产品切片禁用“新增资源”,只从现有资源进入非破坏性编辑。图片进入中央 refine 画布,其他现役类型进入统一派生编辑壳;取消恢复、正式 manifest/revision 实时合并、依赖图重建、dependency/type 双布局协调和三阶段自动定位已经接通。command/event 任意顺序按项目、commit、event 与 revision 去重;低 revision、旧 graph/layout 和失效 focus generation 均不能倒灌。Tauri 远端媒体编辑固定使用 AppData 私有 `editorApi.baseUrl/apiKey` 访问 `/api/external/v1/*`,普通 Launcher、开发工作台和独立 game-chat 的“运行时配置”都可编辑这两个字段;不把 Key 传入 WebView、项目事实、账本、日志或普通错误,素材画布工作区自身不提供凭据输入。重启恢复只继续原 operation,不以新请求、新幂等键或新 operationId 替代结果未知的旧任务。
实现状态(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 保留原资产与原文件、创建新资产,并用规范 `referenceResourceIds` 登记直接血缘;其他类型同样只追加派生文件/asset 或子版本,不覆盖、删除或重排源记录。
@@ -548,15 +548,15 @@ type ProjectAgentMudPointAttribution = {
6. 搜索/筛选隐藏新资源时保留条件,明确提示“新资源已保存,当前筛选条件下不可见”,只通过显式动作清除条件并定位。
7. 现有资源编辑、生成、保存、取消、失败和恢复必须覆盖权威专题 §13 中与当前非破坏性编辑切片对应的验收矩阵;只完成画布 UI 或只完成本地写文件都不能算正式闭环。
8. 自动定位必须分别证明资源已投影、dependency/type 两份布局都 settled 且存在目标位置、目标卡 DOM 已提交;搜索隐藏走显式清除/定位,任何 commit 最多自动聚焦一次。
9. Tauri 远端媒体编辑只使用发布 AppData 私有 External v1 配置;后端按 owner 预扣/退款泥点并返回可轮询 operation。凭据失效、余额不足、平台生成配置故障和远端失败必须在画布内可见;生成状态不得因固定高度或 `overflow` 裁剪而消失,终态后刷新钱包余额。
10. 素材画布生成账本的服务身份固定为 `service-origin-v1`,绑定规范化 External base URL 的服务指纹,不绑定 Developer API Key;确认面板只展示去除路径与凭据的服务 origin。无法用当前 Key 验证的升级前 Key-bound 账本在任何网络动作前显示当前服务 origin 并要求用户确认;确认挑战过期、账本变化或 base URL 变化均失败关闭。确认后 `accepted/running` 只恢复原 GET,`prepared` 只可精确重放冻结的原 POST。全类型资源编辑复用相同显式确认迁移:旧 Key-bound 指纹无法验证时确认前保持零网络动作,确认后已存在 `operationId` 的任务只 GET 原 operation,尚未受理的冻结请求才可复用原幂等键精确 POST。
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` 均不允许归档或重新生成。
13. 派生资产提交必须通过 durable asset transaction journal 串起最终文件、manifest 和 project revision。任一崩溃阶段恢复后只有一份派生文件、一条 manifest asset,revision 精确推进一次;manifest 已写而 revision 未写时只前向补 revision,无法证明的组合进入人工对账。journal 已证明目标 asset、媒体和 target revision 写入后,即使后续合法提交继续推进 manifest/revision,也应按目标 asset 精确身份与 `currentRevision >= targetRevision` 补齐 ledger/draft,不得要求整个 manifest 永远等于历史 after 快照。durable committed 后遗留的 staging 只有在 staging/正式媒体摘要一致,且 manifest 中按 asset ID 或路径唯一命中并与 journal asset 精确相等时才尽力删除;删除失败不降级已提交结果,身份或媒体漂移则保留 staging 并进入对账。
14. generation progress、草稿保存队列、生成/提交回包与延迟 `loadDraft` 必须共用单调 revision 门禁,低 revision 不得覆盖已落地的新草稿。Shift 指针与键盘选择必须与共享 core 一致;单选自身 Shift 不能清空选择,已选多图层普通指针拖动应保持并同步移动选择集。零位移不得产生 undo、documentVersion 或草稿保存。
15. 失败 UI 必须按 `generation / draft-save / asset-commit / recovery / cancellation` 五类 operation 显示可访问名称与安全动作。只有生成失败可以保留参数并“返回修改/重新确认”;草稿、CAS、提交、恢复和取消故障不得出现会发起新生成的按钮。任何非 `editing` 生命周期都必须同时禁用或 inert 背景画布/顶部工具栏,并由生成 handler 再次校验当前状态;modal 遮罩、视觉 disabled 或旧闭包都不能充当业务门禁。
16. 派生子版本 journal 必须冻结 project revision before/after 身份和目标 after 记录。manifest 已有目标子版本但 journal 缺失时失败关闭;旧 journal 缺少 revision 身份且当前 revision 已推进、无法证明是同一事务写入时进入人工对账,不得把现状猜测为已提交。
17. 文本、SVG 与 Agent 回执编辑必须在调用 Provider 前持久化 request-issued;Provider 成功正文必须在解析、格式校验和 staging 之前原子写入私有 durable handoff,并绑定原 operation、请求指纹和内容摘要。issued 后缺少可信 handoff 只能对账,已有可信 handoff 则只消费原正文,两者都不得再次调用 Provider。401/403 只表示当前凭据不能继续授权,不能把已受理 operation 改写为永久对账;修正 Key 后仍只查询原 operation。
17. 文本、SVG 与 Agent 回执编辑必须在调用 Provider 前持久化 request-issued;Provider 成功正文必须在解析、格式校验和 staging 之前原子写入私有 durable handoff,并绑定原 operation、请求指纹和内容摘要。issued 后缺少可信 handoff 只能对账,已有可信 handoff 则只消费原正文,两者都不得再次调用 Provider。普通模式首次 `401` 只允许当前账号 generation 的单飞 refresh,成功后以更高 generation CAS 安装 Token,并使用原正文、原幂等键重试一次;refresh 失败、换号或再次 `401` 时保留原 operation,停止网络。`403` 不触发 refresh。高级 External v1 模式修正 Developer Key 后仍只查询或恢复原 operation。
### 7.7 主站 UI 对齐验收
@@ -0,0 +1,261 @@
# AGC 无人值守游戏生成可靠性收口实施计划
日期:`2026-08-13`
## 1. 目标
本次收口的验收对象不是单个报错点,而是一次完整的用户任务:
> 用户提交一段游戏需求后,不再确认权限、不再补充“继续”、不再手工重试,AGC 在有界时间内自动产出一版可玩的游戏,并完成当前 revision 的静态验证与桌面、移动双视口真实试玩;若外部依赖或环境确实不可恢复,则必须自动收束为带安全原因的明确失败,不能永久停留在运行中、待确认或等待某个专业 Agent。
“产出了一份 HTML”不等于完成。最终完成必须同时满足:
1. 权威入口产物存在、非占位且可解析。
2. 游戏具备真实主要玩法,而不是装饰按钮或固定奖励假体。
3. `playable-web-game-state.v1`、start、primary-action、restart 合同可由真实浏览器执行。
4. 当前 revision 通过 `game.static_smoke`。
5. 当前 revision 通过 desktop 与 mobile `preview.validate`。
6. Runtime、manifest、产物和验证回执的终态一致。
## 2. 当前失败基线
本次复现暴露的不是孤立实现缺陷,而是生成控制面的系统性断链:
- 普通工作台提交使用 `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 的路由、反馈和验收控制,而不是基础模型完全不具备实现能力。
## 3. 范围
### 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`;模型信息不足时先采用目标合同允许的安全默认值。
- 越界路径、任意命令、发布、凭据、系统设置和未列入白名单的外部副作用继续失败关闭,不能为了“无人值守”扩大权限。
3. **可操作的验证诊断与自动修复循环**
- `game.static_smoke` 失败回执向同一 run owner 返回脱敏、结构化的失败码、检查项、项目相对路径和有界说明。
- 公共聊天和跨 owner 回执只展示安全摘要,不泄露绝对路径、命令原始输出、密钥、URL query 或内部 fingerprint。
- 可修复失败必须回到同一 `code-prototype` Run,继续修改后按“脚本解析 -> static smoke -> desktop/mobile preview.validate”顺序重验。
- 相同 revision、相同失败指纹无新 mutation 时不得无限重试;命中停滞门后明确失败。
4. **完成投影与正式产物一致性**
- owner 子任务进入 completed 投影前,逐项验证其声明的正式 artifact 存在、非空,并对 JSON/PNG/HTML 执行已有格式门。
- 只读验证任务不得声明由自己写入的正式文件产物。
- 产物缺失时不能把 manifest 写成 completed;必须产生可修复 blocker 并由主 Run 接管,或在不可恢复时明确 failed。
- 根 Run 只有在当前任务图、正式产物、static smoke 和双视口试玩全部对齐后完成。
5. **Runner 消失后的自动对账**
- 读取 `execution-owner` 时同时核对 boot identity 与进程存活性,不能只相信 JSON 中的 PID。
- owner 已消失且 durable task 仍为可恢复活跃态时,新 Runner 启动/项目 hydration 自动恢复队列;不能永久显示 running。
- 外部副作用结果未知时进入 `needs-reconciliation` 并保留证据,不能盲目重做;纯 Provider、项目内文件和验证动作可以按现有 durable checkpoint 安全续跑。
- 对账与恢复必须幂等,同一 run 不产生重复 child、重复消息或重复付费生成。
6. **有界端到端验收**
- 新增一个从普通 GUI 提交到 game-chat 单主路由的回归入口。
- 用确定性 Provider/工具夹具覆盖“首次 smoke 失败 -> 同主 Run 取得具体诊断 -> 修复 -> smoke 通过 -> 双视口试玩通过 -> completed”。
- 覆盖 owner 中途消失后新 boot 自动续跑,最终只产生一个根终态。
- 任何人工确认、人工澄清、固定专业 DAG 等待、旧 revision 验证复用或 console error 都使 E2E 失败。
### 3.2 本次不做
- 不直接修改用户下载目录中的失败示例;它只作为复现样本。
- 不把直接 Codex 生成的某个三消 HTML固化成平台模板。
- 不恢复已退役的主站玩法入口、公开作品系统或旧创作模板后端。
- 不允许任意 shell、项目外路径写入、自动发布或自动消费未知外部付费能力。
- 不以隐藏错误、自动点击确认或延长预算冒充可靠性修复。
## 4. 目标状态机
```text
accepted
-> route-pending
-> code-prototype-running
-> asset-audit
-> optional-art-delivery
-> implementation
-> syntax/static-validation
-> desktop-mobile-playtest
-> completed
可修复失败:
validation-failed -> owner-repairing -> validation
进程中断:
owner-lost -> recovery-scan -> same-run-resumed
外部结果未知:
owner-lost -> needs-reconciliation -> explicit terminal/recovered
不可恢复或停滞:
any active state -> failed (safe terminal reason)
```
普通无人值守生成路径禁止出现:
```text
waiting-for-confirmation
waiting-for-user-input
fixed-art/audio dependency wait
running with a dead owner and no recovery record
completed with missing artifacts or stale validation
```
## 5. 实施切片
### 切片 A:入口和路由收敛
主要位置:
- `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 和无效“严格审批”承诺。
### 切片 B:无人值守权限与失败反馈
主要位置:
- `runtime_tools/policy.rs`
- `runtime_actions/provider_action_batch.rs`
- `runtime_tools/command_ops.rs`
- `runtime_actions/action_audit.rs`
- `runtime_actions/provider_request_builders.rs`
实施内容:
- 为可信 game-chat autonomous binding 建立窄白名单自动策略。
- 对该来源的确认型动作做“安全自动执行或明确拒绝”二分,不能挂起等待。
- 为 `command.run_limited/game.static_smoke` 定义稳定的 safe detail schema。
- 保证同 owner 的下一轮 Provider context 能读取失败项,公共 UI 仍只拿安全摘要。
- 增加失败指纹与 revision liveness 测试,阻止无 mutation 重复 smoke。
### 切片 C:完成门和恢复对账
主要位置:
- `runtime_protocol/autonomous_completion.rs`
- `runtime_driver/task_start.rs`
- `runtime_driver/recovery_scan.rs`
- `runner/project_owner.rs`
- `runner/recovery.rs`(以实际调用边界为准)
实施内容:
- 将 artifact 合同校验前移到 terminal projection。
- 对完成声明、manifest 状态和文件事实做一次原子/锁内判断。
- owner 丢失时按 durable action 类型判断 same-run resume 或 reconciliation。
- 恢复后重新核对当前 revision,旧 smoke/试玩回执不能过门。
- 缩短无进展窗口;预算只限制时间,不能替代完成门。
### 切片 D:端到端门禁和权威文档
主要位置:
- `apps/ai-game-creator-shell/tests/appSurface.test.ts`
- Runtime Rust 定向测试模块
- `docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`
- `docs/project-memory/shared-memory/development-workflow.md`
- `docs/project-memory/shared-memory/decision-log.md`
- 必要时 `docs/project-memory/shared-memory/pitfalls.md`
实施内容:
- 固定普通 GUI -> game-chat 的来源契约。
- 增加无确认、失败自修复、artifact 真实性和 owner-loss 恢复测试。
- 增加确定性 E2E;真实 Provider smoke 作为现场验收,不把 mock E2E 说成真实生成已经成功。
- 把新的默认路由、无人值守安全边界和复验命令写回权威文档。
## 6. 验收矩阵
| 场景 | 预期结果 |
|---|---|
| 普通工作台提交单 HTML 游戏需求 | source 为 `project-supervisor-game-chat`,只启动 `code-prototype` |
| 素材完整 | 零美术委派、零额外扣费 |
| 缺少规范图和图集 | 先规范图后图集,一次一个 delivery,主 Run 认领后继续 |
| 项目内文件修改、static smoke、preview validate | 在可信 autonomous binding 下不等待人工确认 |
| 请求任意系统命令或项目外写入 | 明确 blocked/failed,不执行,也不挂起等待确认 |
| 首次 JS/static smoke 失败 | 同一 owner 得到结构化失败项,修改后自动重验 |
| 连续同 revision 同错误 | 停滞门阻断重复猜测,明确失败或回到可行动步骤 |
| 子任务回复 completed 但 artifact 缺失 | manifest 不得 completed;产生修复 blocker |
| 最后 mutation 后只存在旧验证 | 根 Run 不得 completed,强制重验当前 revision |
| Runner 在 Provider/文件动作间退出 | 新 boot 幂等恢复同 run,不重复 child/消息 |
| Runner 在未知付费外部动作中退出 | `needs-reconciliation`,不自动重复扣费 |
| 最终完成 | 无 console error;static + desktop/mobile playtest 均属于当前 revision |
## 7. 验证命令
按实际改动范围至少运行:
```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
npm run check:encoding
git diff --check
```
如果完整 Rust suite 受既有 Windows 文件锁影响,必须单独复跑新增 filter,并在交付中如实记录完整门仍不干净;不能用定向通过替代全量结论。
现场真实验收还需要:
1. 使用新的空项目提交一个明确、无需追问的小游戏需求。
2. 全程不点击确认、不发送继续、不手工重试。
3. 记录首个可玩版本耗时、Provider/工具轮数、委派数和失败修复次数。
4. 核对最终 manifest、current revision、static receipt、desktop/mobile playtest receipt 和浏览器 console。
5. 中途强制结束 Runner 一次,重新启动客户端后确认 same-run 自动续跑且没有重复付费动作。
## 8. 完成定义
只有以下条件全部满足,本计划才算实现完成:
- 普通 GUI 默认进入单主快车道。
- 一个确定性端到端夹具证明首次验证失败可由同一主 Run 自动修好并最终完成。
- 一个 owner-loss 夹具证明新 boot 自动恢复且终态唯一。
- 可信无人值守路径不存在普通人工确认或澄清等待。
- completed 前 artifact、当前 revision static smoke 与双视口试玩均被强制复核。
- 相关定向测试、类型检查、编码检查和 diff 检查通过。
- 使用真实 Provider 的空项目 smoke 成功;若现场外部服务不可用,则代码可以提交为“实现完成、真实现场验收未完成”,不得宣称目标已完全达成。
## 9. 实施与验证记录(2026-08-15)
在 `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 项)通过。
## 10. 回滚边界
- 默认路由可回退到原 `project-supervisor-gui`,但不能同时保留两套普通入口形成随机分流。
- 自动权限只由可信 source + root profile + binding fingerprint 共同启用;回滚时删除该窄例外,不修改全局策略默认值。
- 新 safe detail schema 只增加脱敏诊断,不改变原始审计账本的权限边界。
- 恢复逻辑只消费现有 durable task/action/profile/owner 记录,不删除 `.agent`、锁文件或用户产物。
@@ -0,0 +1,247 @@
# AGC 直连 Codex Runtime 迁移实施计划
日期:`2026-08-15`
## 1. 目标
新增一条面向普通 AGC 项目的“直连 Codex Runtime”链路:用户在项目聊天中输入需求,客户端把聊天内容、项目工作区和受限系统提示词直接交给 Codex app-server,由 Codex 自己完成理解、文件修改、命令执行、验证和回复。产品默认只使用 `codex_app_server`,不再让用户选择 Provider / CLI / Supervisor 模式。
本次迁移保留现有 Supervisor、专业 Agent、harness、real-E2E 和旧 Runtime 源码及测试,旧链路只作为开发诊断、回滚和历史数据读取能力,不再作为普通项目聊天的默认执行入口。
## 2. 当前问题证据
- `gameagent-20a04b8f` 首轮生成的入口触发 `ReferenceError: tick is not defined`,同时请求 `assets/art-spritesheet.png` 返回 404,`generic-v1` 的 `primary-action` 没有推进 sequence;Runtime 连续重试至 loop budget exhausted。
- 同一项目重试时,视觉 Agent 访问 `http://localhost:3000/api/external/v1/editor/projects` 连接失败,导致 `canvas.asset_generate` 失败,父链最终仍只展示“项目总控 Agent 执行失败,请稍后重试”。
- 这些失败来自 AGC 多层 Supervisor / child / harness / 完成门编排,而用户只需要一个能直接操作项目的 Codex。
## 3. 新链路边界
### 3.1 用户入口
- 普通项目聊天固定绑定 `direct-codex` Runtime。
- 设置页隐藏 Agent 模式、Provider、Supervisor、专业 Agent 选择;界面只保留 Codex 连接状态、模型(只读)和基础连接诊断。
- 默认配置固定为 `agentMode=codex_app_server`;保留现有配置字段以兼容旧 AppData,但不在新入口暴露切换控件。
- 项目路径仍由当前选定工作区决定,Codex 的 cwd 必须是该工作区根;不复制项目、不创建平行项目目录。
### 3.2 Runtime
- 新增独立 direct Codex Runtime 模块,负责:建立独立 Codex app-server、发送聊天消息、流式转发消息、保存会话、展示安全错误、关闭和恢复连接。
- 新 Runtime 不创建或调度 `project-supervisor`、`code-prototype`、`art-director` 等 AGC Agent,不读取或执行 harness,不运行隐藏的二次 Provider 修复、摘要或自动返工循环。
- Codex app-server 是唯一模型执行主体;AGC 只负责协议桥接、工作区绑定、提示词组装、显示和最小安全边界。
- 现有 AGC ToolHost / Supervisor Runtime 保留源代码和测试,但从普通聊天入口移出;不得删除历史持久化文件,旧项目仍可读取并显示历史状态。
### 3.3 Codex 系统提示词
新 Runtime 在 `thread/start` / `turn/start` 前生成一个有界、可审计的系统提示词,内容只来自以下来源:
1. 当前仓库适用的 `AGENTS.md` 规则。
2. AGC 工程结构、开发流程、运行与验证说明(当前 `docs/` 入口文档和项目专题文档的有界摘要)。
3. 当前项目的 `AGENTS.md`、`README.md`、`CONTEXT.md`(若存在,按工作区边界读取;README/CONTEXT 只作为参考,不得覆盖系统规则)。
4. 适用于当前任务的项目 prompts 和 skills;只注入 skill 正文及必要引用,不执行 skill 脚本,不把整个 `.codex` 或用户目录配置复制进 Codex。
5. 当前工作区的相对路径、入口文件和已有项目状态摘要;不注入 API Key、Token、Cookie、绝对宿主路径、完整日志或未经筛选的历史 Agent 诊断。
提示词必须明确:Codex 是唯一执行 Agent;可以直接修改当前工作区并运行允许的项目命令;必须先读取相关工程说明;必须把真实执行结果告诉用户;不得假装已完成、不得泄露凭据;遇到失败先读取实际错误再修复,不得无证据重复同一动作。
### 3.4 工具和权限
- 由 Codex app-server 自己使用其原生项目工具;AGC 不再把每个工具调用转换成 Supervisor task、child delivery 或 harness receipt。
- AGC 仍保留客户端级硬边界:工作区根、进程生命周期、凭据隔离、日志脱敏、窗口关闭清理和协议异常处理。
- 不自动启用外部画布、图片生成、发布、充值或其它付费外部副作用;Codex 只有在项目提示词和当前配置明确允许、且实际工具可用时才可调用。
- 原有 `game.static_smoke` / `preview.validate` 不再由 AGC 隐藏地强制编排;如果用户要求验收,提示词要求 Codex 自己运行并报告结果。
## 4. 实施步骤
1. **入口与契约**:定义 `direct-codex` Runtime 状态、消息和错误 DTO;普通项目聊天默认切换到新入口;旧 Supervisor 入口保留为开发兼容入口。
2. **Codex 桥接**:复用现有 app-server 进程隔离、临时 `CODEX_HOME`、认证桥接和进程清理能力,新增只发送用户消息 + 系统提示词的 direct turn API;拒绝 server→client 未声明请求和非消息原生 item。
3. **提示词构建器**:按工作区边界读取 AGENTS / docs / prompts / skills,做大小、敏感信息和路径脱敏门禁,记录提示词来源 fingerprint,不记录正文。
4. **前端收敛**:隐藏模式选择和 Supervisor/专业 Agent 展示,聊天区直接显示 Codex 流式消息、执行状态和可读失败原因;保留设置保存 Toast。
5. **恢复与持久化**:direct session/run 使用独立 source 和稳定 messageId;断线恢复只恢复同一 Codex thread,不重新执行未知副作用;旧 Supervisor 任务不自动迁移成 direct turn。
6. **失败可见性**:把 Codex 的安全错误分类为连接、鉴权、上下文、工具执行、命令验证和进程退出,并在 UI 展示具体可操作原因;禁止继续只显示“请稍后重试”。
7. **文档与回滚**:同步技术方案、开发说明和运行配置说明,保留一个开发开关让维护人员读取旧 Runtime,但产品默认不可见。
## 5. 验收
- `npm --prefix apps/ai-game-creator-shell run typecheck` 通过。
- 新 Runtime 单测覆盖:系统提示词来源/敏感信息过滤、工作区 cwd、Codex turn 透传、流式消息幂等、错误映射、断线恢复和进程清理。
- fake app-server 协议测试证明:一次用户输入只产生一个 direct turn;无 Supervisor/child/harness 调度;API Key 不进入 argv、日志或提示词正文;server 请求被拒绝;native tool item 按协议处理。
- AppSurface 测试证明:模式选择不可见、默认 Codex app-server、普通聊天消息直达 Codex、失败原因可见、旧项目历史仍可读。
- `npm run check:encoding` 与 `git diff --check` 通过。
- 显式 opt-in 的真实 Codex app-server smoke:在隔离项目中完成一次聊天、一次真实文件修改和一次用户可见回复;单独报告 Provider / Codex 网络与本机认证结果,不用旧 harness self-test 冒充。
## 6. 不做事项和回滚
- 不删除 Supervisor、专业 Agent、harness、真实 E2E 或旧 Runtime 源码;不批量迁移旧 `.agent` 状态。
- 不把 Codex 原生工具能力无条件扩大为 AGC 的全局权限;安全边界仍由进程、工作区和配置隔离保证。
- 新 Runtime 通过独立 source / feature flag 回滚到旧入口;回滚不重写用户项目文件、不删除 `.agent`、不重放未知外部动作。
## 7. 当前落地状态(2026-08-15)
- 已新增 `direct_runtime` Tauri 链路:普通聊天直接调用 Codex app-server,cwd 绑定当前项目,使用 workspace-write 沙箱;旧 Supervisor/harness 源码未删除。
- 已新增有界系统提示词构建器,注入项目规则、工程说明和执行约束,并屏蔽凭据与宿主私密信息。
- 设置页已隐藏模式选择,保存配置时固定 `agentMode=codex_app_server`。
- 已通过 `cargo check`、direct Runtime 单测、AGC typecheck、配置契约检查和 `git diff --check`。
- 修复了 direct app-server 在隔离 `CODEX_HOME` 下的无人值守写入阻断:direct workspace 使用 `approvalPolicy=on-request`,AGC 对受限 file-change 请求自动接受;隔离 Codex 配置仅将当前工作区登记为 trusted,旧 Runtime 仍保持 `approvalPolicy=never`。
- direct workspace 同时禁用 `shell_tool` / `unified_exec`,避免模型在无人审批策略下退回到被系统拒绝的 PowerShell/Python 命令;原生 file-change 仍由 Codex app-server 执行。
- 新增仅在 `GENARRATIVE_AGC_DIRECT_DEBUG` 显式开启时输出的脱敏 app-server 事件/stderr 诊断;默认不输出正文或凭据,且覆盖 Bearer/API key/token 脱敏测试。
- 已用当前 AGC Rust 二进制真实验收:在 `D:\Documents\Genarrative GameAgent\client-direct-codex-20260815` 先创建并删除测试 marker,再由 direct turn 实际写入 `game/index.html`、`game/style.css`、`game/game.js`;`node --check game/game.js` 通过。
- 已用本地静态 HTTP 服务 + Playwright 打开生成结果:页面标题、Canvas、订单/金币/等级 UI 正常,点击棋盘得到真实“不消除”反馈,点击“整理货架”后金币从 `40` 变为 `20`。仅 favicon 404,不影响游戏入口。
- 首页“自动创建项目”现已把首条完整需求交给 `chat_with_game_creator_direct_codex`,不再创建 Supervisor Session、不再启动 `start_game_creator_supervisor_runtime_task`;进入 direct 项目时也不再自动调用 `resume_game_creator_agent_runtime_tasks`,避免新项目显示无来源的 Resume。
- AppSurface 定向测试锁定“自动建项目只发一次 direct Codex、显示 direct 回复、Supervisor start=0、Runtime resume=0”,并已实际通过。
- 项目开发页中的 direct 组件现在会先 hydrate 外层已选工作区;已有项目不会在首条消息时误创建第二个自动目录。自动建项目或 direct Codex 连接失败后立即停在可见错误,不再落回旧 Supervisor Runtime。
- 系统提示词会按工作区边界加载有界、脱敏的 `prompts` 与 `SKILL.md` 摘要,并附带内置 direct-game-creation skill;不会把 API Key、Cookie、auth.json、`.env` 或宿主绝对路径带入 Codex 上下文。Direct turn 成功后会刷新 AGC manifest 并尝试启动客户端本地预览,预览失败会把具体原因写入聊天和状态栏。
- 系统提示词现作为 Codex `thread/start.baseInstructions` 发送,用户消息单独作为 `turn/start.input`,不再把 AGC 规则伪装成用户文本;仓库级 `AGENTS.md` 与 AGC 技术方案以编译期有界摘要随客户端提供,脱离源码 checkout 的项目也能获得工程约束。
- direct Codex thread 按项目复用同一个进程内 ephemeral session,连续消息保留 Codex 上下文;客户端退出时统一关闭 direct app-server,连接中断后下一次消息会淘汰关闭节点并重新建立连接。
- Codex app-server 的 `usage-limit`、鉴权、上下文超限、沙箱失败、终态未知等稳定错误现在映射为可行动的中文提示;工作台 direct 页面隐藏 Supervisor/专业 Agent 状态卡,保留单一 Codex 状态和真实错误。
- 运行页已直接移除“测试切片”控制行及其本地播放/序号状态和样式,只保留游戏运行画面、信息展示与数值微调;AppSurface 合同同时锁定该控件不再渲染、对应 CSS 不再存在。
- 当前 direct 产物是多文件入口,而历史 `validate_game_html_smoke` 仍按单文件内联 HTML 契约检查;本次 direct 链路不隐藏触发该旧门禁,若要把多文件产物纳入旧门禁需另行设计读取工作区文件的验证契约。
## 8. 陶泥儿美术闭环与资源分类收口(2026-08-16)
### 问题
- 直连入口此前仅根据用户输入中的少量“游戏 + 创建”关键词决定是否调用陶泥儿生图;“做个三消模拟经营”等正常创作输入会绕过该判断,导致只有 HTML / CSS / JS 的项目仍被投影为已完成。
- Codex app-server 没有陶泥儿平台的生图工具;单靠泛化系统提示词无法让它自行调用平台生成、下载、登记并回写美术资源。
- 资源画布把 `text/html`、`text/css` 和 `text/javascript` 统一归为“文档”,混淆了玩法说明与可执行游戏代码。
### 现行契约
1. 直连 AGC 项目首次生成、或当前项目还没有已登记陶泥儿美术时,客户端按标准三阶段优先调用陶泥儿平台:先生成统一规范图 `assets/art-spec.png`,再以该规范图为参考生成 16:9 场景背景图 `assets/direct-game-background.png`,最后以同一规范图生成透明主图集 `assets/art-spritesheet.png`。`sliceLayout=grid-2x2` 与四份受合同保护切片继续作为标准美术包的推荐路径;不得把客户端猜测裁剪或自由连通域结果冒充平台切片。平台返回的主图片必须以 `source.kind=canvas` 登记,资源身份、图片可解码性和同 Canvas 项目关系继续失败关闭;图集源图可信可用但透明化或切片后处理缺失时,按第 13 节安全复用源图并继续同一 Codex thread,不因固定切片缺失终止整个游戏。
2. 客户端把实际可用的规范图、背景图、主图集与切片相对路径、来源和用途作为不可变执行上下文提供给唯一 Codex。规范图作为风格根,其余平台素材应进入核心可玩画面;Codex 可以根据游戏结构选择合理的图集、切片、Canvas 或 WebGL 组织方式,不要求固定文件组合、固定 `drawImage` 次数或单一代码形态。平台素材不能只在回复中声明使用或只显示为旁侧缩略图,核心视觉也不能退化为 emoji、纯 CSS 或纯色占位图。
3. 回合结束时客户端只确定性复核安全与最低来源边界:可信平台图片、身份与同 Canvas 关系成立,`game/index.html` 存在,游戏源码至少引用一份已登记陶泥儿图片。随后由受限 Chromium 对 desktop/mobile 做真实运行、截图、异常、交互及 Canvas/WebGL 图片渲染观察,并把缺口回灌同一 Codex thread 有界整改。固定四切片、固定文件名和固定 `drawImage` 次数不再阻断完成;最终仍未观察到平台素材进入任一视口核心渲染时才拒绝登记版本。详细契约以第 13 节为准。
4. 资源画布增加“游戏代码”分区。HTML、CSS、JavaScript 和其它可执行源码进入该分区;玩法说明、配置和 Agent 文本回执仍归“文档”。已有资源布局若没有代码分区位置,将由现有布局 reconcile 自动补位。
5. 产品界面只展示“陶泥儿”“智能创作”等产品术语;Codex app-server 仅保留为内部执行实现和开发诊断名称,不在普通项目聊天、首页创建状态或设置说明中直接暴露。
6. 每次直连回合在游戏代码复核与登记成功后,必须在项目写锁内推进一次 durable project revision,并以该 revision 创建首个 `initial-*` 或后续 `agent-*` 正式版本。禁止修改 manifest 后沿用旧 revision;外层工作台会把同 revision 的不同 manifest 判为冲突并拒绝投影,表现为磁盘已有游戏代码和版本、客户端仍显示 0 项。
7. direct app-server 禁用 shell / unified exec 时仍必须能可靠修改已有游戏。每轮系统提示词在大段仓库文档之前注入当前 `game/index.html`、`game/style.css`、`game/game.js` 的有界脱敏快照,使 Codex 的原生 file-change 能基于真实旧内容生成补丁;不得退化为猜测变量名的盲补丁。回合前后以三个代码文件的内容指纹判断是否发生真实修改;无修改且 manifest 已同步的回合不得推进 revision 或伪造新项目版本。
### 验收
- Rust 单测覆盖:可信完整图集缺少固定切片仍可进入 Codex;只有规范图和背景图但历史图集不可安全恢复时不得重复发起付费生成;缺可信平台图片、来源身份不成立、PNG 不可解码或源码完全没有平台素材引用时继续拒绝完成。浏览器证据测试必须区分旁侧 `<img>` 与 Canvas/WebGL 实际渲染,并证明 desktop/mobile 任一视口缺少核心素材观察都会回灌同 thread 整改。
- 资源投影与 AppSurface 测试覆盖:`game/index.html`、`game/style.css`、`game/game.js` 显示于“游戏代码”,不再显示于“文档”。
- 连续两次直连回合必须保留同一批游戏代码资产 ID,project revision 单调推进,并形成 `initial-* -> agent-*` 的父子版本链;外层资源管理在新 revision 到达后显示游戏代码和项目版本,不能停留在生成前快照。
- 已有项目修改测试必须证明系统提示词包含有界当前游戏源码、敏感行被过滤,基于该上下文的 file-change 可以命中;Codex 明确未修改文件时,revision 与版本数量保持不变。
- 真实客户端验收必须在新建空项目中看到实际成功生成或安全恢复的 `source.kind=canvas` PNG 位于“美术资源”,代码文件位于“游戏代码”,并在 desktop/mobile 运行画面的核心 Canvas/WebGL 路径中观察到至少一份已登记陶泥儿素材;标准四切片存在时应优先使用,但不存在时不能伪造,也不能据此单独判定游戏失败。
## 9. 直连创作阶段反馈与资源首屏预览(2026-08-17)
### 问题
- 直连回合把陶泥儿美术生成、Codex 文件修改、manifest/版本登记放在一个 Tauri command 内。前端只能在 command resolve 后得到最终回复,用户会在数分钟内只看到笼统等待状态,随后突然出现运行画面。
- 资源卡原本主要等待嵌套资源画布的 `IntersectionObserver` 通知。该嵌套滚动容器在首次进入时不稳定,失败后的可重试读取又不会因可见性回调自动重试,导致用户必须先进入详情才能看到卡片预览。
### 现行契约
1. direct Runtime 在不输出内部路径、Provider 或工具细节的前提下,复用 `game-creator-agent-progress` 发送安全的公开阶段:需求已接收、检查陶泥儿美术包、规范图、背景图、图集与切片、代码生成、项目版本登记和预览刷新。普通直连工作台按当前项目路径接收并即时显示该阶段;命令失败仍沿用现有安全错误映射,不把阶段进度伪装成已完成。
2. 资源管理首次进入时主动请求最多 12 个可预览的非音频、非版本、非占位资源。请求仍服从三并发、96 项队列、48 项/64 MiB 缓存和原有身份失效规则;后续资源继续通过 `IntersectionObserver` 按滚动加载,详情与播放请求可提升优先级。首屏预取不改变权限策略,读取被拒绝时卡片必须保留安全错误状态。
3. 验收必须同时证明:提交直连需求后立即可见“已提交需求,正在准备智能创作”,收到阶段事件后显示对应用户文案;真实普通 AGC 工作台首次打开既有项目时,无需进入详情即可显示游戏代码摘要以及陶泥儿规范图、场景背景图和核心图集的缩略图。
## 10. 平台已完成图集结果回收修复(2026-08-17)
### 现场证据
- 空项目的规范图与场景背景图已通过当前平台登录态生成、登记;核心 `grid-2x2` 图集任务在平台侧进入完成态后,客户端显示“美术包生成失败”。
- 失败文本表明客户端收到了 `completed`,却没有拿到可消费的 `result`。这不是未登录、未配置平台生图或背景图失败,也不能通过重新提交图集来处理,否则会造成重复扣点。
### 修复计划
1. 核对平台账号模式的 `/api/runtime/external-generation/jobs/{operationId}` 完成响应、通用外部 API 完成响应和持久化 `result_payload_json` 的真实包络;统一把完成结果映射为客户端可消费的 `result`,保持 `grid-2x2`、四类切片、资源和资产身份合同不变。
2. 对已进入 `accepted/running/completed` 的本地图集账本只轮询并恢复同一个远端任务;仅 `prepared` 且未取得接受凭证时才以原幂等键重放。任何“结果暂不可读”都保留账本并进入可恢复状态,不发起新的付费请求。
3. 后端增加 completed 队列结果的契约测试;原生端增加平台 completed 包络的回收、四切片严格验收和不重提回归;前端继续将内部错误转换为安全、可行动的中文提示。
4. 先对现有失败项目执行同一任务的状态恢复,确认不会产生新的生成提交;再用当前客户端新建项目跑完整规范图、背景图、图集、四切片、代码、版本与预览闭环。真实验收未通过前,不把本次修复标记为完成。
## 11. 直连聊天记录持久化(2026-08-17)
### 问题
- 普通直连创作会把用户输入、最终回复和失败提示都标记为运行时消息;项目对话保存器此前统一跳过这类消息。
- 项目重新打开时已经会读取 `.agent/conversations/project.jsonl`,但直连问答从未写入该文件,因此客户端重启后只剩默认欢迎语。
### 现行契约
1. 每次直连提交生成一个仅用于项目对话的稳定回合标识,并把最终用户消息与最终助手消息分别写为 `direct-codex:<turn>:user`、`direct-codex:<turn>:assistant`。保存命令继续以 `messageId` 幂等,重试不得产生重复记录。
2. 仅上述 role 与 ID 匹配的最终直连问答可以穿过运行时消息过滤并写入项目主对话;阶段进度、预览启动状态、流式中间内容及无稳定回合 ID 的运行时提示仍只保留在当前页面。
3. 直连失败时,只保存已通过 `projectRuntimeVisibleError(...)` 转换的安全中文提示,禁止把 app-server、Provider、路径、认证或工具原始错误写入对话文件。
4. 项目重新打开时继续复用既有主对话读取与 hydration。恢复聊天记录不代表 Codex app-server 的进程内 thread 能跨客户端恢复;下一条消息仍按现有直连会话策略发起。
### 验收
- AppSurface 覆盖成功与失败回合:用户消息和最终回复各保存一次、共享同一 turn 的不同 role ID;失败记录不含原始内部错误。
- 重载同一项目时,`read_local_conversation` 返回已保存记录,聊天区恢复展示,不再次提交直连请求。
- 真实桌面端验收:在同一项目完成一条直连问答,关闭并重新打开当前客户端后,用户输入和最终可见回复仍在项目聊天中。
### 并发写入约束
直连消息保存与首轮陶泥儿平台美术生成可能同时触发项目写锁。两者均为短时本地写入,直连美术生成的恢复锁、提交锁以及生成产物版本登记必须使用现有的有界等待锁;不能因为聊天记录保存占用项目锁的瞬时竞态而终止整轮游戏生成。
## 12. 顶部播放入口(2026-08-17)
### 产品边界
1. 项目工作台顶部提供唯一面向普通用户的“播放”按钮;运行空态不再引导用户输入 `/run` 或 `/preview`。
2. 播放按钮只负责进入运行视图并排入现有 `game.run_local` 确认流程,不新增一套预览启动实现,也不直接拼接或打开外部 URL。
3. 现有聊天命令解析暂时保留为兼容入口和回归测试依据,但不再作为工作台产品引导。
### 运行合同
- 点击播放后仍需经过项目权限确认。
- 确认后继续执行 `game.static_smoke`、`start_local_game_preview`、预览状态同步、manifest / run trace 刷新和 loopback iframe 安全校验。
- 没有可运行原型时按钮禁用;运行视图仍由现有 `runAvailable` 判定控制。
### 验收
- 可运行项目的工作台顶部显示“播放”,点击后进入运行视图并排入 `game.run_local`。
- 没有可运行原型时“播放”禁用。
- 运行空态文案只提示点击顶部播放按钮,不出现 `/run` 或 `/preview`。
## 13. 直连 Codex 的 LLM 自主试玩验收与柔性美术合同(2026-08-17)
### 13.1 分层边界
直连 Runtime 只把安全、权限、来源和不可逆副作用留在确定性门禁内:项目工作区与权限边界、凭据隔离、平台生成请求的幂等账本与未知结果恢复、持久文件事务、HTTP 完成包基本结构、图片下载/PNG 解码/可见像素、`source.kind=canvas`、资源身份与同 Canvas 项目关系。上述条件不满足时必须失败关闭,不能交给模型猜测或覆盖。
`grid-2x2`、固定四张切片、固定切片文件名、固定 `drawImage` 次数以及某一种 Canvas 代码形态不再是所有游戏的完成阻断合同。它们保留为“陶泥儿标准美术包”的推荐路径:平台返回完整透明主图集但切片后处理缺失时,仍可继续代码生成;已有切片可以被 Codex 优先使用,但客户端不得伪造切片或把缺失切片标记为已存在。若项目已有同一画布、身份可信且可解码的规范图和背景图,但历史核心图集无法恢复,客户端必须直接复用这两张素材继续 Codex 代码生成与试玩,不重新发起图集付费生成,也不为只读恢复失败阻断本轮。只有已用平台图片本身无法下载、解码、无可见像素、来源身份不可信或最终没有任何真实平台素材引用时才阻断。
### 13.2 同一 Codex thread 的有界自主验收
每个直连回合按以下最多三次 Codex turn 执行,不恢复 Supervisor、专业 Agent 或 harness:
1. 首轮由 Codex 生成或修改当前工作区文件。
2. 客户端先复核最低完成证明:`game/index.html` 是否存在,以及源码是否引用至少一个已登记的平台图片。该证明不满足时,不在版本登记阶段直接报错;客户端把脱敏的具体缺口回灌给同一 Codex thread,待其修复后才启动受限本地预览。该回灌不允许 Codex 修改 manifest、伪造素材或覆盖来源身份。
3. 最低证明满足后,客户端启动受限本地预览,使用真实 Chromium 在 desktop 和 mobile 两个固定视口采集页面加载、Canvas、控制台/异常、失败请求、可见文本、截图和有限的真实交互探针;direct 链路不使用 `BrowserPlaytestScenario::GenericV1` 等固定玩法状态机,试玩结果只作为模型判断证据。
4. 客户端把脱敏、结构化的浏览器证据及仍存在的最低完成证明缺口发送给同一 Codex thread。Codex 必须读取实际文件和证据,发现问题就直接修改并说明修复;若文件发生变化,客户端重新试玩。最新结果仍失败时最多再发送一次明确整改反馈,之后安全失败,不登记完成版本。
最终回复必须包含:检查过的文件、真实启动/试玩动作、desktop/mobile 观察、陶泥儿平台素材如何被实际使用、已修复问题和剩余风险。客户端只展示摘要,不把绝对路径、Token、签名 URL、Provider 原文或内部队列信息传给用户。
### 13.3 最低使用证明与完成条件
客户端只要求 `game/index.html` 存在,并能证明至少一个已登记、真实、平台来源的图片路径被游戏源码引用;不统计 `drawImage` 次数,不要求四类切片或固定代码形态。该最低证明失败必须先进入同 thread 有界整改,而不是在浏览器成功后才由版本登记阶段突然终止;若最终仍失败,才拒绝登记。
受限 Chromium 还会对已登记平台图片采集运行时使用观察:图片是否在真实 Canvas / WebGL 渲染调用中出现,以及是否只作为页面可见图片出现。该观察不依赖固定切片、固定文件名、特定棋盘结构或字符串计数,也不替代 Codex 对截图和玩法质量的判断;但若只观察到旁侧预览、未观察到核心渲染路径,客户端必须把这一明确缺口回灌给同一 Codex thread 要求整改,不能把“源码引用”或“旁侧缩略图”表述为素材已进入玩法。浏览器基础设施失败、页面无法加载、Canvas 完全不可见或出现未处理异常仍作为安全失败证据;其它质量问题交给同 thread 有界整改。
### 13.4 验收要求
- 定向 Rust 测试覆盖:完整主图集无切片可通过;来源/身份/PNG 解码/同 Canvas 约束仍失败关闭;源码合理引用任一平台素材可登记;无平台素材引用不能完成;系统提示词包含自主试玩与结构化报告要求。
- fake app-server 测试覆盖:连续 direct turn 复用同一 thread,浏览器证据和整改反馈形成后续 `turn/start`,无 Supervisor/child/harness。
- 真实客户端验收覆盖:当前 checkout 的 AGC 新建或打开直连项目,真实本地预览在 desktop/mobile 运行并至少执行一次可见交互;截图与结构化证据写入项目 `.agent/runtime` 证据目录;完成回复展示可读验收摘要。
### 13.5 透明后处理失败时的图集源图安全复用(2026-08-18)
当陶泥儿 `art-spritesheet` 的远端生成已完成、源 PNG 已落在同一画布,但透明化或切片后处理失败时,直连 Runtime 可以在不重新提交、不重复扣费的前提下只读恢复该源图。恢复仅适用于规范图唯一绑定的核心图集:候选必须属于当前 Canvas、生成路由和种类匹配,且要么 `sourceResourceId` 精确指向当前规范图,要么只包含当前规范图的一项不可变参考。多个候选、外部参考、多参考、不可下载、非 PNG、透明或无可见像素一律失败关闭。
恢复成功后将完整图集作为可信平台素材继续交给同一 Codex thread;客户端不得伪造切片、不得把未生成的切片登记为存在。源图已确认由平台完成且只读恢复成功后,客户端清理同一 `agentId/runId` 的已完成生成账本;只读恢复失败、身份不唯一或结果仍未知时继续保留账本供对账,绝不删除后重发。若没有可安全恢复的历史图集、但规范图和背景图已经可信可用,直连生成可继续使用这两张素材并完成上述 LLM 自主验收,不再为只读恢复失败重发图集请求。
### 13.6 隔离验收进程的陶泥儿开发者凭据(2026-08-17)
真实 CLI / Chromium 验收进程不能依赖已打开 GUI 的内存登录态,也不能复制 GUI 的 Cookie、access token 或 Runner 会话。直连 Runtime 首先只读取当前用户私有的 `~/.config/genarrative/external-editor-api.json`:其中保存一次性显示过的开发者 API Key,和可选的受信任陶泥儿 API origin;仓库、项目目录、`game-creator.config.json`、诊断、命令行参数和 Codex 系统提示词均不得出现该 Key。
当私有 Key 缺失但当前 GUI 已有陶泥儿账号会话时,客户端可按用户授权仅调用受保护的 `/api/profile/api-keys` 创建一个名称固定的本机直连 Key,并以原子写入和当前用户私有权限保存到上述文件。创建后,direct Runtime 的美术准备、只读图集恢复、素材换签、生成提交和轮询统一使用 External v1 路由及该 Key;不得混用账号 JWT 路由。若 Key 缺失且没有 GUI 会话,必须给出“先在客户端登录一次以创建本机开发者 Key”的可行动错误,而不是误报普通试玩失败。
开发者 Key 创建是唯一允许借用 GUI 登录态的受控设置动作;平台图像生成继续由既有幂等账本、同一 idempotency key 和未知结果恢复保护。真实验收必须至少用一个不带 GUI 内存登录态的新进程恢复同一项目,以证明该私钥链路可独立生成、下载并完成 Chromium desktop/mobile 试玩。
### 13.7 首次私钥引导的本机安全存储前置与可行动失败说明(2026-08-17)
首次真实客户端验收表明,失败不是 GUI 登录态未同步:首次本机开发者凭据创建已经拿到远端响应,但 Windows 新建的私有目录 owner 是 `Administrators`,随后 TokenUser 私有 DACL 校验拒绝落盘。一次性显示的远端凭据无法恢复,旧顺序会留下孤儿凭据,因此不能用刷新登录态或自动重放掩盖。
1. 缺失本机开发者凭据时,客户端必须先准备并验证精确的私有存储目录,再请求远端创建凭据。仅当该精确目录由当前调用以原子创建成功时,才允许初始化 owner 和私有 DACL 为当前 TokenUser;已有目录一律按严格 owner/DACL 校验,owner 不匹配时失败关闭,不自动接管、改 ACL、覆盖或删除。
2. 若本机目录预检失败,客户端返回稳定的“本机开发者凭据存储目录未安全初始化;未创建远端凭据”分类,不请求远端创建接口、不发起美术生成、不写 operation 或账本,也不刷新登录态或自动重试。
3. 远端响应后原子写入仍可能因并发或磁盘故障失败;该极窄路径必须单独分类为“凭据已创建但未能安全保存”,提示用户在账户开发者凭据页面撤销后再试,不能自动创建第二把凭据。诊断和正式 UI 只展示上述安全摘要与恢复建议,不包含 access token、开发者凭据、响应正文、绝对路径或签名 URL。
4. 验收先在当前失败项目上恢复:对遗留的空且 owner 不匹配目录做可恢复隔离后,再复用同一项目发送“继续完成此前三消游戏”。成功标准包括本机私钥存在但不读取其内容、平台素材与版本登记完成、desktop/mobile Chromium 试玩证据和隔离进程恢复;此前已创建但无法恢复的远端孤儿凭据作为明确剩余风险,绝不自动撤销。
@@ -0,0 +1,20 @@
# AGC 开发态单窗口启动收口计划
日期:`2026-08-17`
## 目标
`npm run agc` 启动时只打开标题为“陶泥儿”的正式客户端窗口,不再自动额外打开 Agent 聊天开发窗口。
## 范围与边界
- 删除 Tauri setup 中仅 debug 生效的自动 developer 窗口调用,以及已无调用方的 developer 窗口构造代码与专属路由测试。
- 保留普通 `client` 窗口、`--game-chat` 独立入口和显式 `supervisor-chat` 开发调试入口。
- 不删除前端 `?agent-chat` 调试页面;它不再是 `npm run agc` 的自动入口。
- 同步原生壳静态门禁、技术方案和长期决策记录,防止自动双窗口回归。
## 验收
1. Tauri 定向 Rust 测试和前端类型检查通过。
2. 配置门禁、编码检查和差异检查通过。
3. 实际运行 `npm run agc` 后,仅存在标题为“陶泥儿”的客户端窗口,不存在 Agent 聊天开发窗口。
+118 -15
View File
@@ -6,6 +6,28 @@
- 决策:`style="pixelArt"` 与手动 `POST /api/editor/images/pixel-art-snaps` 仍共用 `snap_pixel_art_with_grid_policy`。检测、切线、采样、Alpha、strict 拒兜底不变。`resample` 之后、`encode_png` 之前,用单一整数 N 做 nearest 放大:`N*` 为 `(C·W + R·H) / (C² + R²)`,在 `floor` / `ceil`(小于 1 当 1)中取距离平方更小者,并列取较小 N;超单边 `10000` 或总像素 `8294400` 则降 N,最低 `N=1`。只持久化这一张 PNG。手动算法指纹升为 `perfect-pixel-v3`。
- 不做:改 walker、透明补边、裁切、横纵不同倍率、Lanczos / bilinear、另存逻辑图、前端框缩放、失败路径、新测试。
- 关联文档:`docs/technical/【前端架构】图片画布编辑器MVP接入方案-2026-06-11.md`、`docs/【编辑器】画板角色形象生成入口设计-2026-06-15.md`、`docs/【编辑器】画板图标素材生成入口设计-2026-06-15.md`、`docs/【编辑器】图片画布结构化持久化与迁移回滚方案-2026-07-19.md`、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`。
## 2026-08-15 AGC game-chat 主代码 Run 接管直属美术 delivery
- 背景:真实 `gpt-5.6-sol / max` 验收中,`art-director` 失败后已形成 `ready + needs-repair` delivery,但认领、合同读取、claim observation 和完成 blocker 均硬编码为 Supervisor-only;实际直属父 Run `code-prototype` 无法消费回执,随后又发起 29 次 Provider 请求。
- 决策:保留原 Supervisor 能力,并把 delivery 管理权限窄扩展给身份链完整的当前可信 game-chat `code-prototype` 父 Run。Runtime 在存在 ready 回执时确定性执行 `agent.run_status(scope=self)`;claim 未完整 Observed 前不请求 Provider;普通失败或不合法 marker 认领后立即终止。完整 `game-chat-safe-default-repair.v1` marker 不再交回 Provider 决策,而是由 Runtime 按原 Agent、原合同和原 delegationId 直接生成唯一一层 `agent.delegate`;repairRequired 状态的重复 route/read/query 由 liveness 门拒绝。
- 安全边界:权限必须同时证明 game-chat 根 source/profile、root/parent/child task、父 binding fingerprint、delivery parent/session/run、delegationId 和目标 Agent;Agent ID、任务正文或错误关键词不能授权。身份损坏时 capability、run status 和 completion gate 全部失败关闭;父 task/chain 无法证明但仍有活跃或已认领 delivery 时也必须 blocked,不能静默当作“不适用”。Suppressed 且未形成 child 的失败前置记录不再参与 capability、claim 或 completion barrier,以保留同 action reopen / 新 action 重试语义。`code-prototype` 只能管理内部 delivery,正式用户 assistant 与根 completed 投影仍只允许根 `project-supervisor`。
- 验证方式:覆盖合法认领与合同精确读取、错误 Agent/Run/delegation 拒绝、delivery 身份篡改阻断、唯一安全默认返工、普通失败零后续 Provider lifecycle,以及新的真实 Provider 空项目轮次。顺带收紧 `validate_executable_inline_javascript_syntax`:正文游离 `<` 不再吞掉后续 `<script>`,未闭合或非标签状 `<` 继续扫描,避免后置脚本被静默跳过语法校验。
- 关联文档:`docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md`、`docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`。
## 2026-08-14 AGC 将 reasoningEffort=max 作为独立强度贯通
- 背景:`gpt-5.6-sol / max` 真实验收预检发现,AGC 与 `platform-llm` 只接受到 `high`;同时 canonical Agent 会先用角色默认强度覆盖全局值,空 `agentLlm` 不能证明实际请求使用 `max`。
- 决策:新增独立 `max` 枚举和 wire 值,贯通配置、Provider 适配、Codex 映射、请求指纹、前端类型与配置检查;禁止把 `max` 静默映射成 `high` 或 `x-high`。本轮真实验收使用 `agentMode=provider`,并为 Supervisor、主代码 Agent 和两个条件美术 Agent 显式设置 `max` 覆盖。
- 验证方式:定向验证配置解析、Responses 请求 JSON、Provider 双向适配和 Codex effort;真实 E2E 报告必须同时绑定 `providerModel=gpt-5.6-sol`、`providerReasoningEffort=max`、`providerApiKind=openai_responses` 与 endpoint SHA-256。
- 关联文档:`docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`。
## 2026-08-14 首份结构化计划完整替换 legacy 计划脚手架
- 背景:真实 Luna 无人值守轮次在 revision 2 的 `game.static_smoke` 失败后,于同一 `code-prototype` Run 成功 patch 到 revision 3,但没有重新验证。取证确认 smoke 失败发生在 `planRevision=0` 阶段,Runtime 先把 legacy 活动步骤标为 `failed`;随后首份结构化 `planUpdate` 错误保留该 legacy 终态,game-chat 快车道因“结构化计划含 failed 步骤”在读取当前 revision 门禁前终止。
- 决策:`planRevision=0 -> 1` 是 legacy 到 structured 的一次性迁移边界。第一次有效结构化更新完整替换 legacy `plan / planSteps / activePlanStepIndex`,不继承任何 legacy `completed / failed` 脚手架步骤;只有函数入口处已经存在结构化计划时,才合并并保护历史终态。
- 安全边界:已建立结构化计划后的 `completed / failed` 单调与不可改写语义保持不变,普通失败继续 fail-closed;不新增 smoke receipt 特判恢复通道,不放宽项目 revision、static smoke、desktop/mobile 试玩、身份绑定或最终完成门。
- 验证方式:覆盖 legacy failed 被首份结构化计划替换、structured failed 仍不可改写,以及 `smoke failed -> structured repair plan -> same-run patch -> current revision smoke recheck`;运行 `structured_plan_`、`game_chat_` 分组和串行 Rust 全量,并以新的独立 `gpt-5.6-sol` / `max` 真实 Provider 空项目轮次取得完整最终证据。
- 关联文档:`docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`。
## 2026-08-12 Repository checks 采用 CI 与本地共用的单一门禁入口
@@ -72,18 +94,17 @@
- 终态与队列:资源编辑账本正式区分可继续阶段、`reconciliation-required`、`remote-failed` 和 `archived`。远端明确失败只保存稳定分类与终态时间,不得再 POST、轮询或重新扣费;只有该终态能由用户显式归档并移出活动恢复队列,归档保留账本且不伪装 `committed`。结果未知和需对账项继续失败关闭。
- 本地提交:派生 asset 提交新增 `game-creator-resource-edit-asset-transaction.v1` durable journal,冻结 operation/project/source、最终路径/摘要、manifest before/after 和 project revision before/after,以 `prepared -> media-installed -> manifest-written -> revision-written -> committed` 推进。只有文件、manifest、revision 与 journal 全部回读相等才提交 ledger;manifest after/revision before 只前向补 revision,无法证明的组合进入对账,不做猜测回滚。durable committed 后遗留 staging 只有在 staging 与正式媒体摘要一致、manifest 按 asset ID 或路径唯一命中且精确等于 journal asset 时才尽力清理;删除 I/O 失败不改变 committed,身份或媒体漂移则保留 staging,并把 journal 与 ledger 转入对账。
- 版本提交:派生子版本 journal 冻结 project revision before/after 摘要和目标 after 记录。manifest 已有目标子版本但 journal 缺失时失败关闭;旧 journal 缺少 revision 身份时,只有当前 revision 仍为 base 才允许补齐身份,revision 已推进且无法证明由同一事务写入时必须进入 `reconciliation-required`;缺少上述 journal 证明时,不得仅以子版本存在或 revision 数值已到达推断 committed。
- 服务身份:新生成账本统一写 `service-origin-v1`,绑定规范化 External base URL 的服务指纹,Developer API Key 只负责授权而不拥有 operation;确认面板只展示去除路径与凭据的服务 origin。升级前 Key-bound 指纹可被当前 Key 精确验证时自动迁移;对素材画布生成账本,无法验证时在任何网络动作前显示脱敏服务 origin 并要求用户确认带有期限且绑定账本快照的挑战值,确认后已受理任务只恢复原 GET,prepared 任务只精确重放冻结 POST。全类型资源编辑复用同一身份分类,旧指纹无法验证时保留原 operation 进入对账,不自动接管或重放。
- 服务身份:普通模式新生成账本写入 `official-platform-v1 + 固定官方 origin + ownerUserId`,高级 External v1 模式写入显式 service origin;Access Token 与 Developer API Key 都只负责授权而不拥有 operation。两种模式的已受理任务只恢复原 GET,prepared 任务只精确重放冻结 POST;普通模式 owner 不匹配时零网络,高级模式 origin 不匹配时失败关闭。
- 前端一致性:generation progress、保存队列、生成/提交回包和延迟草稿读取共用单调 revision 门禁;当前 scope 低 revision 不得回退已落地草稿,同 revision 只接受完整相等的幂等回包。Tauri 指针与键盘 Shift 选择共用 `resolveLayerPointerSelection`;移动、缩放和平移只在首次真实变化时 capture history,零位移不生成 undo、documentVersion 或保存。
- 交互恢复:工作台用独立 modal 展示全部后端权威 operation,允许选择任意可恢复项;`remote-failed` 只提供归档,`reconciliation-required` 只读展示。读取失败显式重试,操作后重读后端,项目切换后丢弃迟到结果。`canvas.failed` 统一携带 `generation / draft-save / asset-commit / recovery / cancellation` 五类 operation,只有生成失败显示“返回修改/重新确认”。
- 产品语义:当前仍禁用“新增资源”,只对现有资源做非破坏性派生编辑;新结果追加为新文件、asset 或子版本,源资源、源文件和原版本保留不变。
## 2026-08-10 Tauri 客户端远端资源编辑固定使用 External v1
## 2026-08-10 Tauri 客户端远端资源编辑统一复用平台生成链路
- 产品边界:主站网页画布继续使用登录态 `/api/editor/*`、`/api/assets/*` 与 `/api/runtime/external-generation/jobs/*`;AI 游戏创作 Tauri 客户端没有网页画布宿主,图片、图片引用、视频、音效和背景音乐等远端媒体编辑固定使用 `/api/external/v1/*`。两条入口继续复用相同请求 DTO、owner 归属、统一生成队列和正式资产结果,不新建平行生成服务。
- 凭据边界:客户端沿用发布 AppData 私有运行时配置中的 `editorApi.baseUrl/apiKey`,不实现登录后自动签发 Developer API Key,不把站内 Access Token 传给 Tauri 生成命令,也不把 API Key 打包进仓库、传入 WebView、写入项目、账本、日志或普通错误。Key 缺失投影安全配置错误,`401/403` 投影 External 凭据无效或权限不足,不再描述为站内登录失效。
- 配置入口:普通 Launcher、开发工作台和独立 game-chat 复用同一“运行时配置”对话框,均可编辑 AppData 私有 `editorApi.baseUrl/apiKey`;字段可见性不依赖开发模式或 Agent 模式。素材画布工作区自身不承接凭据输入,密钥输入保持 password 类型并禁用浏览器自动填充。
- 路由边界:图片编辑、视频、音效和 BGM 分别使用 `/api/external/v1/editor/images/edits`、`/api/external/v1/editor/videos/generations`、`/api/external/v1/editor/audios/sound-effects/generations` 与 `/api/external/v1/editor/audios/background-music/generations`;上传、确认、轮询和换签固定使用 External v1 对应端点。SVG、UTF-8 文档、代码、Agent 回执与项目版本仍是本地派生,不制造无意义的远端请求。
- 可靠性边界:External POST 固定携带原稳定 `Idempotency-Key` 并只接受 `202 + operationId`;`prepared` 只重放原正文和原键,`accepted/running` 只查询 `/api/external/v1/generations/{operationId}`。账本使用 `service-origin-v1` 绑定规范化 External base URL 的服务指纹,不绑定或保存明文 Key;升级前 Key-bound 素材画布生成账本无法用当前 Key 验证时,必须由用户显式确认面板中展示的当前 origin 才能恢复冻结请求;全类型资源编辑的旧指纹无法验证时保留原 operation 对账。升级前已保存的站内 endpoint 只保留为待对账状态,禁止拿 External Key 自动重放。本地参考媒体继续严格执行 ticket → OSS form → confirm,结果只消费稳定 `objectKey/resource/asset`,旧资源保留且派生资源追加。
- 产品边界:主站网页画布与普通 AI 游戏创作 Tauri 客户端统一使用登录态 `/api/editor/*`、`/api/assets/*` 与 `/api/runtime/external-generation/jobs/*`;第三方、standalone game-chat 和显式高级模式使用 `/api/external/v1/*`。两条入口复用相同请求 DTO、owner 归属、统一生成队列和正式资产结果,不新建平行生成服务。
- 凭据与配置:普通客户端的 Access Token 只通过专用 session install/clear 协议进入 GUI/Runner 内存,普通生成/恢复命令参数和运行时配置页不携带或展示 Token、URL、Developer Key。高级模式使用隔离 AppData 的 `editorApi.baseUrl/apiKey`,不与普通 release 自动共享。
- 路由边界:普通图片编辑、视频、音效和 BGM 使用对应 `/api/editor/*`,上传/确认/换签使用 `/api/assets/*`,状态查询使用 `/api/runtime/external-generation/jobs/*`;高级模式使用对应 External v1 路由。SVG、UTF-8 文档、代码、Agent 回执与项目版本仍是本地派生。
- 可靠性边界:两种模式都携带原稳定 `Idempotency-Key`;普通站内响应兼容 `200 + queueState.operationId` 与 inline 完成,高级 External v1 固定 `202 + operationId`。`prepared` 只重放原正文和原键,`accepted/running` 只查询原 operation。账本绑定调用模式、服务 origin 和普通模式 ownerUserId,不绑定 Token/Key;换号后旧 owner 账本零网络、零安装。
- 关联:`apps/ai-game-creator-shell/src/features/asset-canvas/tauriImageCanvasHostAdapter.ts`、`apps/ai-game-creator-shell/src/view/project-development/resourceEditModel.ts`、`apps/ai-game-creator-shell/src/view/project-development/index.tsx`、`apps/ai-game-creator-shell/src-tauri/src/project/asset_canvas/generation.rs`、`apps/ai-game-creator-shell/src-tauri/src/project/resource_editor.rs`。
## 2026-08-10 客户端参考媒体直传复用已授权私有前缀
@@ -5147,9 +5168,9 @@
- 2026-06-25 调整:普通用户通过聊天输入 `/run` 触发待确认 `game.run_local`,确认后只能复用白名单 `game.static_smoke` 自检当前 `game/index.html`,通过后启动 `127.0.0.1` 本地 HTTP 预览。独立执行 `game.static_smoke` 时如果已有 `.agent/run.latest.json`,必须追加 `Playtest / game.static_smoke` trace step,避免“运行了代码但编排 trace 不可见”。
- 2026-06-25 调整:普通用户通过聊天输入 `/trace` 触发只读 `agent.trace_read`,读取 `.agent/run.latest.json` 并在聊天里摘要 loop 轮次、stopReason、nextStep、active / carry-over 任务、repairRoutes、agent 建议命令和最近 step。trace 面板仍只在开发窗口展示,普通用户窗口不新增面板。
- 2026-06-25 调整:普通用户通过聊天输入 `/import-canvas-export /绝对/画板素材.zip 画板项目ID` 触发待确认 `canvas.export_import`,读取现有 `/editor/canvas` 素材导出 ZIP。导入命令只读取用户指定 ZIP,写入当前本地项目 `assets/canvas-imports/`,基础护栏限制路径逃逸、文件数量和解压体积;导出包没有真实 resourceId 时,用 `canvas-export:<file>` 作为可追踪 assetObjectId,不伪造后端画板资源行。
- 2026-06-25 调整,2026-06-30 更新:普通用户通过聊天输入 `/sync-canvas-project 画板项目ID` 触发待确认 `canvas.project_sync`,复用现有 `/api/external/v1/editor/projects/{projectId}` 读取画板项目快照,再用 `/api/external/v1/assets/read-url` 对 objectKey 或 legacy path 换签,下载资源到本地项目 `assets/canvas-sync/` 并登记为 `canvas` 来源资产;该命令从客户端配置项 `editorApi.apiKey` 读取平台 API Key,默认 base URL 为 `http://127.0.0.1:8082`,可用 `editorApi.baseUrl` 覆盖。API Key 不写入 manifest、agent.db、trace 或日志。该路径不伪装浏览器登录态,也不绕过画板生成、钱包扣费或外部生成 worker;它只同步用户 API Key 已有权限读取的画板资源。
- 2026-06-30 调整:`game.generate_draft` 在 `editorApi.apiKey` 已配置且美术组缺少 `canvas` 来源图片资产时,直接调用 External Editor API 的 `/api/external/v1/editor/images/generations` 生成首版美术素材,再通过 `/api/external/v1/assets/read-url` 换签下载到本地 `assets/canvas-generated/`,登记为 `canvas` 来源资产并追加 `canvas.asset_generate` 本地索引记录。API Key 不写入 manifest、agent.db、trace 或日志;生成失败不阻断本地原型生成,会在 trace 中记录失败并保留同步建议。
- 2026-06-25 调整,2026-06-30 更新:美术组 `Asset` 和音乐组 `SFX` 角色在 loop 中读取 `.agent/manifest.json`;当本地项目还没有对应类型的 `canvas` 来源资产时,角色 step 会追加 `agent.tool.suggest.canvas.project_sync` toolCall:美术组需要 `image/*` 或 `application/vnd.genarrative.image-sequence`,音乐组需要 `audio/*`。美术组在未配置 `editorApi.apiKey` 或平台生图失败时仍只给出同步建议;音乐组不调用图片生成接口,只建议同步已有音频资源。
- 普通用户通过聊天输入 `/sync-canvas-project 画板项目ID` 触发待确认 `canvas.project_sync`;普通模式用当前陶泥儿登录态读取 `/api/editor/projects/{projectId}` 并通过 `/api/assets/read-url` 换签,高级模式使用对应 External v1 路由。固定官方 origin、owner 和凭据均不写入 manifest、Agent DB、trace 或日志。
- `game.generate_draft` 在当前模式具备画板服务授权且美术组缺少 `canvas` 来源图片资产时,复用同一平台生成链路生成首版美术素材并下载到本地;普通模式使用登录态内部路由,高级模式使用 External v1。
- 美术组 `Asset` 和音乐组 `SFX` 在缺少对应 `canvas` 来源资产时建议同步;普通模式未登录或高级模式 Developer Key 缺失时只给出准确的能力不可用说明,不伪造生成结果。
- 2026-06-24 调整:同一本地项目多次 `game.generate_draft` 必须追加 `memory/session.md` 与 `memory/project.md`,不得覆盖历史对话和创作目标记录。
- 2026-07-01 调整:AI 游戏创作 App 在 `memory/session.md` 与 `memory/project.md` 之外新增项目级黑板 `memory/blackboard.md`,只记录重要跨 agent 决策、依赖和风险摘要;每个角色 agent 拥有私有记忆 `memory/agents/<group>/<role>.md`。角色 brief 必须读取自己的私有记忆和项目黑板;`game.generate_draft` 通过 Evaluator 与 `game.static_smoke` 后,追加项目黑板摘要和各角色成功产出摘要,不得覆盖既有记忆。失败 run 仍只保留 trace 和 pass 快照,不写最终记忆摘要。
- 2026-07-06 调整:AI 游戏创作 App 主聊天普通文本改为进入主聊天 Agent,而不是直接排队 `game.generate_draft`;主聊天 Agent 读取短期记忆、长期记忆、项目黑板、最近项目对话和本地资产摘要作为背景,支持 `agentLlm.chat` 单独 provider 配置,但只做自然语言交互、澄清和 slash 命令建议,不写项目、不运行工具、不伪装生成结果。显式 `/generate <创作想法>` 或 `/draft <创作想法>` 才进入 `game.generate_draft` 待确认流。
@@ -6722,7 +6743,7 @@
- MCP 边界:动态 MCP 函数的 `arguments.input` 必须在创建 durable pending 前按当前 catalog 的原始 `inputSchema` 本地校验;native parser 负责把错误归类为可修复的 arguments-schema,统一 enrichment 覆盖 legacy 兼容解析并把错误接回同一 repair 链。实际 MCP 调用前还必须按当前 catalog schema 重验一次,阻断升级前遗留的 schema 外 durable pending。校验器关闭 HTTP 与文件解析能力,外部 `$ref`、无效 schema、required/type/enum/additionalProperties 不匹配全部失败关闭,错误不得回显参数或 schema 私密值。
- Native Prompt:Provider 请求只描述实际广告的 `update_agent_plan`、动作函数、`respond_to_user` 和动态 MCP 函数;内部 `mcp.call` wrapper、`thinkingSummary/planUpdate` envelope、空 actions 以及无 function-tools 文本回退不再进入实时 Prompt。required-nullable 字段未使用时显式传 JSON `null`,空对象 input 只允许权威空 schema 工具。
- Supervisor 合同:配置 External Editor API Key 时,`art-asset-plan` 的 owner 产物统一为 `assets/manifest.art.json` 与 `assets/art-spritesheet.png`;未配置 Key 时只要求 `assets/manifest.art.json`,不得伪造或要求三个 PNG。版本化 Bundle 的视觉合同和 playbook 不得给出互斥 expectedArtifacts。
- Supervisor 合同:当前模式具备画板服务授权时,`art-asset-plan` 的 owner 产物统一为 `assets/manifest.art.json` 与 `assets/art-spritesheet.png`;普通模式未登录或高级模式未配置 Developer Key 时只要求 `assets/manifest.art.json`,不得伪造或要求三个 PNG。版本化 Bundle 的视觉合同和 playbook 必须从同一授权事实派生。
## 2026-08-04 图集事务与 Tetris 完成门使用句柄和 AST 收口
@@ -7147,6 +7168,17 @@
- 决策:普通 AGC Tauri release 的平台认证与客户端 API 固定访问 `https://dev.genarrative.world/api/*`;本地 `npm run agc` 继续使用 Vite `/api` 代理,普通网页构建继续使用同源相对路径,game-chat release 继续绕过平台登录。
- 传输边界:dev 公网入口不接受 Tauri WebView 的跨域 OPTIONS 预检,因此 release 使用 `tauri-plugin-http` 原生 transport。插件的 npm 依赖只归属 AGC 子包及其 lockfile,根 H5 package 与根 lockfile 不得引入任何 Tauri guest 依赖。插件 capability 与前端 URL 解析双重限制为 `https://dev.genarrative.world/api/*`,不为 WebView CSP 增加远程 `connect-src`,也不开放任意 HTTP(S) 目标。
- 会话边界:插件默认 Cookie Store 持久化 refresh Cookie;访问 Token 继续保存在现有客户端存储并通过 Authorization header 发送,不把 Token、Cookie 或登录正文写入日志、配置文件或仓库。
- 编辑器通道边界:普通/debug 构建由可信 native build flavor 固定为平台账号模式,缺少 native 会话时失败关闭并要求重新登录,绝不回退读取 `editorApi`。只有正式 `game-chat-release` 构建进入 External Developer 模式并读取其独立 AppData;普通配置读视图不暴露 Developer Key,renderer 保存会移除 `editorApi`。图片 refine 的本地源在 upload/confirm 后必须登记为项目 resource,再以 `sourceReferenceId` 提交,不能把 objectKey 或 assetObjectId 冒充业务引用。
## 2026-08-15 AGC 普通远端编辑复用网站登录态路由
- 路由决策:普通 AGC 登录后直接调用固定官方 origin 下的网站现役 `/api/editor/*`、`/api/assets/*` 与 `/api/runtime/external-generation/jobs/*`,不再要求用户配置 External Editor Base URL 或 `tnr_sk_...`。普通 release 的官方 origin 继续服从 2026-08-10 的 dev API 固定规则,本地 dev 使用配套代理。`/api/external/v1` 的 Bearer Developer API Key 契约保持独立且不接受网站 Access Token,只供第三方 Agent/CLI、独立 standalone game-chat release 与显式高级自定义模式;服务端不为普通用户自动签发、代管或下发 Developer Key。
- UI 与 standalone 例外:普通 Launcher、工作台、已认证 debug game-chat 和运行时配置页不展示或维护 External Editor URL/Key。独立 standalone game-chat release 仍绕过 `AuthenticatedClient`,只能在用户显式配置其隔离 AppData 的高级 External v1 URL/Key 后使用云端画板能力;凭据缺失时明确不可用,不得回退到普通登录态、内置 Key 或隐式公共账号。
- 会话 CAS:WebView 登录、refresh、退出和换号通过窄 Tauri/Runner 协议同步 `userId + 短期 Access Token + authGeneration` 到 GUI/Runner 进程内存。generation 单调递增,只有不旧于当前值的安装/清除可以生效;每个业务请求在发出前冻结 `ownerUserId + authGeneration`,在响应解析、账本推进、媒体安装和正式项目提交前都重新核对。旧 generation 的迟到安装、响应或清除不得覆盖新账号,也不得把旧账号产物安装到新账号项目。
- 凭据边界:Access Token、refresh Cookie、Authorization 和 authGeneration 不进入 AppData、项目、manifest、生成账本、Agent prompt、conversation、Agent DB、trace、日志或普通错误;durable 账本只保存非敏感 ownerUserId。Runner IPC 只允许专用 session install/clear 消息携带 Token,普通生成/恢复命令参数继续不得携带 Access Token 或 Developer Key。
- 401/refresh:普通模式首次 `401` 进入当前 authGeneration 的全局单飞 refresh;其它请求等待同一 Promise,但各自 deadline、取消和账号归属独立。refresh 成功只在原 generation/owner 仍当前时以更高 generation CAS 发布新 Token,然后每个调用最多使用原 endpoint、原始请求字节和原 `Idempotency-Key` 重试一次。refresh 失败、账号已切换或重试仍为 `401` 时停止网络并保留原 operation;`403` 表示当前账号权限不足,不触发 refresh。高级 External v1 模式只允许用户修正自己的 Developer Key,并继续原 operation。
- Durable 身份与换号:普通账本身份固定为 `official-platform-v1 + 官方 origin + ownerUserId`,高级账本身份固定为 External service origin,二者均不绑定可轮换 Token/Key。退出或换号会提升 generation、中止并脱离旧请求;新账号对旧 owner 的 `prepared/accepted/running` 账本必须零 POST、零 GET、零下载、零安装、零归档,只有重新登录同一 owner 后才能恢复。`401/403/404`、网关错误或轮询超时不能在 owner 不匹配时证明旧 operation 的终态。
- 幂等与站内响应:`prepared` 只可精确重放账本冻结的原 endpoint、原始正文和原幂等键;`accepted/running` 只查询原 operationId。Access Token/Key 轮换、refresh、重启、退出或换号都不得创建替代 operation、修改正文或重新扣费。站内生成适配 `200 + queueState.operationId`、inline 完成和 `job` 状态包装;External v1 继续固定 `202 + operationId`,两者共享相同 owner、计费、稳定引用与本地事务门禁。
## 2026-08-12 子 Agent 澄清回执由 Supervisor 中转(Issue #163)
@@ -7178,6 +7210,22 @@
- HTTP 传输边界:根 H5 包不得依赖 Tauri guest 插件;AGC 独立包保留 `@tauri-apps/plugin-http`。Rust 插件显式关闭默认特性,只启用 `charset`、`cookies`、`http2` 和 `rustls-tls`,避免 `reqwest/system-proxy` 通过 Cargo feature union 把画布、Provider、Runtime 与本地回环夹具统一接入 OS 自动系统代理;如未来产品要求正式客户端继承系统代理,必须按各客户端明确设计并单独完成跨平台验证。
- 运行决策:Godot 项目提交给 Project Supervisor 时使用 `standard` Run Profile,避免触发 Web 专用 `game/index.html`、HTTP preview 与自主 Web 完成门。Godot 编辑器启动和内嵌运行预览不在本切片范围。
## 2026-08-14 AGC Web game-chat fresh-init 真实验收基线
- fresh-init 决策:`supervisor-game-chat-single-main-playable` 的 disposable 项目只预置 Git、`AGENTS.md`、三份隔离 evidence 与敏感诱饵,不再预写 `package.json`、`verify-e2e.mjs` 或 `game/index.html`;入口必须由正式 `--init` 写入生产 `DEFAULT_GAME_INDEX_HTML`。canonical 副本由无 Provider self-test 与 Rust 常量逐字节比对,防止验收基线静默漂移。
- 报告门禁:同一真实 E2E 报告必须记录初始入口 SHA-256,并同时断言初始字节命中生产默认入口、根下唯一固定 child 为 `code-prototype`、最终入口不同于 baseline、`game.static_smoke` 凭证 SHA-256 等于最终入口,以及 desktop/mobile 两个 viewport 各自 passed;任一项不成立均失败关闭。
- 范围边界:这条真实 Provider 验收仅覆盖普通 Web 工作台的 `project-supervisor-game-chat + autonomous-game-build` 单 Supervisor 链,不覆盖显式 `professional-dag` 或固定 16 节点 CLI/GUI 链。后者的 owner-artifact verify、产物所有权与 path-scope 仍是独立未解决项;seeded deterministic E2E、普通 self-test 和 game-chat 报告均不得据此声称该问题已修复或该链已通过真实验收。
## 2026-08-13 AGC 普通 Web 工作台默认单主无人值守生成
- 决策:项目首页进入的普通 Web 工作台默认 `single-supervisor`,提交固定映射为 `project-supervisor-game-chat + autonomous-game-build`。该决策覆盖此前“普通 GUI autonomous 继续固定完整 DAG”的现行入口规则;固定专业 autonomous DAG 只保留给显式 `professional-dag` 和专业 CLI 验收,Supervisor 调试与 Godot 继续 `standard + project-supervisor-gui`。
- 路由:game-chat 根先由 Supervisor 持久化意图,随后只启动唯一 `code-prototype`;主 Run 完成资产审计后,只有真实缺口才可一次委派一个受限美术 child。普通用户界面不再展示固定专业 DAG、子 Agent Dock 或“严格审批”,统一显示自动执行与中性生成状态。
- 澄清:仅可信 game-chat autonomous 根链及其绑定 child 将 `NeedsUserInput` 转为安全默认返工,并保持同一主 Run 继续;问题正文与公开问题指纹清除,内部只保留不公开的 SHA-256 幂等 marker。standard、GUI/CLI 调试、非可信或身份不完整链路仍保留原人工澄清,自动化不能扩大项目外写入、任意命令、发布、凭据或未知外部副作用权限。
- 诊断:`game.static_smoke` 必须先解析可执行内联 JavaScript。公共失败回执只暴露稳定结构化字段;同一 owner 额外取得脱敏有界诊断。可修复失败按同 Run 的“诊断、修改、当前 revision 静态复验、双视口试玩”循环收口,不能以继续堆关键词或要求用户发送“继续”代替修复。
- 恢复:跨 boot 取得 `execution-owner` 即幂等触发既有 durable recovery scan;安全动作续跑,未知外部副作用保留证据并进入 reconciliation,同 boot 重入不得重复恢复副作用。
- 完成:根 Run 只有在正式 artifact、manifest、当前 revision static smoke 和 desktop/mobile `preview.validate` 一致时唯一 completed。确定性 loopback E2E 是提交门,真实 Provider 空项目单输入、零人工介入 smoke 是现场验收门,两者不得混称。
- 关联:`docs/project-memory/plans/【实施计划】AGC无人值守游戏生成可靠性收口-2026-08-13.md`、`docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`。
## 2026-08-12 AGC Agent 设置分层界面
- `RuntimeConfigDialog` 保持现有配置字段、持久化格式、Runner 读取和 MCP 测试语义,只重构界面信息架构。
@@ -12167,9 +12215,9 @@
- 2026-06-25 调整:普通用户通过聊天输入 `/run` 触发待确认 `game.run_local`,确认后只能复用白名单 `game.static_smoke` 自检当前 `game/index.html`,通过后启动 `127.0.0.1` 本地 HTTP 预览。独立执行 `game.static_smoke` 时如果已有 `.agent/run.latest.json`,必须追加 `Playtest / game.static_smoke` trace step,避免“运行了代码但编排 trace 不可见”。
- 2026-06-25 调整:普通用户通过聊天输入 `/trace` 触发只读 `agent.trace_read`,读取 `.agent/run.latest.json` 并在聊天里摘要 loop 轮次、stopReason、nextStep、active / carry-over 任务、repairRoutes、agent 建议命令和最近 step。trace 面板仍只在开发窗口展示,普通用户窗口不新增面板。
- 2026-06-25 调整:普通用户通过聊天输入 `/import-canvas-export /绝对/画板素材.zip 画板项目ID` 触发待确认 `canvas.export_import`,读取现有 `/editor/canvas` 素材导出 ZIP。导入命令只读取用户指定 ZIP,写入当前本地项目 `assets/canvas-imports/`,基础护栏限制路径逃逸、文件数量和解压体积;导出包没有真实 resourceId 时,用 `canvas-export:<file>` 作为可追踪 assetObjectId,不伪造后端画板资源行。
- 2026-06-25 调整,2026-06-30 更新:普通用户通过聊天输入 `/sync-canvas-project 画板项目ID` 触发待确认 `canvas.project_sync`,复用现有 `/api/external/v1/editor/projects/{projectId}` 读取画板项目快照,再用 `/api/external/v1/assets/read-url` 对 objectKey 或 legacy path 换签,下载资源到本地项目 `assets/canvas-sync/` 并登记为 `canvas` 来源资产;该命令从客户端配置项 `editorApi.apiKey` 读取平台 API Key,默认 base URL 为 `http://127.0.0.1:8082`,可用 `editorApi.baseUrl` 覆盖。API Key 不写入 manifest、agent.db、trace 或日志。该路径不伪装浏览器登录态,也不绕过画板生成、钱包扣费或外部生成 worker;它只同步用户 API Key 已有权限读取的画板资源。
- 2026-06-30 调整:`game.generate_draft` 在 `editorApi.apiKey` 已配置且美术组缺少 `canvas` 来源图片资产时,直接调用 External Editor API 的 `/api/external/v1/editor/images/generations` 生成首版美术素材,再通过 `/api/external/v1/assets/read-url` 换签下载到本地 `assets/canvas-generated/`,登记为 `canvas` 来源资产并追加 `canvas.asset_generate` 本地索引记录。API Key 不写入 manifest、agent.db、trace 或日志;生成失败不阻断本地原型生成,会在 trace 中记录失败并保留同步建议。
- 2026-06-25 调整,2026-06-30 更新:美术组 `Asset` 和音乐组 `SFX` 角色在 loop 中读取 `.agent/manifest.json`;当本地项目还没有对应类型的 `canvas` 来源资产时,角色 step 会追加 `agent.tool.suggest.canvas.project_sync` toolCall:美术组需要 `image/*` 或 `application/vnd.genarrative.image-sequence`,音乐组需要 `audio/*`。美术组在未配置 `editorApi.apiKey` 或平台生图失败时仍只给出同步建议;音乐组不调用图片生成接口,只建议同步已有音频资源。
- 普通用户通过聊天输入 `/sync-canvas-project 画板项目ID` 触发待确认 `canvas.project_sync`;普通模式用当前陶泥儿登录态读取 `/api/editor/projects/{projectId}` 并通过 `/api/assets/read-url` 换签,高级模式使用对应 External v1 路由。固定官方 origin、owner 和凭据均不写入 manifest、Agent DB、trace 或日志。
- `game.generate_draft` 在当前模式具备画板服务授权且美术组缺少 `canvas` 来源图片资产时,复用同一平台生成链路生成首版美术素材并下载到本地;普通模式使用登录态内部路由,高级模式使用 External v1。
- 美术组 `Asset` 和音乐组 `SFX` 在缺少对应 `canvas` 来源资产时建议同步;普通模式未登录或高级模式 Developer Key 缺失时只给出准确的能力不可用说明,不伪造生成结果。
- 2026-06-24 调整:同一本地项目多次 `game.generate_draft` 必须追加 `memory/session.md` 与 `memory/project.md`,不得覆盖历史对话和创作目标记录。
- 2026-07-01 调整:AI 游戏创作 App 在 `memory/session.md` 与 `memory/project.md` 之外新增项目级黑板 `memory/blackboard.md`,只记录重要跨 agent 决策、依赖和风险摘要;每个角色 agent 拥有私有记忆 `memory/agents/<group>/<role>.md`。角色 brief 必须读取自己的私有记忆和项目黑板;`game.generate_draft` 通过 Evaluator 与 `game.static_smoke` 后,追加项目黑板摘要和各角色成功产出摘要,不得覆盖既有记忆。失败 run 仍只保留 trace 和 pass 快照,不写最终记忆摘要。
- 2026-07-06 调整:AI 游戏创作 App 主聊天普通文本改为进入主聊天 Agent,而不是直接排队 `game.generate_draft`;主聊天 Agent 读取短期记忆、长期记忆、项目黑板、最近项目对话和本地资产摘要作为背景,支持 `agentLlm.chat` 单独 provider 配置,但只做自然语言交互、澄清和 slash 命令建议,不写项目、不运行工具、不伪装生成结果。显式 `/generate <创作想法>` 或 `/draft <创作想法>` 才进入 `game.generate_draft` 待确认流。
@@ -13742,7 +13790,7 @@
- MCP 边界:动态 MCP 函数的 `arguments.input` 必须在创建 durable pending 前按当前 catalog 的原始 `inputSchema` 本地校验;native parser 负责把错误归类为可修复的 arguments-schema,统一 enrichment 覆盖 legacy 兼容解析并把错误接回同一 repair 链。实际 MCP 调用前还必须按当前 catalog schema 重验一次,阻断升级前遗留的 schema 外 durable pending。校验器关闭 HTTP 与文件解析能力,外部 `$ref`、无效 schema、required/type/enum/additionalProperties 不匹配全部失败关闭,错误不得回显参数或 schema 私密值。
- Native Prompt:Provider 请求只描述实际广告的 `update_agent_plan`、动作函数、`respond_to_user` 和动态 MCP 函数;内部 `mcp.call` wrapper、`thinkingSummary/planUpdate` envelope、空 actions 以及无 function-tools 文本回退不再进入实时 Prompt。required-nullable 字段未使用时显式传 JSON `null`,空对象 input 只允许权威空 schema 工具。
- Supervisor 合同:配置 External Editor API Key 时,`art-asset-plan` 的 owner 产物统一为 `assets/manifest.art.json` 与 `assets/art-spritesheet.png`;未配置 Key 时只要求 `assets/manifest.art.json`,不得伪造或要求三个 PNG。版本化 Bundle 的视觉合同和 playbook 不得给出互斥 expectedArtifacts。
- Supervisor 合同:当前模式具备画板服务授权时,`art-asset-plan` 的 owner 产物统一为 `assets/manifest.art.json` 与 `assets/art-spritesheet.png`;普通模式未登录或高级模式未配置 Developer Key 时只要求 `assets/manifest.art.json`,不得伪造或要求三个 PNG。版本化 Bundle 的视觉合同和 playbook 必须从同一授权事实派生。
## 2026-08-04 图集事务与 Tetris 完成门使用句柄和 AST 收口
@@ -14174,3 +14222,58 @@
- 决策:内部稳定 `deploymentId` 继续绑定分支、Compose project 和端口租约;页面/API 记录 ID 在 Jenkins 分配执行器后改为构建编号,排队阶段为“待分配”。卸载通过构建编号找到内部实例,再向固定 Job 传内部 ID。
- 清理:失败或取消且不存在可卸载实例的记录保留 7 天;成功卸载的内部审计记录保留 30 天;仍可卸载的失败记录永久保留到人工卸载。服务启动、读取列表和创建部署时执行清理并原子落盘。
- 链接:服务内部仍通过 Jenkins loopback 轮询;只向浏览器返回由 `GENARRATIVE_PREVIEW_DEPLOYER_JENKINS_PUBLIC_BASE_URL` 构造的局域网构建详情地址,禁止回传 loopback URL。
## 2026-08-16 AGC 直连回合的 revision 与项目版本同步
- 根因:直连 Runtime 登记游戏代码并写入首个版本时复用了陶泥儿美术生成后的旧 project revision。外层工作台按 revision 合并 manifest,同 revision 的不同快照必须失败关闭,因此磁盘已有 `game/index.html`、`game/style.css`、`game/game.js` 和版本记录时,资源管理仍可能显示游戏代码 0 项、项目版本 0 项。
- 决策:每次直连 Codex 回合只有在代码文件存在、完整陶泥儿美术包有效且五类素材进入实际 Canvas 渲染后,才在项目写锁内推进一次 durable project revision,并以新 revision 创建首个 `initial-*` 或后续 `agent-*` 正式版本。后续版本绑定上一正式版本为父版本,继续复用原游戏代码资产 ID,禁止通过重复登记制造平行资产。
- 已有项目编辑:direct app-server 继续禁用 shell / unified exec,但系统提示词必须在仓库长文档之前带入当前三个游戏代码文件的有界脱敏快照,供原生 file-change 精确匹配。回合前后绑定三个文件的内容指纹;没有真实文件变化且 manifest 已同步时,不推进 revision、不追加版本,不能把“无法读取所以未修改”的回复登记成正式修订。
- 验收:连续两次产物同步必须得到单调 revision、`initial-* -> agent-*` 父子版本链、稳定的 3 个代码资产 ID;真实客户端外层资源管理必须随新 revision 显示游戏代码和项目版本。
## 2026-08-17 AGC 直连阶段反馈与资源预览首屏预取
- 直连 Runtime 的美术生成、代码生成和版本登记仍保持单次原子回合,不拆回 Supervisor 或 harness。为避免用户等待数分钟只看到“思考中”,Runtime 在每个用户可理解的安全阶段复用 `game-creator-agent-progress`:需求接收、陶泥儿美术包检查、规范图、背景图、图集及切片、代码生成、版本登记和预览刷新;普通直连工作台仅接受当前项目的事件并显示 `message`,不把内部执行协议、路径或凭据暴露到聊天。
- 资源画布不能把 `IntersectionObserver` 作为首屏唯一预览触发器。工作台进入资源管理时主动预取最多 12 个可预览的非音频、非版本、非占位资源;保留现有按可见性懒加载、队列优先级、并发上限、缓存上限、权限失败提示与详情/播放升级机制。这样不会一次读取大项目全部资源,但陶泥儿标准三张 PNG 和游戏代码能在正常首屏项目中无需打开详情直接显示。
- 验收:定向 hook 测试证明预取会直接调用本地 preview command 并进入 loaded;AppSurface 证明 direct 提交即时显示接收文案并消费阶段事件;2026-08-17 在当前 checkout 的普通 AGC 客户端打开 `gameagent-3291e57c`,未打开任何资源详情即观察到三份游戏代码摘要和三张陶泥儿 PNG(规范图、16:9 背景、核心图集)缩略图。
## 2026-08-17 AGC 开发态默认单窗口启动
- 决策:`npm run agc` 及普通 debug 启动只打开标题为“陶泥儿”的 `client` 客户端窗口,不再由 Tauri setup 自动创建 Agent 聊天开发窗口。普通创作、直连 Codex Runtime 和项目工作台行为均不受影响。
- 保留:`?agent-chat` 仅作为显式前端调试路由;`supervisor-chat` 和 `--game-chat` 继续是独立的显式开发验收入口,不会随着普通启动同时弹出。
- 守卫:原生壳配置检查必须拒绝恢复 `open_developer_window(app.handle())?` 自动调用;真实开发 smoke 以普通客户端单窗口为准。
## 2026-08-17 直连 Codex 使用 LLM 自主试玩替代固定美术产物门
- 直连 Runtime 的确定性门禁只保护工作区权限、凭据隔离、平台生成幂等与账本、文件事务、图片下载/PNG 解码、平台来源身份和同 Canvas 关系。`grid-2x2`、固定四切片、固定文件名及固定 `drawImage` 次数降为陶泥儿标准推荐路径,不再阻断所有合理的游戏产物。
- Codex 是唯一执行主体。客户端在同一 Codex thread 内最多追加两次结构化浏览器证据/整改 turn;受限 Chromium 负责 desktop/mobile 页面、Canvas、控制台/网络、截图和有限真实交互探针,禁止恢复 Supervisor、专业 Agent 或 harness,也不把固定玩法状态机当成 direct 完成合同。
- 完成登记前至少要有 `game/index.html` 和一个已登记、真实、平台来源的图片被源码引用;游戏质量与视觉实际使用由 Codex 根据真实试玩证据自行判断,最终回复必须说明检查文件、试玩动作、双视口观察、素材使用、修复和剩余风险。
## 2026-08-17 AGC 直连平台资源失败诊断
- 普通客户端使用陶泥儿平台账号会话时,直连 Runtime 的只读画布恢复继续以 External Editor 形状构造请求,再统一经 `resolve_platform_editor_api_route` 映射到 `/api/editor/...` 与 `/api/assets/...`;不得把平台 access token 直接送到未映射的 `/api/external/v1/...` 路由,也不得为排障改用或落盘开发者 API Key。
- 直连回合的请求准备、平台美术准备、Codex 代码生成、真实浏览器试玩和版本登记失败,统一投影为 `direct-codex-failure:v1`:仅含稳定阶段、脱敏摘要、是否可重试和下一步建议。每次失败尽力写入项目 `.agent/runtime/direct-codex-diagnostics/<nonce>/failure.json`,不保存 token、Cookie、完整 URL、绝对路径或原始服务端正文;写诊断失败不得遮蔽原失败。
- 普通客户端必须展示上述安全摘要与建议,不能把可解释的资源恢复失败降级成“执行失败,请稍后重试”。平台账号失效提示重新登录;资源身份冲突、多个同源图集或透明图集明确要求先在资源画布核对,而非盲目重复生成或扣费。
- 已有同一画布、身份可信且可解码的规范图与背景图时,历史核心图集的只读恢复只是可选增强:未找到该图集不得阻断直连 Codex 生成、浏览器试玩或版本登记,也不得触发重复付费生成;最终源码仍须实际引用至少一个已登记的平台图片。
- 透明后处理失败但平台已保留源图时,只有同一画布身份的只读恢复成功后才清理对应 `agentId/runId` 生成账本;恢复失败、身份不唯一或结果未知继续保留 `accepted` / `operationId` 供对账,禁止因清理过早而重复扣费。
## 2026-08-18 AGC 登录服务器选择
- AGC 登录页提供 `release`(`https://www.genarrative.world`)、`dev`(`https://dev.genarrative.world`)和 `custom` 三种服务器选择;选择持久化在客户端本地存储,登录、验证码、刷新和原生平台会话安装统一使用当前选择。
- custom 只接受纯 HTTPS origin;`localhost` / loopback 的 HTTP 也允许用于本机服务,禁止把路径、查询参数、凭据或非本机明文 HTTP 地址作为服务器地址。
- Tauri release 的 HTTP capability scope 必须覆盖 release、dev、custom HTTPS 以及 loopback HTTP,否则前端选择虽能保存,plugin-http 仍会在请求层拒绝登录。
- 直连 Codex 的本机 External Editor API Key 必须按服务器 origin 独立存储。登录服务器切换后禁止复用另一 origin 的历史 Key 或 base URL;否则会出现登录走新服务器、平台资源生成仍请求旧服务器的漂移。
## 2026-08-18 AGC 登录网络错误与 Web Build 门禁对齐
- 网络 transport 的原始错误(例如浏览器 `Load failed`、URL、底层连接文本)不得直接进入登录页;客户端按超时、拒绝连接、地址解析和 TLS/证书四类可操作原因归一化,其余情况使用统一服务不可达提示。
- 本地 `master` 推送门禁 `scripts/check-repository-ci.sh` 必须在 lint 后运行 Jenkins Web Build 所覆盖的 AGC AppSurface 套件,再执行 build、content 和 diff 检查,避免登录 UI 回归只在远端构建阶段暴露;完整 Vitest 仍由 Jenkins 生产构建执行。
- Gitea `repository-checks` 因此必须和 Frontend / Native jobs 一样先执行 AGC 子包的 lockfile 安装;根目录 `npm ci` 不包含 `@tauri-apps/plugin-http` 等子包依赖,不能用预构建镜像缓存假定它们已存在。
- 验证:`npx vitest run apps/ai-game-creator-shell/tests/appSurface.test.ts -t "shows a clear login service error|explains a refused login connection|keeps the stored token when startup auth check cannot reach the service"`、`npm run check:git-hooks`、`npm run check:encoding`、`git diff --check`。
## 2026-08-19 AGC 画板恢复测试显式认证模式
- 背景:普通 Debug 客户端已默认走平台账号路由;旧画板恢复 fixture 只写 `editorApi` 配置,却未安装测试会话或任务级开发者凭据。请求会在到达 loopback mock 前以 `authentication-required` 返回,而 fixture 随后无限等待 `accept`,使 Native shell CI 无界卡住。
- 决策:断言 External Editor `external-v1` 路由的测试必须通过 task-local 测试凭据显式进入开发者路径;断言普通客户端恢复路径的测试必须安装可自动恢复的测试平台会话并断言 `/api/runtime/external-generation/jobs/*`。所有等待 mock 请求的 fixture 必须使用有界 accept deadline,不得用无期限 `join` 掩盖请求前失败。
- 验证:`cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml canvas_generation_tests:: -- --test-threads=1`。
- 2026-08-19 追加:同一默认认证切换也覆盖资源编辑和 autonomous main-loop fixture。`resource_editor` 的 External Editor 视频提交/轮询/服务身份恢复测试同样使用 task-local 凭据;平台账号语义测试使用隔离测试会话。main-loop 的视觉任务配置测试不再通过旧 `editorApi` 文件伪造登录态。所有 loopback listener 在 accept 时设有 5 秒 deadline,并把 accepted stream 恢复为 blocking,避免 Windows `WouldBlock(10035)` 或请求未发出时无限等待。
- 定向验证:`project::asset_canvas::generation::tests::` 14/14、`project::resource_editor::tests::` 36/36、`agent::runtime_driver::main_loop_tests::` 48/48、`agent::runtime_protocol::autonomous_completion_contract_tests::` 107/107 通过。此前一次 Windows 全量 Native Rust 为 1811 passed、108 failed、15 ignored;失败集合仍包含 Provider/mock 调度与既有专业链断言。HEAD 基线独立复现 `tests::project::generate_platform_art_asset_downloads_and_registers_external_image` 的同一登录态缺失,故不能把全量结果伪报为本次 fixture 修复引入;本次新增认证/accept deadline 相关用例均已隔离通过,最后两个 autonomous completion fixture 的认证迁移已单独通过,完整套件未在该两行测试改动后重新执行。
@@ -99,6 +99,8 @@ game-chat 条件快车道采用单主口径。父 Run 与全部 child Run 共用
失败续跑还必须覆盖同 Session 同 source 继承、跨 Session / 跨 source 不继承、首次与连续 successor 的 effective task / contract / scheduler 一致性,以及中英文纯继续短语使用同一识别函数。非占位入口的新 `code-prototype` 必须先产生本人 mutation 再 smoke;连续只读 smoke 不得收束。占位 fallback 只允许显式支持的真实玩法模板,俄罗斯方块必须验证棋盘、下落、旋转、锁定和消行语义,未知玩法必须失败关闭。
legacy 计划迁移到结构化计划时以 `planRevision` 为唯一边界:`planRevision=0` 的 `planSteps` 只是 Runtime 脚手架,第一次有效 `planUpdate` 必须完整替换它,即使 legacy 活动步骤已因工具 observation 变成 `completed / failed`;不得把该脚手架终态合并进首份结构化计划。入口处已经存在结构化计划后,后续更新仍必须保留 `completed / failed` 终态,Provider 不得重开失败步骤。修改此边界至少运行 `first_structured_plan_replaces_terminal_legacy_scaffolding_steps`、`structured_plan_failed_step_remains_immutable_after_migration`、真实 smoke 修复序列回归,以及 `structured_plan_`、`game_chat_` 串行分组;最终无人值守结论仍必须来自新的独立真实 Provider 空项目轮次,不能由历史失败轮和本地单测拼接。
game-chat GUI 恢复还要覆盖两类竞态:root Runtime 先终态、单主 Run 或其必要美术 child 后终态时,必须等到所有必要 delivery 的最终状态后仅持久化一条 `【Supervisor 阶段记录】`;页面初始 hydration 直接读到真实终态时也要补写缺失记录,但不得把 `idle` 当作完成。同时,GUI 启动的 `agent.resume` 自动扫描必须先做只读恢复工作预检:新项目或无 task / retry / handoff / finalization / pending / reconciliation 工作的已终态项目不弹确认,存在任何 durable recovery artifact 则仍必须命中 `agent.resume` policy。
```bash
@@ -680,3 +682,11 @@ npm run ai-game-creator-shell:agent-runtime:supervisor-swarm-tool-plan-handoff-r
- 修改预览完成门时,分别覆盖 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 和后来修改的文件,不能按当前文件反推历史请求。
## AI 游戏创作普通 Web 工作台无人值守验收
- 普通项目首页进入的 Web 工作台使用 `single-supervisor`,提交必须是 `project-supervisor-game-chat + autonomous-game-build`;持久 Supervisor 决策前零 child,之后只启动 `code-prototype`。显式 `professional-dag` 与 CLI 专业验收继续完整 autonomous DAG,Supervisor 调试与 Godot 继续 standard;这些显式入口不受普通默认值影响。
- 修改入口或路由后,至少运行 AGC typecheck、`agentRuntimeModel.test.ts` 和挂载后的 `appSurface.test.ts`,同时断言普通工作台不展示专业 Agent 栏、子 Agent Dock 或审批按钮;显式专业入口仍可访问这些开发能力。steer 必须精确匹配 source、profile、Session 和 run。
- 修改 smoke、delivery 或 recovery 后,必须用确定性路径证明:首次 `game.static_smoke` 精确报告 JavaScript/合同失败;公共回执不含诊断和绝对路径;同 owner 取得脱敏诊断;同一 `code-prototype` Run 有真实 mutation;最新 revision 的 static smoke 与 desktop/mobile `preview.validate` 均通过;根 Run 只有一个 completed;confirmation 与 user-input 为零。
- 修改 `execution-owner` 后必须覆盖跨 boot 首次 claim 自动触发一次 recovery scan、同 boot/重复 hydration 幂等不重复,以及未知外部副作用仍进入 reconciliation。不能只证明 OS 锁可重新取得,也不能依赖用户显式 `/resume` 或点击继续。
- 最终交付把“确定性 mock/loopback E2E”和“真实 Provider 空项目 smoke”分开报告。未完成后一项时可以说明实现和回归已完成,但不得宣称已经证明真实场景全程无人介入。
@@ -4766,3 +4766,10 @@
- 处理:generation progress、保存队列、生成/提交回包和延迟 `loadDraft` 统一用当前 scope、触发最低 revision 与回包当下草稿的单调门禁;同 revision 只允许完整相等回包。Tauri 指针和键盘选择复用 `resolveLayerPointerSelection`。pointerdown 只冻结快照,首次真实 move/resize/pan 才 capture 一次;零位移、未变选择和锁定图层不增加 undo、documentVersion 或草稿保存。
- 失败边界:`canvas.failed` 必须携带 `generation / draft-save / asset-commit / recovery / cancellation`,只有 `generation` 失败显示“返回修改/重新确认”。保存/CAS 只重试或重载,提交/恢复只安全恢复或对账,取消故障只保留草稿继续编辑;初始恢复失败也不得进入生成重试。
- 验证:用 deferred Promise 覆盖 r5/r6 逆序、保存与 progress 交错和 scope 切换;同时覆盖 Shift 单选自身、多选拖动、指针完整序列、零位移、首次有效移动只一条 history,以及五类失败的可访问名称与按钮集。
## Windows MSVC 测试不要依赖系统 OpenSSL(2026-08-17)
- 现象:Windows 上执行 Rust 测试时,`openssl-sys` 构建脚本因找不到 OpenSSL 开发目录或 vcpkg 而失败;机器即使带有 Strawberry Perl 的 `openssl.exe` 和 `libssl.a`,也不能直接供 `x86_64-pc-windows-msvc` 链接。
- 原因:测试代码仅为动态生成 RSA fixture 引入 `openssl` dev-dependency,从而把原本使用纯 Rust 加密实现的 crate 额外绑定到本机原生 OpenSSL 工具链;Strawberry 附带的库面向 MinGW,不等于可用的 MSVC OpenSSL SDK。
- 处理:测试优先使用明确标记、只供测试的固定 PEM fixture,并继续通过项目自身的密钥解析与签名验证路径覆盖真实行为;不要仅为生成 fixture 引入系统原生库,也不要把 MinGW OpenSSL 路径写入 `OPENSSL_DIR` 冒充 MSVC 依赖。
- 验证:运行目标 crate 的 `cargo tree -i openssl-sys --target all` 确认依赖已退出,再执行包含测试目标的 `cargo test --tests`,不能只用不会编译 dev-dependency 的 `cargo check --lib` 代替。
@@ -47,6 +47,8 @@ SpacetimeDB 2.7 CLI 发布到受控 Compose 网络地址时固定使用 `--yes=r
预览 Compose override 将 SpacetimeDB 内存上限设为 `2g`。基础 loadtest Compose 的 `896m` 是压测采样口径,当前完整模块首次发布和实例化会超过该上限;预览环境若沿用该值,容器会被 cgroup OOM 杀死并使模块上传中断。该覆盖只作用于分支预览实例,不修改生产或压测基线。
每个预览实例使用独立 SpacetimeDB 空库,不继承生产账号和短信凭据。Jenkins 在实例私有 `api-server.env` 中开启预览专用认证:未注册的中国大陆手机号首次使用 6 到 128 位密码时自动创建预览账号;短信入口使用 `mock` provider 与固定预览验证码 `123456`,不向真实手机发送短信。该设置不写入公共 env 示例、生产配置或镜像层;实例重建会重建独立数据库,原预览账号不保留。
## Jenkins 参数与产物
固定 Job:`shared/Genarrative-Preview-Deployer`。
@@ -118,4 +120,5 @@ Jenkins 在构建完成、归档 artifact 和更新 REST 状态之间可能短
- 后端:输入校验、登录会话、Origin、Crumb、Jenkins `401/403/404/5xx`、queue 到 build 状态机、artifact schema、卸载所有权和幂等测试。
- 前端:登录、分支与可选 commit、自动刷新、排队/构建/成功/失败状态、内网链接、卸载确认和刷新恢复测试。
- Jenkins:两个分支依次发布后在不同端口并存;同一分支换 commit 优先复用端口;非分支 commit 被拒绝;卸载只删除目标实例并释放端口。
- 预览认证:新手机号可以首次密码登录并重复使用同一密码;错误密码被拒绝;获取验证码后使用 `123456` 可完成登录;容器不包含生产短信凭据。
- 通用:`npm run check:encoding`、相关 typecheck/build/test、Rust 定向测试和 `git diff --check`。
@@ -1080,18 +1080,18 @@ Runtime 只在以下客观条件同时满足时写 `contractStatus=evidence-read
### 单层 repair
Supervisor 只有在同一父 run 已认领原 delivery,且原回执为 `needs-repair` 或 Supervisor 明确判定语义未满足时,才能发出新的 `agent.delegate`,并把 `repairOfDelegationId` 指向该原 `delegationId`。被引用记录必须属于同一 `project-supervisor` 父 run、状态为 `claimed-by-parent`,且自身不是 repair;返工目标必须与原 delivery 的专业 Agent 完全一致。
当前可信父 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 结果继续唤醒、认领并收束到原 Supervisor Session/run;它不能创建第二条面向用户的 assistant。repair 再次 `needs-repair` 时不得继续嵌套委派,Supervisor 只能基于现有证据裁决或走用户输入门禁。`suppressed` repair 不视为已完成返工,原 `repairRequired` 门禁必须继续阻断 finalization;同一 durable action 可以在无终态字段时把原 delivery 恢复为 `dispatched`,若该 action 已持久失败,新 action 也只可在既有 repair 全部 suppressed 时创建替代的基础设施投递,不能形成第二轮语义返工。
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 仍必须逐条通过完整可信链校验。
Supervisor 认领回执后必须能够再次从 durable delivery 取回权威返工合同,不能依赖首次 `agent.run_status` observation 或模型记忆。普通 `agent.run_status` 要返回有界的 `claimedDelegateContracts` 目录,至少包含 `delegationId / targetAgentId / repairOfDelegationId / contractStatus / acceptanceCriteriaCount / expectedArtifactsCount`;带可选 `delegationId` 查询时,只允许原 `project-supervisor` 父 run 读取属于自己且已 `claimed-by-parent` 的 delivery,并返回未截断的 `delegationId / targetAgentId / acceptanceCriteria / expectedArtifacts / repairOfDelegationId / deliveryStatus / terminalStatus / contractStatus`。该查询是只读、可幂等重放的私有 observation,不返回 task 正文、Provider payload、凭据或绝对路径;合同超过明确有界输出上限时失败关闭,不能截断后让模型猜测。返工被“合同未完整继承”拒绝时,失败 observation 必须携带同一 durable delivery 的完整 `claimedDelegateContract` 权威快照,Supervisor 可直接逐字段据此修正;该字段缺失或身份不确定时才必须按原 `delegationId` 重读,不得重复无目标地轮询状态或从 action history 的摘要反推。
当前可信父 Run 认领回执后必须能够再次从 durable delivery 取回权威返工合同,不能依赖首次 `agent.run_status` observation 或模型记忆。普通 `agent.run_status` 要返回有界的 `claimedDelegateContracts` 目录,至少包含 `delegationId / targetAgentId / repairOfDelegationId / contractStatus / acceptanceCriteriaCount / expectedArtifactsCount`;带可选 `delegationId` 查询时,只允许当前可信父 Run 读取属于自己且已 `claimed-by-parent` 的 delivery,并返回未截断的 `delegationId / targetAgentId / acceptanceCriteria / expectedArtifacts / repairOfDelegationId / deliveryStatus / terminalStatus / contractStatus`。该查询是只读、可幂等重放的私有 observation,不返回 task 正文、Provider payload、凭据或绝对路径;合同超过明确有界输出上限时失败关闭,不能截断后让模型猜测。返工被“合同未完整继承”拒绝时,失败 observation 必须携带同一 durable delivery 的完整 `claimedDelegateContract` 权威快照,当前可信父 Run 可直接逐字段据此修正;该字段缺失或身份不确定时才必须按原 `delegationId` 重读,不得重复无目标地轮询状态或从 action history 的摘要反推。
### Prompt 与完成门禁
- 专业 Agent 的 task prompt 必须带完整委派合同:`delegationId / task / acceptanceCriteria / expectedArtifacts / repairOfDelegationId`,以及当前 Agent/Session/run 与父 Supervisor 身份;同时明确它只提交内部回执和证据,不直接回答正式用户。
- 结构化计划 checkpoint 只有在步骤或状态真实变化时才允许单独提交。当前 `in_progress` 步骤所需事实、权限和合同已经齐全时,Agent 必须在同一 Provider 响应附带具体 action;格式修复也必须保留原本可执行的动作意图,不能连续只改 `explanation` 或反复只调用 `update_agent_plan`。Runtime 的未完成计划 observation 和 `nextStep` 使用同一口径,真实 E2E 对 repair 创建另设有界父 loop 门禁。
- Supervisor prompt 必须明确:不得把 `evidence-ready` 当作自动语义通过,不得忽略或吞掉 `needs-repair`;对无法自行裁决的冲突、缺失决策或用户偏好,只能汇总后通过既有 `user.input_request` 向用户提问,专业 Agent 与 child 不得各自直达用户。
- finalization 在项目锁内必须确认所有必要 static delivery 已终态、ready 已认领、claim 已 Observed、允许的单次 repair 已收束;同时要求结构化计划全部完成,并清零 verification、pending confirmation、`user.input_request`、process/reconciliation、isolated join、Goal/steer 等既有 blocker。只有原 `project-supervisor` Session/run 可以随后写入唯一正式用户 assistant 和 completed 投影。
- 当前可信父 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
@@ -1,8 +1,8 @@
# 客户端素材创作无限画布阶段一合同
更新时间:`2026-08-10`
更新时间:`2026-08-15`
状态:阶段一产品与技术合同已冻结;截至 2026-08-10,客户登录态图片生成、泥点计费链路、中央进度/失败态、Tauri 正式资产提交及画布 UI 对齐阶段三至五已落地。当前产品入口按第 16 节禁用新增,并把编辑入口扩展到资源总览的全部现役类型;后续增量仍受本文合同约束。
状态:阶段一产品与技术合同已冻结;截至 2026-08-15,普通客户远端编辑统一使用陶泥儿网站登录态与固定官方服务地址,泥点计费链路、中央进度/失败态、Tauri 正式资产提交及画布 UI 对齐阶段三至五已落地。当前产品入口按第 16 节禁用新增,并把编辑入口扩展到资源总览的全部现役类型;后续增量仍受本文合同约束。
本文是网站与 AI 游戏创作 Tauri 客户端共享图片画布能力的下一阶段编码依据。若本文与资源管理阶段七的“美术编辑暂缓”口径冲突,以本文对后续素材创作切片的更新决定为准;资源总览既有布局、依赖图和只读聚焦合同继续有效。
@@ -58,7 +58,7 @@ 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 和 AppData 私有 External Editor 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 +200,7 @@ 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 节的本地合同;远端媒体编辑通过 AppData 私有 `editorApi.baseUrl/apiKey` 使用 External v1,后端按 owner 进入统一生成队列与泥点预扣/退款。素材画布工作区不显示或要求填写 Base URL / API Key,普通 Launcher、开发工作台和独立 game-chat 的独立“运行时配置”对话框均可维护这两个字段;凭据不能进入共享画布、项目 sidecar、manifest、事件或错误正文。
- 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
@@ -952,13 +952,16 @@ confirmation-required
### 14.4 首版请求范围与恢复
- 主站网页画布继续使用 `POST /api/editor/images/generations`、`POST /api/editor/images/edits` 与 `/api/runtime/external-generation/jobs/{operationId}`。AI 游戏创作 Tauri 客户端固定使用对应 `/api/external/v1/editor/images/*`,携带发布 AppData 私有 `editorApi.apiKey` 和稳定 `Idempotency-Key`,状态只查询 `GET /api/external/v1/generations/{operationId}`。两条入口复用相同请求 DTO、owner 归属和统一生成队列;客户端不读取或透传主站 Access Token,也不实现登录后自动签发 Developer API Key。
- External 图片生成和编辑支持相同 prompt、`1:1 | 2:3 | 3:2 | 9:16 | 16:9`、`0.5K | 1K | 2K`、合法 `assetKind` 与参考资源约束。refine 的 `sourceImageSrc` 必须来自源资产的 objectKey、服务端项目 resourceId 或素材 assetId;`assetObjectId` 本身不是该字段接受的引用。本地独有图片在用户确认后先走 External direct-upload ticket → OSS form → object confirm,确认后的 objectKey 才可进入生成请求。`sourceResourceId` 只在源资产确有服务端 resourceId 时发送,不能用本地 `local-asset:*`、objectKey 或 assetObjectId 冒充。额外参考最多 8 个。
- 主站网页画布与普通 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/403` 仍为 `authentication-required`。任一阶段失败都必须保持 External `operationId=null`、生成 endpoint/request body 未建立,不得进入扣费或生成提交。普通错误不得包含 ticket host、formFields、policy、signature、Token、API Key、Provider 响应正文或本机绝对路径。
- 图片参考资源准备失败按阶段投影安全错误码:本地读取/校验为 `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 响应正文或本机绝对路径。
- `accepted/running` 重启只查询原 operation;`prepared` 只以账本中的原 endpoint、原始字节和原键恢复同一 POST。轮询超时、临时鉴权/网关错误或结果未知保持可恢复,不自动转 failed 或换键扣费。
- 用户“停止等待”只撤销当前 session 的聚焦意图,不伪装远端取消。后台 command 可以继续安全 reconcile;应用退出后由项目恢复扫描继续原 operation。迟到完成可以更新原项目权威缓存和 manifest,但不能切回旧画布、清搜索或抢焦点。
- External API Key 缺失、无效或权限不足,余额不足、平台生成服务配置错误、远端 terminal failed、稳定引用缺失、下载失败、staging/正式提交失败都不得返回资源创建成功。错误只说明需要配置或检查 External Editor 凭据,不回显 Key、Authorization 或上游正文。只有 terminal failed 才允许用户通过新的独立确认建立新 intent;其它未知或对账状态必须保留原身份。
- 普通模式缺少有效登录态、刷新失败或账号权限不足,以及余额不足、平台生成服务配置错误、远端 terminal failed、稳定引用缺失、下载失败、staging/正式提交失败,都不得返回资源创建成功。错误只引导用户重新登录或检查账号权限,不要求填写 Developer API Key,也不回显 Token、Authorization 或上游正文。高级 External v1 模式才可提示检查 Developer API Key。只有 terminal failed 才允许用户通过新的独立确认建立新 intent;其它未知或对账状态必须保留原身份。
- 普通模式会话使用单调 `authGeneration` 做安装与清除 CAS。登录、刷新或换号只允许更高 generation 覆盖 GUI/Runner 内存快照;每个网络动作在发出前冻结 `ownerUserId + authGeneration`,响应解析、账本推进、媒体安装和正式提交前都必须复核仍属于当前账号。旧 generation 的迟到成功、失败或清除不得覆盖新账号状态,也不得把旧账号媒体提交到新账号项目。
- 普通模式首次遇到 `401` 时,每个 `authGeneration` 全局只允许一个 refresh 请求;其它调用等待该 Promise,但各自仍受自己的 deadline/取消信号约束。refresh 成功后以更高 generation CAS 安装新 Token,并只用原 endpoint、原始请求字节和原 `Idempotency-Key` 重试一次;不能重建正文、创建新 operation 或重新扣费。refresh 失败、账号已切换或重试仍为 `401` 时停止网络动作并保留原账本;`403` 不触发 refresh。
- 私有生成账本的普通模式服务身份固定为 `official-platform-v1 + 官方 origin + ownerUserId`,并保存创建该账本时的账号身份,不保存 Access Token、refresh Cookie 或 authGeneration。Access Token 轮换不改变 operation 身份;切号或退出会提升 generation、中止并脱离旧请求,旧账号的 `prepared/accepted/running` 账本在新账号下零网络动作、零安装、零归档。只有重新登录同一 owner 后才能继续原 POST/GET;不能把新账号下的 `401/403/404` 当作旧 operation 的终态证明。
## 15. 2026-08-06 画布 UI 对齐阶段三至五收口
@@ -979,19 +982,19 @@ 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/external/v1/editor/images/edits`;提示词、比例、尺寸、资源用途、泥点计费和原 operation 恢复继续复用现有生成合同,凭据只来自发布 AppData 私有 `editorApi.apiKey`。
- 普通客户端确认编辑后固定调用 `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/external/v1/editor/videos/generations`。有稳定远端引用时直接作为 `referenceVideoSrcs`,只有本地文件时先走 External direct-upload ticket、OSS 表单上传和 confirm,再提交同一逻辑生成;结果必须下载到新的本地文件并登记远端稳定身份。
- 音效和背景音乐分别使用 `POST /api/external/v1/editor/audios/sound-effects/generations` 与 `POST /api/external/v1/editor/audios/background-music/generations`。当前接口没有源音频引用字段,因此产品语义固定为“基于原资源语义的派生重制”,界面不得描述为对源波形的裁剪、变声或局部修改;结果仍必须引用源资源身份并保留原音频。
- 普通客户端视频使用 `POST /api/editor/videos/generations`。有稳定远端引用时直接作为 `referenceVideoSrcs`,只有本地文件时先走 `/api/assets/direct-upload-tickets`、OSS 表单上传和 `/api/assets/objects/confirm`,再提交同一逻辑生成;结果必须下载到新的本地文件并登记远端稳定身份。
- 普通客户端音效和背景音乐分别使用 `POST /api/editor/audios/sound-effects/generations` 与 `POST /api/editor/audios/background-music/generations`。当前接口没有源音频引用字段,因此产品语义固定为“基于原资源语义的派生重制”,界面不得描述为对源波形的裁剪、变声或局部修改;结果仍必须引用源资源身份并保留原音频。
- 项目版本编辑固定追加 `parentVersionId` 指向源版本的子版本,继承源版本资源绑定并记录本轮编辑提示;已有版本数组元素不可修改、删除或重排。
- 所有编辑结果固定创建新的本地 asset、文件路径、版本 ID 或资源身份。源 asset、源文件、Agent 回执与源版本不得删除、覆盖或复用;新 asset 的 `referenceResourceIds` 必须包含源资源规范身份,资源总览同时保留新旧资源。
- 各类型统一使用稳定 `operationId / Idempotency-Key`。远端 `202` 只表示受理,必须轮询原 operation;提交结果未知或登录失效时保留原身份供恢复,不能换键重提。签名 URL 不得写入 manifest,manifest 只保存稳定 objectKey 对应的资源 / 资产身份。
- External 图片 refine、视频、音效和背景音乐请求统一在 `generationInputs.source` 写入专用消费身份 `game-creator-resource-editor`;所有 External 路由必须实际读取并传递同一稳定 `Idempotency-Key`。队列完成态只向该消费身份返回经过裁剪的稳定 `objectKey / resource / asset` 引用和必要媒体元数据,不暴露 provider、worker、队列内部字段或临时签名 URL。
- 各类型统一使用稳定 `operationId / Idempotency-Key`。普通站内响应的 queued operation 与高级 External v1 的 `202` 都只表示受理,必须轮询原 operation;inline 完成则直接消费同一请求的稳定结果。提交结果未知或登录失效时保留原身份供恢复,不能换键重提。签名 URL 不得写入 manifest,manifest 只保存稳定 objectKey 对应的资源 / 资产身份。
- 图片 refine、视频、音效和背景音乐请求统一在 `generationInputs.source` 写入专用消费身份 `game-creator-resource-editor`;普通内部路由和高级 External 路由都必须实际读取并传递同一稳定 `Idempotency-Key`。队列完成态只向该消费身份返回经过裁剪的稳定 `objectKey / resource / asset` 引用和必要媒体元数据,不暴露 provider、worker、队列内部字段或临时签名 URL。
- 生成公开状态每次写入草稿都必须推进草稿 revision,并把最新 revision 同步到私有生成账本、进度事件、staging 与正式 commit;旧 UI 快照不得覆盖 accepted/running/reconciliation 状态。
- operation 已受理或首次提交结果未知后遇到 401/403,不得写成 terminal failed 或不可逆 `reconciliation-required`。私有账本保留原 remote phase、operation、原请求字节和原幂等身份;修正 External Editor API Key 配置后,已有 `operationId` 只继续 GET 同一 operation,未受理请求才允许用冻结正文和原幂等键重试 POST。
- operation 已受理或首次提交结果未知后遇到 `401`,不得写成 terminal failed 或不可逆 `reconciliation-required`。普通模式先按上述单飞流程刷新;刷新失败、换号或当前 owner 不匹配时保留原 remote phase、operation、原请求字节和原幂等身份,停止网络。重新登录同一 owner 后,已有 `operationId` 只继续 GET 同一 operation,未受理请求才允许用冻结正文和原幂等键重试 POST。高级 External v1 模式修正 Developer API Key 后遵守相同恢复规则。
- 全类型资源编辑私有账本必须冻结 `sourceAssetId / sourceMediaType / sourceAssetKind / producerTaskId / sourceVersionId` 源快照;新账本不得依赖 UI 仍停留在原资源,旧账本则只允许从当前 manifest、已完成任务产物、版本数组和受控扩展名兼容恢复。恢复结果仍要重新校验唯一来源、项目归属与媒体类型,不能把账本快照当成越权凭据。
- 私有账本的 External 配置身份只绑定规范服务地址,不绑定可轮换的 Developer API Key。升级前仍使用“服务地址 + Key”指纹的 Agent 生成账本,在原 Key 尚可用时首次恢复必须原子迁移为仅服务地址指纹;无法用当前 Key 验证时先返回与账本快照绑定的显式确认挑战,确认前零网络动作,确认时复核 operation、挑战值与当前规范服务地址,成功后原子迁移。迁移后 Key 轮换不影响原 operation;401/403/404、轮询超时或网关暂时失败都必须保留原 endpoint、请求字节、幂等键和 operation,恢复命令不允许前端重新拼请求或携带 Key。
- 普通模式私有账本绑定固定官方 origin 与 ownerUserId,不绑定可轮换的 Access Token;恢复命令不得让前端重新拼请求或把 Token 写入参数。高级 External v1 账本绑定显式服务 origin,同样不绑定可轮换的 Developer API Key。两种模式都不得因凭据轮换改变原 operation;`401/403/404`、轮询超时或网关暂时失败必须保留原 endpoint、请求字节、幂等键和 operation,并先按账本记录的模式与 owner 做隔离校验。
- pending 恢复扫描的目录上限统计所有实际目录条目,包括未知文件、非 pending 账本和损坏条目;达到上限后停止扫描并返回安全错误,不能通过堆放无关文件绕过边界。已 committed 的账本不得出现在 pending 列表中。
- 派生媒体提交必须以账本冻结的源摘要再次校验源文件;摘要、媒体身份或版本父子关系变化时失败关闭。远端派生视频二次编辑必须复用已提交账本中的稳定 `objectKey`,不能把仅用于本地登记的 `assetObjectId` 当成 generation reference。版本 journal 重放只能返回既有子版本,不得重复追加。
- 返回资源总览时,clean 草稿直接保留并退出;dirty 草稿必须使用独立确认面板提供“保留草稿并退出”和“放弃草稿”,默认保留。保留前必须等待当前保存或主动 flush,放弃才允许调用 discard。