整理项目文档并统一当前口径

- 删除过时 PRD、设计、计划和退役文档
- 收口文档索引、产品基线、玩法链路和共享记忆
- 清理历史决策重复内容、断链和本机路径
- 更新 AGC Runtime、Provider、后端与运维当前约束
This commit is contained in:
2026-08-26 10:11:46 +08:00
parent 7cb79e3aa4
commit 969dcc0272
98 changed files with 350 additions and 19679 deletions
+3 -2
View File
@@ -83,11 +83,12 @@ npm run check:encoding
## 文档入口
`docs/` 已在 `2026-05-15` 完成压缩整理,旧 PRD、设计、审计、阶段计划和技术流水账不再作为实现依据。当前只读取
`docs/` 已在 `2026-08-25` 按当前代码与运行态重新收口。旧 PRD、设计、审计、阶段计划和技术流水账不再作为实现依据;专题文档的现役清单统一从 `docs/README.md` 进入
- [docs/README.md](./docs/README.md):当前文档总入口。
- [docs/【项目基线】当前产品与工程约束-2026-05-15.md](./docs/【项目基线】当前产品与工程约束-2026-05-15.md):产品、命名、UI、协作和废弃路线。
- [docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md](./docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md)DDD 边界、API 分组、SpacetimeDB schema 规则和表目录。
- [docs/【玩法创作】平台入口与玩法链路-2026-05-15.md](./docs/【玩法创作】平台入口与玩法链路-2026-05-15.md)创作入口、草稿架和各玩法当前口径
- [docs/【玩法创作】平台入口与玩法链路-2026-05-15.md](./docs/【玩法创作】平台入口与玩法链路-2026-05-15.md)平台现役入口、项目页和画布链路
- [docs/【开发运维】本地开发验证与生产运维-2026-05-15.md](./docs/【开发运维】本地开发验证与生产运维-2026-05-15.md):本地启动、检查、部署、埋点和运营查询。
- [docs/project-memory/README.md](./docs/project-memory/README.md):团队共享的当前项目记忆、决策和未关闭事项。
- [UI_CODING_STANDARD.md](./UI_CODING_STANDARD.md):像素 UI 资产与编码规范。
-177
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,6 +1,6 @@
# UI Coding Standard
> **当前文档入口**:项目文档已压缩到 `docs/README.md` 和 4 份当前文档UI 资产和 9-slice 规则以本文为准,平台级 UI 约束见 `docs/【项目基线】当前产品与工程约束-2026-05-15.md`。
> **当前文档入口**:项目文档总入口为 `docs/README.md`UI 资产和 9-slice 规则以本文为准,平台级 UI 约束见 `docs/【项目基线】当前产品与工程约束-2026-05-15.md`,专题方案只从总入口读取
## Goal
+36 -53
View File
@@ -1,76 +1,59 @@
# 文档总览
`docs/` 只把当前融合文档和仍在维护的专题文档作为实现依据。旧创作模板、旧创作入口及其专属服务文档仅保留为历史材料,不再要求继续实现或兼容
本目录只把当前实现依据、公开契约和仍在维护的专题合同作为入口。代码、当前文档与项目记忆冲突时,以当前代码和最新专题文档为准;未列入下表的材料不作为实现依据
## 必读入口
1. [Agent 工作入口与执行准则](./【协作规范】Agent工作入口与执行准则-2026-06-22.md)
2. [当前产品与工程约束](./【项目基线】当前产品与工程约束-2026-05-15.md)
3. [server-rs 与 SpacetimeDB 数据契约](./【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md)
4. [平台入口与玩法链路](./【玩法创作】平台入口与玩法链路-2026-05-15.md)
5. [本地开发验证与生产运维](./【开发运维】本地开发验证与生产运维-2026-05-15.md)
6. [AI 游戏创作项目开发工作台 PRD](./prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md)
7. [AI 游戏创作智能体 App 实施计划](./technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md)
8. [客户端素材创作无限画布阶段一合同](./technical/【技术方案】客户端素材创作无限画布阶段一合同-2026-08-05.md)
4. [本地开发验证与生产运维](./【开发运维】本地开发验证与生产运维-2026-05-15.md)
5. [项目记忆入口](./project-memory/README.md)
团队长期约定、决策、流程和排障摘要统一从 [项目记忆入口](./project-memory/README.md) 读取。代码、当前融合文档与项目记忆冲突时,以代码和最新融合文档为准。
## 当前产品与平台
## 当前专题
- [当前产品与工程约束](./【项目基线】当前产品与工程约束-2026-05-15.md):现役入口、账号钱包、UI 和后端分层。
- [平台入口与玩法链路](./【玩法创作】平台入口与玩法链路-2026-05-15.md):只描述现役平台壳与旧模板退役边界。
- [外部 OpenAPI 与 API Key 接入方案](./【后端架构】外部OpenAPI与APIKey接入方案-2026-06-19.md)
- [External v1 OpenAPI](./openapi/genarrative-external-v1.openapi.json):公开 HTTP 契约唯一机器可读来源。
### AI 游戏创作与 Agent Runtime
## AI 游戏创作与 Agent Runtime
- [AI 游戏创作智能体 App 实施计划](./technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md)
- [立项策划 AgentFast GDD)技术方案](<./technical/【技术方案】立项策划AgentFast GDD-2026-08-10.md>)
- [AI 游戏创作 Agent Runtime V1.1](<./technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md>)
- [AI 游戏创作智能体 App 实施计划](./technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md):当前 DirectProject、受控语义工具、UI workflow、资源和运行时合同。
- [项目开发工作台 PRD](./prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md):当前工作台页面和验收边界。
- [立项策划 AgentFast GDD](<./technical/【技术方案】立项策划AgentFast GDD-2026-08-10.md>):当前策划入口、审批和恢复合同。
- [GameAgent 资源自由画板与快速编辑](./technical/【技术方案】GameAgent资源自由画板与快速编辑-2026-08-20.md)
- [UI 工作流资源桥接与 Runtime 执行](./【技术方案】UI工作流资源桥接与Runtime执行-2026-08-24.md)
- [UI 编辑器 Godot 容器布局](./technical/【技术方案】UI编辑器Godot容器布局模型-2026-08-18.md)
- [UI 编辑器子节点显示规则](./technical/【技术方案】UI编辑器子节点显示规则-2026-08-18.md)
- [UI 编辑会话模块边界](./technical/【前端架构】UI编辑会话模块边界-2026-08-19.md)
### 图片编辑器与 Agent
## 图片画布与媒体
- [客户端素材创作无限画布阶段一合同](./technical/【技术方案】客户端素材创作无限画布阶段一合同-2026-08-05.md)
- [图片画布编辑器 MVP 接入方案](./technical/【前端架构】图片画布编辑器MVP接入方案-2026-06-11.md)
- [图片画布编辑器前端拆分计划](./technical/【端架构】图片画布编辑器前端拆分计划-2026-06-17.md)
- [图片画布游戏场景生成链路](./technical/【技术方案】图片画布游戏场景生成链路-2026-08-04.md)
- [画板音乐生成入口设计](./【编辑器】画板音乐生成入口设计-2026-06-18.md)
- [SFX 生成优化 V2.0 任务拆解](./project-memory/plans/【实施计划】SFX生成优化V2.0任务拆解-2026-08-06.md)
- [SFX 生成优化 V2.0 T6 测试与发布门禁](./【实施记录】SFX生成优化V2.0T6测试与发布门禁-2026-08-07.md)
- [音频生成 Composer 恢复共享分流方案](./project-memory/plans/【前端重构】音频生成面板恢复共享分流方案-2026-08-06.md)
- [BGM 提示词优化 T6 测试与发布门禁](./【实施记录】BGM生成提示词优化T6测试与发布门禁-2026-08-05.md)
- [图片画布结构化持久化与迁移回滚](./【编辑器】图片画布结构化持久化与迁移回滚方案-2026-07-19.md)
- [编辑器生成结果原子提交与幂等重放](./technical/【端架构】编辑器生成结果原子提交与幂等重放方案-2026-08-06.md)
- [画板音乐生成入口](./【编辑器】画板音乐生成入口设计-2026-06-18.md):BGM/SFX 共享视图、独立业务规则和当前发布门禁。
- [画布 Agent 对话面板](./【编辑器】画布Agent对话面板-2026-07-03.md)
- [画布 Agent 会话消息存 OSS](./adr/【ADR】画布Agent会话消息存OSS-2026-07-03.md)
- [图片画布撤销范围与操作提示方案](./【图片画布】撤销范围与操作提示方案-2026-07-17.md)
- [编辑器模型定价配置](./【编辑器】模型定价配置管理方案-2026-06-22.md)
## 后端、运维与测试
- [BgFilter 受限资源调度方案](./technical/【后端架构】BgFilter受限资源调度方案-2026-07-21.md)
- [SpacetimeDB 连接池取消安全](./【后端架构】SpacetimeDB连接池租约Drop兜底与取消安全-2026-06-11.md)
- [Jenkins 容器预览部署控制面](./technical/【开发运维】Jenkins容器预览部署控制面技术方案-2026-08-15.md)
- [浏览器内 AI Web 工程沙箱预览](./technical/【技术方案】浏览器内AIWeb工程沙箱预览方案-2026-06-13.md)
- [AI Web 工程 Runner 安全模型](./technical/【安全模型】AIWeb工程Runner与预览隔离威胁模型-2026-06-13.md)
### 后端与公开数据
- [外部生成 Worker 化方案](./technical/【后端架构】外部生成Worker化方案-2026-06-03.md)
- [BgFilter 受限资源调度方案(同步内部 HTTP 原地等待版)](./technical/【后端架构】BgFilter受限资源调度方案-2026-07-21.md)
- [统一公开作品 Read Model 设计](./technical/【后端架构】统一公开作品ReadModel设计-2026-05-26.md)
- [外部 OpenAPI 与 API Key 接入方案](./【后端架构】外部OpenAPI与APIKey接入方案-2026-06-19.md)
- [SpacetimeDB 连接池取消安全](./【后端架构】SpacetimeDB连接池租约Drop兜底与取消安全-2026-06-11.md)
### 后台、宿主壳与运维
- [Dashboard 运营看板方案](./technical/【后台管理】Dashboard运营看板方案-2026-06-23.md)
- [Jenkins 容器预览部署控制面](./technical/【开发运维】Jenkins容器预览部署控制面技术方案-2026-08-15.md)
- [后台多账号与 Tab 访问权限](./technical/【后台管理】多账号与Tab访问权限方案-2026-07-14.md)
- [宿主壳能力统一协议](./【前端架构】宿主壳能力统一协议-2026-06-17.md)
- [Expo React Native 与 Tauri 宿主壳方案](./【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md)
- [Pingora 独立网关试点](./technical/【开发运维】Pingora独立网关试点-2026-06-11.md)
- [本地 SSH 服务器管理面板](./technical/【开发运维】本地SSH服务器管理面板技术方案-2026-06-11.md)
### 测试与协作
- [npm workspaces 统一依赖边界](./technical/【技术方案】npm-workspaces统一依赖边界-2026-08-21.md)
- [React 组件测试准则](./technical/【前端测试】React组件测试准则-2026-06-26.md)
- [AI Web 工程静态预览验收清单](./technical/【测试用例】AIWeb工程静态预览MVP验收清单-2026-06-13.md)
- [当前阶段规划](./planning/README.md)
- [宿主壳能力统一协议](./【前端架构】宿主壳能力统一协议-2026-06-17.md)
- [Expo React Native 与 Tauri 宿主壳方案](./【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md)
## 历史文档边界
## 维护规则
- 旧创作模板、旧创作入口、旧运行态和旧素材生成方案不再从本页索引,也不再作为修复目标
- `maincloud`、旧 Node/Express/PostgreSQL/Go 后端和人工 `spacetime --root-dir` 口径均已废弃
- 历史文档不得覆盖当前融合文档、代码契约或 `docs/project-memory/shared-memory/decision-log.md` 中更新的决策
## 命名规则
后续新增 Markdown 文档文件名使用 `【标签名】中文标题-日期.md`。历史文件不做无关批量重命名;本次涉及的旧文档可直接删除或在当前入口中取消引用。
- 当前文档只保留稳定合同、公开契约和仍在推进的专题;一次性计划、实施记录和已关闭实验完成后删除或融合,不再长期堆积
- `docs/project-memory/shared-memory/` 只保存长期有效的概览、决策、流程和踩坑;`plans/``todos/` 仅保存仍开放且有明确下一门禁的事项
- 修改 `/api/external/v1` 必须同步 OpenAPI 和契约测试;修改 SpacetimeDB schema 必须同步 migration、表目录、绑定和 schema 检查
- 旧模板、旧公开作品、旧运行态和旧后端路线不因历史源码或数据表仍存在而恢复入口。
- 新增 Markdown 使用 `【标签名】中文标题-YYYY-MM-DD.md` 命名;不要把个人配置、密钥、Token、日志或构建产物写入文档。
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,48 +0,0 @@
# 寓教于乐 马路街区式横向世界入口概念图
更新时间:`2026-05-23`
## 背景
寓教于乐板块需要继续探索图形化玩法入口。前一轮“乐园地图 / 世界地图”方向已被证明不够贴近参考图,本轮进一步收敛为“中央马路串联主题小建筑群街区”的结构,让每一屏都像一个可横向滑动的儿童小镇街区。
## 参考结论
从参考图和视频里提炼出的关键结构是:
1. 每一屏都是一组主题小建筑群,不是稀疏乐园点位。
2. 中央马路是主路径,汽车沿路通过,边缘继续延伸到下一屏。
3. 建筑群贴着道路两侧聚合,形成清晰街区,而不是围绕中央广场或环形路径展开。
4. 左右两边都要有明确“可继续探索”的出画感,方便后续做横向滑动世界。
## 目标
- 视觉上像可滑动的儿童街区地图。
- 每一屏都能作为独立探索单元,并且能自然接到前后相邻屏。
- 保持寓教于乐既有的卡通绘本风,不借用真实品牌乐园或现成 IP。
- 适合后续叠加入口按钮、焦点框和中文标题。
## 本次概念方向
1. 识物认知主街
2. 绘画创作工坊街
3. 运动音乐街区
4. 自然探索实验大道
## 推荐方向
优先推荐 `绘画创作工坊街``运动音乐街区`。这两条在当前批次里最接近“中央马路 + 两侧主题小建筑群 + 左右可延展”的参考结构。
## 生图脚本
- 生成脚本:`scripts/generate-edutainment-road-town-map-concepts.mjs`
- 输出目录:`output/imagegen/edutainment-road-town-map-concepts-20260523/`
- 风格参考:`public/child-motion-demo/picture-book-grass-stage.png`
## 说明
本次产物是设计概念稿,不直接进入正式资源目录。后续如果继续收敛,可以以 `城市公园脊` 为母版,向左、向右补相邻屏幕的区域内容。
## 当前结论
乐园分区结构可以抛弃,后续所有概念都优先按“马路街区式一屏一屏延展”的结构继续迭代。
@@ -1,36 +0,0 @@
# 寓教于乐电视端乐园地图入口概念图
更新时间:`2026-05-18`
## 背景
寓教于乐板块需要一个面向电视端 / 横屏大屏的图形化入口,整体感觉接近主题乐园地图,但必须保留 Genarrative 现有的明亮卡通绘本插画风,不借用任何真实品牌乐园或版权角色。
## 目标
- 远看像一个完整乐园地图,近看能分辨每个玩法入口。
- 入口区域清晰分区,后续可以叠加焦点框、按钮和中文标题。
- 中心和下方保留足够留白,适合遥控器焦点、儿童角色或主推荐位。
- 风格保持和寓教于乐现有草地舞台资源一致。
## 本次概念方向
1. 环形乐园岛:中央草地广场 + 外圈入口环路。
2. 展开绘本地图:横向展开的大绘本页,左右页自然衔接。
3. 云朵空中岛:多个浮岛通过彩虹桥和云朵步道连接。
4. 草地舞台地图:更接近实际运行态的横屏草地入口首屏。
## 推荐方向
优先推荐 `草地舞台地图` 作为后续落地主方向,因为它与现有寓教于乐草地舞台最接近,且中央下方留白最适合后续叠加交互焦点。
## 生图脚本
- 生成脚本:`scripts/generate-edutainment-tv-map-concepts.mjs`
- 默认尺寸:`2048x1152`
- 风格参考:`public/child-motion-demo/picture-book-grass-stage.png`
- 输出目录:`output/imagegen/edutainment-tv-map-entry-concepts-20260518/`
## 说明
本次结果是设计概念稿,不直接进入 `public/` 正式资源目录。后续若要继续细化,可在同一脚本里增加新的横屏变体,并保持“不写文字、不露品牌 IP、绘本插画风”这三条底线。
-13
View File
@@ -1,13 +0,0 @@
# 规划与优先级
本目录保存仍处于推进中的阶段计划、并行任务拆分、可派发任务包和验收顺序。长期稳定的产品与架构口径仍以根部融合文档为准。
## 当前计划
- [【玩法创作】创作流程统一总计划-2026-05-30.md](./【玩法创作】创作流程统一总计划-2026-05-30.md):创作入口、统一创作页、统一生成页、结果页、发布、作品架、广场和运行态的阶段计划、进度记录、并行波次和可直接派发的任务包。
## 维护规则
- 计划文档只记录可执行阶段、负责人切分、验收门禁和当前状态。
- 已经稳定为长期约定的内容,应同步沉淀到 `docs/【玩法创作】平台入口与玩法链路-2026-05-15.md``docs/project-memory/shared-memory/`
- 若代码事实与计划冲突,以代码和当前融合文档为准,并回写更新本目录。
@@ -1,375 +0,0 @@
# 创作流程统一总计划
更新时间:`2026-05-30`
## 总览
| 项目 | 当前值 |
| --- | --- |
| 总轮次 | 5 |
| 当前轮次 | Round 4(已收口) |
| 当前阶段 | Phase 6 |
| 当前状态 | Phase 0~6 已收口;统一创作页已升级为 `UnifiedCreationWorkspace`,平台壳不再直接依赖旧工作台文件 |
| 当前并行波次 | 波次 D(验收与冻结) |
| 当前重点 | 后续新增玩法按仓库入口规范、当前开发运维文档和现役定向测试验收 |
## 目标与范围
本计划统一 Genarrative 所有玩法的创作链路,不再只跟踪首批的拼图、抓大鹅和敲木鱼。最终目标是让各玩法按同一条平台链路交付:
```text
创作入口 -> 统一创作页/工作台 -> 统一生成页 -> 结果页 -> 试玩 -> 发布 -> 统一作品详情/作品架/广场 -> 正式 runtime
```
统一不是把所有玩法 UI 做成同一个表单,而是统一阶段、契约、恢复、生成反馈、错误承接、发布后去向和验收门禁。各玩法工作台仍负责真实输入控件、资产槽位、校验和提交。
## 当前进度
| 阶段 | 状态 | 说明 |
| --- | --- | --- |
| Phase 0 总计划与门禁 | 已完成 | 本文档、`docs/planning/README.md``docs/README.md``docs/project-memory/shared-memory/document-map.md` 已补齐入口;后续按 phase 扩展门禁。 |
| Phase 1 首批统一壳 | 已收口 | `puzzle``match3d``jump-hop``wooden-fish` 已接入 `UnifiedCreationPage` / `UnifiedGenerationPage`,竖屏滚动和字段契约已回归。 |
| Phase 1 补充统一壳 | 已收口 | `jump-hop` 也已接入 `UnifiedCreationPage` / `UnifiedGenerationPage`,统一创作页现在接管拼图、抓大鹅、跳一跳和敲木鱼四条入口的可见外壳与滚动。 |
| Phase 2 契约与配置治理 | 已完成 | `creationTypes[].unifiedCreationSpec`、前端 fallback、后台配置校验和文档门禁已按现有测试与 schema 检查收口。 |
| Phase 3 剩余表单/图片工作台接入 | 已收口 | 跳一跳、宝贝识物、方洞结果页与首批普通工作台回归已通过;方洞、大鱼按当前形态纳入最小回归,后续若迁移工作台再单独立项。 |
| Phase 4 特殊工作台接入策略 | 已收口 | RPG、视觉小说、汪汪声浪的最小例外/闭环回归已通过,例外口径已落到平台总链路文档。 |
| Phase 5 结果页、发布、作品架与广场收口 | 已收口 | 结果页、发布、公开详情、推荐 runtime 与公开 read model 最小自动回归已通过,公开详情作者展示口径已统一。 |
| Phase 6 全链路验收与冻结 | 已收口 | 跨玩法 smoke、移动端优先验收、回归矩阵、长期维护规则和冻结证据已补齐。 |
此表即总进度记录,后续每次 phase 收口、启动或回退时,只更新这里和下方任务状态。
当前已完成 Round 0~4 / Phase 0~6。后续新增玩法或统一链路改动以仓库入口规范、当前开发运维文档和现役定向测试为质量基线。
## 执行轮次
按可交付批次拆成 5 轮(Round 0~4)。当前已完成 Round 0~4Round 4 / 波次 D 已作为冻结基线收口。
| 轮次 | 覆盖阶段 | 目标 | 状态 |
| --- | --- | --- | --- |
| Round 0 | Phase 0 | 补齐总计划、文档入口和并行任务表 | 已完成 |
| Round 1 | Phase 2 | 契约与配置治理 | 已完成 |
| Round 2 | Phase 3 + Phase 4 | 普通工作台并行接入,特殊工作台先定例外边界 | 已完成 |
| Round 3 | Phase 5 | 结果页、发布、作品架与广场收口 | 已完成 |
| Round 4 | Phase 6 | 全链路验收与冻结 | 已完成 |
## 阶段拆分
### Phase 0:总计划与执行门禁
目标:让团队有一个唯一可查的总计划、进度表和并行任务清单。
状态:已完成。
- 新增本计划文档和 `docs/planning/README.md`,并在 `docs/README.md``docs/project-memory/shared-memory/document-map.md` 中补上规划入口。
- 补齐 `当前进度``执行轮次` 和可并行任务表,后续每个 phase 完成后更新本文档的状态、验收命令和风险。
退出条件:
- 文档入口可从 `docs/README.md` 找到。
- 总计划包含阶段、进度、并行任务、验收和风险。
### Phase 1:首批统一壳收口
目标:用低风险的四条链路验证统一创作/生成壳。
- 范围:`puzzle``match3d``jump-hop``wooden-fish`
- 创作页统一经过 `UnifiedCreationPage`,工作台保留各自真实输入能力。
- 生成页统一经过 `UnifiedGenerationPage``CustomWorldGenerationView`
- 竖屏滚动由统一创作页承担,避免内层滚动窗。
状态:已收口。
### Phase 2:契约与配置治理
目标:把统一创作页从前端“能渲染”推进到平台配置“可治理”。
- 明确 `unifiedCreationSpec` 的字段种类、必填语义、阶段映射和兼容 fallback。
- 后台配置、前台读取和 `api-server` 路由熔断继续以 SpacetimeDB 入口配置为事实源。
- 前端本地 fallback 只服务旧后端或本地异常,不作为新增玩法事实源。
- 为字段契约、入口开放状态、阶段映射补自动测试。
退出条件:
- `creation-entry config` 契约在前后端文档中闭合。
- 新增玩法不能绕过统一入口配置接线。
状态:已完成。
验证:`npm run check:encoding``npm run typecheck``npm run admin-web:typecheck``npm run check:spacetime-schema` 和统一创作页 / 统一生成页相关测试已通过。
### Phase 3:剩余表单/图片工作台接入
目标:把结构相近的玩法先迁到统一创作与生成壳,扩大覆盖面。
候选范围:
- 第一批直接迁移:`jump-hop``baby-object-match`
- 需要先做工作台形态评估:`square-hole``big-fish`
- 其它已经是表单/图片输入工作台、且无复杂多阶段编辑器的玩法
统一要求:
- 继续复用 `CreativeImageInputPanel``CreativeAudioInputPanel` 等现有通用输入组件。
- 不在工作台 UI 中默认写规则说明或功能解释。
- 自动素材生成走统一生成页;没有自动生成的玩法需要明确跳过生成页的阶段策略。
- 结果页和 runtime 不因迁移创作页而改业务真相。
- `square-hole``big-fish` 先评估是否保留 Agent 形态还是迁到表单/图片工作台,再决定是否进入直接迁移实现。
- `jump-hop` 已纳入统一创作壳,后续若要调整字段或视觉,只能在统一壳与工作台之间协同改,不再恢复独立入口壳。
退出条件:
- 每个接入玩法都有创作页、生成页或跳过生成页的明确验收。
- 移动端竖屏能从标题、表单滚动到提交按钮。
状态:已收口。
2026-05-30 回归记录:
- `jump-hop``baby-object-match``big-fish``square-hole` 的核心工作台 / 结果页 / runtime 测试已补齐并通过。
- `jump-hop` 结果页刷新恢复已补齐 `profileId -> getWorkDetail` 回读;直达 `/creation/jump-hop/result` 且缺少恢复参数时显示“跳一跳草稿未恢复”恢复面板,不再白屏。
- `square-hole` 结果页的试玩 / 发布路径已补齐服务 mock 回归,确认保存成功后才触发试玩和发布回调。
- 首批普通工作台回归通过:拼图、抓大鹅、敲木鱼、跳一跳、宝贝识物、方洞结果页。
- 竖屏浏览器 smoke 已覆盖 `/creation/jump-hop``/creation/baby-object-match``/creation/square-hole``/creation/bark-battle``/creation/visual-novel``/creation/jump-hop/generating``/creation/jump-hop/result``/runtime/jump-hop`,截图保存在 `.app/browser-check/phase-flow-20260530/`
### Phase 4:特殊工作台接入策略
目标:处理不能直接套表单/图片工作台的玩法,先定边界再迁移。
候选范围:
- RPG / 自定义世界
- 视觉小说
- 汪汪声浪(`bark-battle`
- 其它多阶段编辑器、对话式 Agent 或特殊创作流
统一要求:
- 必须在玩法文档中写明“创作工具模式例外”。
- 例外只影响工作台内部,不影响入口配置、生成反馈、结果页、发布、作品架、广场和 runtime 的平台主链路。
- 对话式或多阶段编辑器仍需和统一作品、统一错误、统一生成完成反馈对齐。
- `bark-battle` 默认按特殊工作台收口;若后续产品决策确认可完全表单化,再单独前移到 Phase 3,不在本轮默认假设里。
退出条件:
- 每个特殊玩法都有例外声明、阶段映射和验收清单。
- 没有新增平行入口系统、平行作品架或平行公开列表。
状态:已收口。
2026-05-30 回归记录:
- RPG 例外边界指定 interaction 测试通过。
- Bark Battle 创作入口、结果页试玩/发布和正式 runtime 指定 interaction 测试通过。
- 视觉小说工作台、生成阶段、结果页和运行态测试通过,当时的视觉小说负向扫描无异常。
### Phase 5:结果页、发布、作品架与广场收口
目标:把“创作页统一”推进到“交付链路统一”。
- 发布成功默认进入统一作品详情或明确的 runtime 去向。
- 草稿架能恢复生成中、失败、待发布和已发布状态。
- 公开列表、发现流、详情页优先消费后端 read model 或 BFF 缓存。
- 跨流程错误统一进入 `PlatformErrorDialog`,异步完成统一进入 `PlatformTaskCompletionDialog`
- 私有 generated 图片展示前必须换签。
退出条件:
- 每个可发布玩法都有作品架、公开详情、广场或明确不公开声明。
- 生成中刷新、失败重试、发布后回读和登录切换都有测试或手测记录。
状态:已收口。
2026-05-30 回归记录:
- 发布到作品详情、已发布作品进入详情、体验按钮直达 runtime、详情 profile 回读指定 interaction 测试通过。
- 拼图已发布作品进入首页和移动端游戏分类、Big Fish 公开隐藏口径、Match3D 推荐 runtime 资源回读指定 interaction 测试通过。
- 公开详情作者展示统一为“公开昵称 · 陶泥号”,`PlatformWorkDetailView` 与公共作者展示 helper 测试已回归。
- 本地 API smoke 已在重新拉起 `dev:spacetime``dev:api-server` 后通过:`GET http://127.0.0.1:8082/healthz` 返回 `{"ok":true,"service":"genarrative-api-server"}`
### Phase 6:全链路验收与冻结
目标:形成后续新增玩法可复用的稳定门禁。
- 按玩法输出创作入口、生成页、结果页、试玩、发布、作品架、广场、runtime smoke 矩阵。
- 当时补齐跨玩法回归 / 冒烟矩阵,不再只覆盖首批四条链路;当前执行入口已收敛到根 `package.json` 和开发运维文档。
- 固化移动端竖屏优先验收,桌面端作为兼容验证。
- 补齐“新增玩法接入 PRD 检查块”和代码评审检查清单。
退出条件:
- 全部计划内玩法均有明确状态:已统一、例外接入、暂不接入。
- `npm run typecheck``npm run check:encoding` 和对应玩法门禁通过。
状态:已收口。
2026-05-30 冻结记录:
- Phase 2 自动回归通过:入口配置、统一字段 spec、统一创作页和统一生成页测试共 11 项。
- Phase 3 自动回归通过:拼图、抓大鹅、敲木鱼、跳一跳、宝贝识物、大鱼、方洞结果页相关测试共 67 项;跳一跳直达结果页恢复测试通过。
- Phase 4 / Phase 5 指定交互回归通过:RPG 例外边界、Bark Battle 闭环、作品详情、推荐 runtime、公开 read model 与跳一跳恢复相关 interaction 测试共 18 项。
- Phase 5 详情 / 弹窗 / 作品架回归通过:公开详情、错误弹窗、反馈弹窗、作品展示 helper、作品架交互测试共 63 项。
- 当时的视觉小说负向扫描、`npm run check:spacetime-schema``npm run check:encoding` 均通过。
- API smoke 通过:`GET http://127.0.0.1:8082/healthz` 返回 `{"ok":true,"service":"genarrative-api-server"}`
- 竖屏浏览器 smoke 通过并保存截图:`.app/browser-check/phase-flow-20260530-round5/`,覆盖 `/creation/jump-hop``/creation/visual-novel``/creation/square-hole``/creation/bark-battle``/creation/baby-object-match``/creation/jump-hop/generating``/creation/jump-hop/result``/runtime/jump-hop`
### Phase 6 补充:跨玩法最小验收口径
Phase 6 不再继续拆新波次,当前只把 Phase 2 到 Phase 5 的最小验证集合收束成一份可直接执行的门禁矩阵。建议顺序如下:
| 阶段 | 最小命令 | 说明 |
| --- | --- | --- |
| Phase 2 | `npm run check:encoding``npm run typecheck``npm run admin-web:typecheck``npm run test -- src/components/platform-entry/platformEntryCreationTypes.test.ts src/components/unified-creation/unifiedCreationSpecs.test.ts src/components/unified-creation/UnifiedCreationPage.test.tsx src/components/unified-creation/UnifiedGenerationPage.test.tsx` | 校验入口配置、统一字段 spec、统一创作页和统一生成页。 |
| Phase 3 | `npm run test -- src/components/unified-creation/workspaces/PuzzleCreationWorkspace.interaction.test.tsx src/components/unified-creation/workspaces/Match3DCreationWorkspace.interaction.test.tsx src/components/unified-creation/workspaces/WoodenFishCreationWorkspace.test.tsx src/components/unified-creation/workspaces/JumpHopCreationWorkspace.test.tsx src/components/jump-hop-result/JumpHopResultView.test.tsx src/components/jump-hop-runtime/JumpHopRuntimeShell.test.tsx src/components/edutainment-creation/BabyObjectMatchWorkspace.test.tsx src/components/edutainment-result/BabyObjectMatchResultView.test.tsx src/components/edutainment-runtime/BabyObjectMatchRuntimeShell.test.tsx src/components/big-fish-creation/BigFishAgentWorkspace.interaction.test.tsx src/components/big-fish-result/BigFishResultView.test.tsx src/components/big-fish-runtime/BigFishRuntimeShell.test.tsx``npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "direct jump hop result route"` | 校验普通表单 / 图片 / 音频工作台仍按结构化 payload 提交,跳一跳结果页直达恢复不白屏,并把 BabyObjectMatch / BigFish 一并纳入最小回归。 |
| Phase 4 | `npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "opening RPG agent workspace does not refetch session snapshot in a render loop|create tab resumes agent workspace when draft has no compiled result yet|create tab resumes agent workspace when session has no draft profile even if summary counts look compiled|opening a compiled draft with a missing agent session falls back to draft hub"``npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "create tab opens bark battle entry form from the template card|bark battle draft result can test before publish and publish to work detail|direct bark battle runtime public code opens published runtime"``npm run test -- src/components/visual-novel-creation/VisualNovelAgentWorkspace.test.tsx src/components/visual-novel-result/VisualNovelResultView.test.tsx src/components/visual-novel-runtime/VisualNovelRuntimeShell.test.tsx` | 校验特殊工作台例外、Bark Battle 公开闭环和视觉小说现役链路。 |
| Phase 5 | `npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "agent draft result publishes to gallery from publish panel|creation hub published work enters existing detail view|creation hub published work experience button enters world directly|creation hub published work start uses loaded detail profile instead of library summary"``npm run test -- src/components/rpg-entry/RpgEntryFlowShell.agent.interaction.test.tsx -t "published puzzle works appear on home and mobile game category channel|published big fish works stay hidden from platform home and mobile game category channel|home recommendation Match3D runtime keeps profile generated models when card summary is stale|home recommendation Match3D runtime passes top-level UI background assets|home recommendation Match3D runtime reloads detail when card only has UI assets"``npm run test -- src/components/platform-entry/PlatformWorkDetailView.test.tsx src/components/platform-entry/PlatformErrorDialog.test.tsx src/components/platform-entry/PlatformFeedbackView.test.tsx src/components/rpg-entry/rpgEntryWorldPresentation.test.ts``npm run test -- src/components/custom-world-home/CustomWorldCreationHub.test.tsx src/components/custom-world-home/CustomWorldCreationHub.interaction.test.tsx` | 校验结果页、发布、作品架、公开详情、推荐 runtime 和公开 read model,并补公开详情作者展示口径与作品架恢复矩阵。 |
如果这轮还改了 SpacetimeDB schema,追加 `npm run check:spacetime-schema`;如果还改了 API 路由、BFF、公开列表或 `/works/detail` 回读,追加 `npm run dev:api-server`,并另开终端从 `.app/dev-stack.json` 读取实际 `api-server` URL 后检查 `/healthz`
## 可并行任务列表
| 任务 ID | 可并行 | 状态 | 任务 | 主要产出 | 依赖 | 建议 Owner |
| --- | --- | --- | --- | --- | --- | --- |
| T0-1 | 否 | 已完成 | 总计划与文档入口 | 本文档、`docs/planning/README.md`、文档索引更新 | 无 | 文档 owner |
| T1-1 | 否 | 已完成 | Phase 1 收口确认 | 三条首批链路验收记录、已知风险 | T0-1 | 前端 owner |
| T2-1 | 是 | 已完成 | `unifiedCreationSpec` 契约审计 | 字段种类、必填、阶段映射、fallback 规则 | T0-1 | 契约 owner |
| T2-2 | 是 | 已完成 | 后台入口配置治理 | 后台配置校验与配置说明 | T2-1 | 后台 owner |
| T2-3 | 是 | 已完成 | 前端入口读取与 fallback 测试 | 入口配置单测、异常兜底测试 | T2-1 | 前端 owner |
| T3-1 | 是 | 自动回归通过 | 跳一跳统一接入方案与实现 | 统一创作工作台、生成页迁移、验收 | T2-1 | 玩法 owner A |
| T3-2 | 是 | 自动回归通过 | 宝贝识物统一接入方案与实现 | 创作页/生成页迁移、验收 | T2-1 | 玩法 owner B |
| T3-3 | 是 | 最小回归通过 | 方洞工作台形态评估与迁移方案 | 保留 Agent 形态还是迁表单的决策、边界和风险清单 | T2-1 | 玩法 owner C |
| T3-4 | 是 | 最小回归通过 | 大鱼工作台形态评估与迁移方案 | 保留 Agent 形态还是迁表单的决策、边界和风险清单 | T2-1 | 玩法 owner D |
| T4-1 | 是 | 自动回归通过 | RPG 例外边界设计 | 例外声明、阶段映射、验收清单 | T2-1 | 特殊玩法 owner |
| T4-2 | 是 | 自动回归通过 | 视觉小说例外边界设计 | 例外声明、阶段映射、验收清单 | T2-1 | 特殊玩法 owner |
| T4-3 | 是 | 自动回归通过 | 汪汪声浪(bark-battle)统一/例外决策 | 接入或例外方案、验收清单 | T2-1 | 特殊玩法 owner |
| T5-1 | 是 | 最小回归通过 | 统一结果页能力矩阵 | 每个玩法结果页能力与缺口表 | T3/T4 方案稳定 | 结果页 owner |
| T5-2 | 是 | 最小回归通过 | 作品架恢复矩阵 | 生成中、失败、待发布、已发布恢复验收 | T3/T4 方案稳定 | 作品架 owner |
| T5-3 | 是 | 最小回归通过 | 公开 read model 对齐 | 广场/详情/分享码缺口与执行清单 | T3/T4 方案稳定 | 后端 owner |
| T5-4 | 是 | 最小回归通过 | 统一错误与完成反馈回归 | `PlatformErrorDialog``PlatformTaskCompletionDialog` 覆盖 | T3/T4 方案稳定 | 平台壳 owner |
| T5-5 | 是 | 自动回归通过 | 统一创作壳滚动收口 | `UnifiedCreationPage` 统一接管四条入口滚动、跳一跳纳入统一壳 | T3/T4 方案稳定 | 平台壳 owner |
| T6-1 | 否 | 已完成 | 全链路质量门禁扩展 | Phase 2 到 Phase 5 最小验证集合;现已收敛到根脚本和开发运维文档 | T3/T4/T5 完成 | QA owner |
| T6-2 | 否 | 已完成 | 全量验收与冻结 | 状态表、未接入声明、最终测试记录 | T6-1 | Release owner |
并行原则:
- T2 系列已完成,T3/T4 已进入回归;后续缺口修补仍不得绕过 T2 已固定的入口配置和统一 spec 规则。
- T3 各玩法可并行,但同一文件同一时间只允许一个 owner,尤其是 `PlatformEntryFlowShellImpl.tsx`、路由和 shared contracts。
- T5 可以在 T3/T4 各玩法方案稳定后分块并行,不必等所有玩法实现完再开始。
- T6 必须串行收尾,避免验收矩阵和实际实现漂移。
## 可直接派发的任务包
任务包是执行层最小分工单元。每个包都可以单独开分支、单独验收;如果两个包需要改同一个公共文件,先由公共 owner 合并接口或壳层改动,再由玩法 owner 接入,避免互相覆盖。
| 包 ID | 可并行对象 | 状态 | 目标 | 不做什么 | 交付物 | 验收 |
| --- | --- | --- | --- | --- | --- | --- |
| P2-A 契约包 | 可与 P2-B、P2-C 并行 | 已完成 | 固定 `unifiedCreationSpec` 字段类型、必填、阶段映射、fallback 规则 | 不接新玩法,不改 UI 设计方向 | 前后端契约、配置字段文档、契约测试 | `npm run test -- src/components/unified-creation/unifiedCreationSpecs.test.ts src/components/platform-entry/platformEntryCreationTypes.test.ts`;涉及 schema 时追加 `npm run check:spacetime-schema` |
| P2-B 后台配置包 | 可与 P2-A、P2-C 并行 | 已完成 | 后台入口配置能编辑、校验、保存统一创作契约 | 不做玩法工作台迁移 | 后台表单、保存校验、异常提示、后台单测 | `npm run admin-web:typecheck``npm run test -- apps/admin-web/src/pages/AdminCreationEntrySwitchPage.test.tsx` |
| P2-C 前台读取包 | 可与 P2-A、P2-B 并行 | 已完成 | 前台从 `/api/creation-entry/config` 读取统一 spec,旧后端只走兜底 | 不把 fallback 当事实源,不恢复硬编码入口 | 入口派生、fallback 单测、统一创作/生成页回归 | `npm run test -- src/components/unified-creation/UnifiedCreationPage.test.tsx src/components/unified-creation/UnifiedGenerationPage.test.tsx` |
| P3-A 跳一跳接入包 | 可与 P3-B、P3-C、P3-D 并行 | 自动回归通过 | `jump-hop` 接入统一创作壳、生成页或明确跳过策略 | 不改正式 runtime 规则真相,不重做作品架 | 入口阶段映射、统一工作台接入、生成/结果跳转、竖屏验收 | 跳一跳相关单测、统一创作页回归、移动端 `/creation/jump-hop` smoke |
| P3-B 宝贝识物接入包 | 可与 P3-A、P3-C、P3-D 并行 | 自动回归通过 | `baby-object-match` 接入统一创作壳、生成页或明确跳过策略 | 不复制上传/历史素材逻辑 | 工作台接入、资产槽位复用、结果跳转、竖屏验收 | 宝贝识物相关单测、统一创作页回归、移动端 `/creation/baby-object-match` smoke |
| P3-C 方洞评估包 | 可与 P3-A、P3-B、P3-D 并行 | 部分回归通过 | 判断 `square-hole` 保留 Agent 形态还是迁表单/图片工作台 | 不直接大改实现 | 例外或迁移方案、字段清单、风险、验收用例 | 文档评审通过;若改代码,补对应工作台测试 |
| P3-D 大鱼评估包 | 可与 P3-A、P3-B、P3-C 并行 | 部分回归通过 | 判断 `big-fish` 保留 Agent 形态还是迁表单/图片工作台 | 不直接大改实现 | 例外或迁移方案、字段清单、风险、验收用例 | 文档评审通过;若改代码,补对应工作台测试 |
| P4-A RPG 例外包 | 可与 P4-B、P4-C 并行 | 自动回归通过 | 明确 RPG 对话式工作台如何接入统一阶段、错误、完成、发布去向 | 不把 RPG 当新增玩法默认模板 | 例外声明、阶段映射、刷新恢复和发布验收 | RPG 指定 interaction 测试、作品详情/进入世界回归 |
| P4-B 视觉小说例外包 | 可与 P4-A、P4-C 并行 | 自动回归通过 | 明确视觉小说特殊生成和结果页边界 | 不迁入外部平台社区、支付、榜单、回放 | 例外声明、上传资产口径、生成/结果/发布验收 | 视觉小说创作、结果和运行态相关测试 |
| P4-C 汪汪声浪决策包 | 可与 P4-A、P4-B 并行 | 自动回归通过 | 判断 `bark-battle` 是特殊工作台例外还是回到表单模式 | 不同时做两套入口 | 决策记录、阶段映射、发布和 runtime 验收 | Bark Battle 创作、发布、runtime 指定测试 |
| P5-A 结果页矩阵包 | 可与 P5-B、P5-C、P5-D 并行 | 最小回归通过 | 列清每个玩法结果页能力、缺口和最小补丁 | 不在结果页新增无需求的大功能 | 结果页能力矩阵、局部重试/上传/发布边界 | 对应结果页测试和手测记录 |
| P5-B 作品架恢复包 | 可与 P5-A、P5-C、P5-D 并行 | 最小回归通过 | 生成中、失败、待发布、已发布都能从作品架恢复 | 不只靠前端内存 notice | 作品摘要字段、作品架 adapter、恢复测试 | 作品架相关 interaction 测试;移动端草稿 Tab smoke |
| P5-C 公开 read model 包 | 可与 P5-A、P5-B、P5-D 并行 | 最小回归通过 | 公开列表、详情、分享和推荐 runtime 对齐后端 read model | 不让前端拼源表当事实源 | 后端 read model/BFF 缺口清单和实现 | 公开列表/详情/API smoke;必要时 `npm run dev:api-server` + `/healthz` |
| P5-D 统一反馈包 | 可与 P5-A、P5-B、P5-C 并行 | 最小回归通过 | 错误和异步完成统一进入平台弹窗 | 不在页面内重复裸错误 banner | `PlatformErrorDialog``PlatformTaskCompletionDialog` 覆盖矩阵 | 平台弹窗测试、跨流程失败/完成手测 |
| P6-A 门禁包 | 串行,依赖 P3/P4/P5 | 已完成 | 固化跨玩法自动测试、竖屏手测和 API smoke | 不继续接新玩法 | 冻结前命令集合;现已收敛到根脚本和开发运维文档 | 跨玩法回归与冒烟验证通过 |
| P6-B 冻结包 | 串行,依赖 P6-A | 已完成 | 更新总状态表,标记已统一、例外接入、暂不接入 | 不遗留“状态未知”玩法 | 总进度、风险清单、后续维护规则 | `npm run check:encoding`、关键门禁通过、文档索引有效 |
### 并行执行注意事项
- 公共壳层 owner 统一负责 `PlatformEntryFlowShellImpl.tsx``appPageRoutes.ts`、入口阶段类型、共享 contract 和统一生成页主流程;玩法 owner 只接自己的工作台和映射。
- 后端 schema owner 统一负责 SpacetimeDB 表、`migration.rs`、表目录和 bindings;玩法 owner 不单独改 schema 后跳过生成绑定。
- 文档 owner 每轮只更新本计划的状态、波次和风险,不把一次性聊天记录写进长期文档。
- 同一波次内如果发现计划和代码事实冲突,先改计划和对应融合文档,再继续实现;不要在代码里临时绕开统一链路。
### 依赖关系摘要
- 可以并行启动:`T3-1``T3-2``T3-3``T3-4`,其中 `T3-3``T3-4` 先做形态评估,`T3-1``T3-2` 可以直接进入实现。
- 可以并行启动:`T4-1``T4-2``T4-3`,但它们只做例外边界和决策,不直接扩散到新的玩法实现。
- `T5-1``T5-2``T5-3``T5-4` 可以并行预研,但最好等至少一批 Phase 3 / 4 方案稳定后再落代码。
- `T6-1``T6-2` 必须串行,且都依赖 Phase 3 到 Phase 5 的验证结果。
## 并行波次
### 波次 A:先定契约
状态:已完成。
- `T2-1` `unifiedCreationSpec` 契约审计
- `T2-2` 后台入口配置治理
- `T2-3` 前端入口读取与 fallback 测试
说明:三项可以并行,先把统一创作入口的真值源、后台编辑面和前端兜底一起收紧。
### 波次 B:第一批迁移与例外评估
状态:自动回归已通过,遗留形态评估按缺口任务继续跟踪。
- `T3-1` `jump-hop` 统一接入
- `T5-5` 统一创作壳滚动收口
- `T3-2` `baby-object-match` 统一接入
- `T3-3` `square-hole` 工作台形态评估
- `T3-4` `big-fish` 工作台形态评估
- `T4-1` `RPG` 例外边界设计
- `T4-2` `视觉小说` 例外边界设计
- `T4-3` `汪汪声浪(bark-battle` 统一/例外决策
说明:`jump-hop``baby-object-match` 已完成最小接入回归;`square-hole``big-fish` 的形态评估继续按缺口任务跟踪;特殊工作台例外边界已完成最小回归。
### 波次 C:交付链路收口
状态:最小回归通过。
- `T5-1` 统一结果页能力矩阵
- `T5-2` 作品架恢复矩阵
- `T5-3` 公开 read model 对齐
- `T5-4` 统一错误与完成反馈回归
说明:交付链路已按页面 / read model / 弹窗分块完成最小回归,后续只处理验收发现的真实缺口。
### 波次 D:验收与冻结
状态:已收口。
- `T6-1` 全链路质量门禁扩展
- `T6-2` 全量验收与冻结
说明:必须串行,先补门禁再冻结状态表。
## 验收矩阵
每个玩法推进时至少记录:
| 验收项 | 要求 |
| --- | --- |
| 创作入口 | 从创作 Tab 或直达 URL 能进入对应工作台,入口事实源来自 `/api/creation-entry/config`。 |
| 创作页 | 统一标题/阶段壳存在,工作台不重复渲染巨大旧标题,移动端可滚动到提交按钮。 |
| 输入控件 | 图片、音频、文本、选择器复用现有通用组件,不复制上传/历史图逻辑。 |
| 生成页 | 自动生成玩法使用统一圆环生成页;无生成页玩法有明确跳转策略。 |
| 结果页 | 能展示草稿、编辑作品信息、处理局部重生成、试玩和发布。 |
| 恢复 | 刷新、退出登录、生成中、失败、作品架恢复都有可观察行为。 |
| 发布与公开 | 发布后能进入统一详情或 runtime;公开列表/read model 不靠前端拼源表。 |
| runtime | 试玩与正式运行态区分清楚,正式业务真相以后端为准。 |
| 移动端 | 竖屏优先,无按钮遮挡、套滚动、文字溢出或固定底栏遮挡。 |
## 统一约束
- 不恢复前端硬编码入口配置。
- 不新建平行创作入口系统、平行作品架或平行公开列表。
- 不把功能说明、规则说明或开发解释默认写进 UI 面板。
- 不让前端承接发布、计分、胜负、资产持久化或公开状态等业务真相。
- 后端仍按 `server-rs + Axum + SpacetimeDB` 和 DDD 分层推进。
- 涉及 SpacetimeDB schema 时必须同步 migration、表目录、生成绑定,并运行 schema 检查。
## 推荐推进顺序
1. 将 Round 4 / Phase 6 作为当前冻结基线,后续只做同口径回归,不再新增波次。
2. 对 Phase 3、Phase 4、Phase 5 只处理回归发现的真实缺口,不扩新玩法。
3. 更新冻结状态表,明确每个玩法是已统一、例外接入还是暂不接入。
4. 后续新增玩法默认遵循仓库入口规范、当前开发运维文档和现役定向测试,无需再补新的总计划轮次。
当前轮次看 Round 4 / Phase 6Round 0~4 已作为历史完成记录保留。
@@ -1,121 +0,0 @@
# 宝贝识物寓教于乐模板 PRD 2026-05-11
## 1. 目标
新增寓教于乐内容线的创作模板:
```text
宝贝识物
```
创作者必须通过该模板创作并发布作品后,用户才能在寓教于乐板块体验对应关卡。
本模板只服务儿童动作 Demo 内容线,不把普通教育题材作品自动归入寓教于乐。
## 2. 创作输入
创作者必须填写两个物品名称:
1. 物品 A 名称;
2. 物品 B 名称。
两个名称都必须去除首尾空白后非空。当前阶段不新增题材、难度、计时、失败次数、分数、体力或递增规则。
## 3. 生成规则
提交后生成一份宝贝识物草稿,草稿包含:
1. 模板 ID`baby-object-match`
2. 模板名称:`宝贝识物`
3. 两个物品;
4. 两个物品图;
5. 游戏视觉主题包;
6. 作品标签。
素材使用 VectorEngine `gpt-image-2` / image-2 生成。图片生成只能走后端接口,前端不得读取、拼接或暴露 `VECTOR_ENGINE_API_KEY`
为降低生成成本,创作提交后只生成两张原始图片:一张 `2x2` 素材 sheet 和一张单独场景背景图。`2x2` 素材 sheet 固定包含左上物品 A、右上物品 B、左下篮子、右下礼物盒。服务端必须按固定格切图,并把物品、篮子和礼物盒转成透明 PNG。只有透明抠图后的两个物品素材才允许写入草稿 `itemAssets` 并进入游戏运行态。左右手位置指示器属于运行态默认规则,使用项目内置静态素材,不在每次创作时生成。
同一次创作还必须生成游戏视觉主题包,必需资源为背景环境、礼物盒、篮子。主题包必须继续保持寓教于乐插画风,并根据用户填写的两个物品关键词匹配主题:例如关键词偏动漫角色或玩具时,背景环境和元素可使用动漫、玩具主题;关键词偏水果时,背景环境和元素可匹配果园、自然主题;其它关键词按其语义匹配合适主题。主题包不得改变关卡玩法规则,不新增文字说明、额外按钮或额外判定规则。
视觉主题包的资源边界:
1. 背景环境图不做透明抠图,但必须保证屏幕中间、中下方和底部左右篮子区域清爽,不遮挡放大后的物品、礼物盒和篮子;
2. 礼物盒资源从 `2x2` 素材 sheet 右下格切出,输出为透明 PNG,运行态按当前礼盒视觉的 2 倍尺寸展示,素材主体必须饱满清晰;
3. 篮子资源从 `2x2` 素材 sheet 左下格切出,输出为透明 PNG,运行态按当前篮子视觉的 1.5 倍尺寸展示,左右篮子仍固定为两个物品对应选项,篮子造型资源可以复用同一张主题篮子图;篮子切图不得保留手柄、篮口或边缘处的白底描边和抠图毛边;
4. 运行态左右手位置指示器使用内置默认静态素材,姿势为用户第一人称看到的半抓握手,不随创作关键词重新生成;
5. 礼物盒打开时的烟雾弹出特效由运行态 CSS 动效兜底;历史草稿如果已有 `smoke-puff` 资源可继续兼容读取,但新生成链路不再单独生成该资源。
当前本地 Demo 阶段已接入真实 image-2 资源链路。创作提交必须成功获得 `generationProvider = "vector-engine-gpt-image-2"` 的两个物品透明 PNG、背景环境图、礼物盒和篮子后,才能进入结果页、试玩或发布;若后端接口、登录态、VectorEngine 配置或上游生成失败,前端必须停留在生成失败状态并展示错误,不得静默回退为占位图。历史草稿中若仍存在 `generationProvider = "placeholder"` 的占位资源,结果页必须提示重新生成,试玩和发布前必须先补齐 image-2 资源。
## 4. 标签规则
发布作品必须携带精确标签:
```text
寓教于乐
```
标签识别只接受精确等于 `寓教于乐`。不接受 `儿童教育``动作教育``寓教于乐 ` 等近似标签。
宝贝识物草稿与发布 payload 中都必须保留该标签。发布后的公开展示、搜索、深链和入口开关继续遵循 `CHILD_MOTION_EDUTAINMENT_DISCOVER_ENTRY_2026-05-09.md`
## 5. 结果页能力
结果页展示:
1. 作品名称;
2. 两个物品名称;
3. 两个物品图;
4. 标签;
5. 保存草稿;
6. 发布;
7. 试玩。
结果页不展示长规则说明文案。试玩按钮直接进入宝贝识物首关本地运行态。
试玩按钮进入宝贝识物首关运行态,运行态消费当前草稿中的两个物品名称和两张物品图,不重新生成或改写物品内容。
若草稿包含视觉主题包,运行态还必须消费该主题包中的背景环境、礼物盒和篮子资源;左右手位置指示器始终使用内置默认静态素材。旧草稿或接口失败时允许回退到当前 CSS 绘本风兜底。历史草稿中若已有 UI 装饰、左右手或烟雾弹出特效资源,运行态仅做兼容读取或忽略,不作为新链路必需资源。
## 6. 发布后体验
发布完成后作品应进入寓教于乐内容线,并在寓教于乐入口开启时可被板块消费。
入口关闭时,发布作品完全不可见,不能通过推荐、发现普通频道、搜索、作品号、公开详情深链或浏览历史访问。
## 7. 与运行时线程的边界
本 PRD 同步约束首关运行态,已确认规则包括:
1. 进入关卡后先展示两个目标物品:物品 A 居中展示 2 秒,名称 UI 与字体约为默认大小的 2 倍,随后物品和名称飞入左侧篮子预设位置,并在飞行过程中恢复为默认大小;左侧就绪后等待 1 秒,再展示物品 B 并飞入右侧篮子预设位置;全部就绪后等待 1 秒再进入礼物盒入场。
2. 目标展示完成后,首次礼物盒自动打开并弹出首个随机物品;后续每次正确反馈完全结束后重新进入礼物盒入场。
3. 每轮仅中间礼物盒跳出的物品随机;左右两侧篮子固定为当前草稿两个物品的顺序;
4. 下一关按钮当前占位;
5. 不新增用户未确认的计时、失败次数、分数、体力或难度递增。
6. 屏幕中上方字幕固定为“将物品放入对应的篮子里”。
7. 礼物盒位于屏幕中下方并按当前视觉放大一倍,首次进入关卡和每次正确反馈结束后的新轮次都从上方落下后自动打开。
8. 屏幕下方左侧和右侧分别展示两个固定篮子,左侧固定使用草稿第一个物品图,右侧固定使用草稿第二个物品图。
9. 左右篮子按当前视觉放大 50%,物品图标与篮子中心尽量对齐,物品图标下方展示对应物品名称 UI。
10. 礼物盒打开时播放烟雾特效,中央物品从烟雾特效中弹出;物品弹出后礼物盒从舞台移除。
11. 中央物品 UI 和左右篮子上方物品图标都使用固定正方形槽位,生成素材只在槽位内等比缩放;长条形物品不得拉伸外层 UI 框。
12. 运行态实时展示用户左右手位置;任意一只手先接触中央物品 UI 后,中央物品绑定并跟随该手移动,手带物品进入左侧或右侧篮子区域时代表选择对应篮子;选篮不使用动作名判定,也不再使用左手固定选左篮、右手固定选右篮的规则。
13. 正确时展示“真棒”字幕和正确特效;错误时展示“再想一想吧”字幕和错误特效,物品回到中央。
14. 成功 20 次后展示“恭喜你!小朋友!”字幕和特效,并展示“再来一次”和“下一关”按钮。
15. 当前本地 Demo 阶段音效与语音播报接口只预留调用点,不在前端写死外部硬件或服务接口。
## 8. 验收
1. 创作入口显示 `宝贝识物` 并可进入模板表单。
2. 未填写任一物品名称时不能生成草稿。
3. 生成草稿后进入结果页,展示两个物品名称和物品图。
4. 生成草稿后包含视觉主题包,主题包含背景环境、礼物盒、篮子三类必需资源。
5. 草稿标签中始终包含精确 `寓教于乐`
6. 发布 payload 始终包含精确 `寓教于乐`
7. 发布完成后出现分享弹窗或发布完成状态。
8. 前端不读取或暴露 VectorEngine 密钥。
9. 结果页试玩进入宝贝识物运行态,不再显示“试玩关卡正在接入中”。
10. 运行态通过鼠标左键映射左手位置、鼠标右键映射右手位置;调试输入也必须先触碰中央物品,再拖入任一篮子完成选择。
11. 成功 20 次后出现“再来一次”和“下一关”按钮。
12. 使用长条形物品素材时,中央物品 UI 和篮子物品图标仍保持固定正方形槽位,只缩放物品本体。
13. 运行态开局先完成两个目标物品的居中展示和飞入篮子动画,之后才出现礼物盒并进入首轮随机物品。
@@ -1,77 +0,0 @@
# 拼消消玩法模板 PRD
日期:`2026-05-30`
## 目标
新增玩法模板 **拼消消**,工程域与 `playId` 均为 `puzzle-clear`,公开作品码前缀为 `PC-`。拼消消以拼图的交换 / 拖拽手感为原型,但运行态规则独立:玩家移动 1x1 卡牌碎片,把同一复合图案组拼成完整矩形后消除;消除产生空位后,由顶部对应纵列的卡牌准备区下落补位。
首版必须完成公开闭环:
```text
创作入口 -> 轻表单工作台 -> 独立生成页 -> 结果页 -> 试玩 -> 发布 -> 统一作品详情 -> 正式 runtime -> 基础统计 / 作品架 / 广场
```
## 创作工具平台接入声明
- 工作台模式:表单 / 图片输入创作工作台。
- 创作链路:入口 -> 工作台 -> 生成页 -> 结果页 -> 试玩 -> 发布 -> 运行态。
- 单图资产槽位:
- `board-background` / `ui-background` / `中央场地底图` / `boardBackgroundPrompt` 优先、空值时回退 `themePrompt`,并支持用户上传图 / 写回 `draft.boardBackgroundAsset``draft.boardBackgroundPrompt``work.boardBackgroundAsset``work.boardBackgroundPrompt` / 允许历史图 / 允许 AI 重绘。
- 中央场地底图的字段名沿用平台表面口径,实际作用是玩家逐步消除清空中央棋盘后慢慢看到的主题目标图;AI 生成尺寸必须与中央棋盘一致,使用 1:1 正方形画面。prompt 必须强绑定主题、画面精致、强表现力并一眼体现主题,带来探索、揭开全貌和追求目标完成的感受;不得继续要求“画面干净”或“适合作为卡牌棋盘底图”。
- 系列素材槽位:
- `batchId=puzzle-clear-pattern-atlas-v1`
- `sheetSpec`4 张素材工作表,每张 `1024x1536` 竖版,后台按 `4 列 x 6 行` 裁切,每个 1x1 单元为 `256x256`;服务端再把切片合成一张 `10x10 / 2560x2560` 最终 atlas。复合图案组总数为 `35`,形状配比 `1x2=23``1x3=5``2x2=4``2x3=3`,总计 `95` 个 1x1 卡牌切片。
- `slotSpecs`:每个复合图案组一个 `patternGroup`,服务端预排 `groupId``shape`、atlas 坐标和 1x1 切片坐标。
- 切图规则:生图 prompt 只要求复合图案组能按 4x6 素材工作表均等切成 1x1 方形小份,不允许模型在图上绘制切分线、边框、网格线或裁切参考线;服务端按 sheet 布局直接裁出 1x1 卡牌碎片,校验每个编号占格数与领域图案组面积一致,再合成最终 atlas,写入 `patternGroups[]``cardAssets[]`
- 透明化规则:首版保留完整方形卡面,不强制透明化;若 provider 输出带边框、切分线、网格、裁切参考线或文字,生成任务失败并回写审计。
- 失败回写:生成页写回 `generationStatus=failed` 与失败阶段;结果页保留重试入口。
- 局部重生成:v1 允许整批 4 张素材工作表重试,不做单组局部重生。
- API 命名空间:`/api/creation/puzzle-clear/...``/api/runtime/puzzle-clear/...`
- 业务真相:草稿、发布、runtime snapshot、胜负、补牌、防死局、统计均由后端裁决;前端只做动画和交互表现。
- 创作工具模式例外:无。
- 验证命令:`npm run check:encoding``npm run typecheck``npm run test -- src/services/puzzle-clear/puzzleClearLocalRuntime.test.ts``npm run test -- src/components/puzzle-clear-result/PuzzleClearResultView.test.tsx src/components/puzzle-clear-runtime/PuzzleClearRuntimeShell.test.tsx``cargo test -p module-puzzle-clear --manifest-path server-rs/Cargo.toml``cargo test -p api-server puzzle_clear --manifest-path server-rs/Cargo.toml -- --nocapture`;涉及 SpacetimeDB schema 后运行 `npm run spacetime:generate``npm run check:spacetime-runtime-access``npm run check:spacetime-schema``npm run check:server-rs-ddd`
## 工作台字段
| 字段 | 契约字段 | 默认值 | 校验 | 落库 |
| --- | --- | --- | --- | --- |
| 作品标题 | `workTitle` | 空 | 必填,1-30 字 | session draft / work profile |
| 简介 | `workDescription` | 空 | 0-120 字 | session draft / work profile |
| 主题词 | `themePrompt` | 空 | 必填,1-80 字 | 生成 prompt 与草稿 |
| 场地底图主题词 | `boardBackgroundPrompt` | 空 | 0-80 字;为空时底图生成回退 `themePrompt` | session draft / work profile / 主题目标图生成 prompt |
| 中央场地底图 | `boardBackgroundAsset` | 空 | 上传或 AI 生成至少一种 | 单图资产槽位 |
| AI 生成底图 | `generateBoardBackground` | `true` | boolean | 生成编排参数 |
规则参数不开放创作者编辑:棋盘尺寸、倒计时、消除次数、形状解锁、防死局发牌和半锁定规则固定。
## 运行规则
| 关卡 | 棋盘 | 目标消除 | 倒计时 | 解锁形状 |
| --- | --- | --- | --- | --- |
| 1 | 6x6 | 35 | 10 分钟 | 1x2、1x3、2x2、2x3 |
- 开局每个小格子从背面翻向正面。
- 可消除图由横向或纵向复合图案组组成,最小消除单位为两张图拼接。
- 完成一个复合图案组后,该组所有 1x1 卡牌碎片消除。
- 消除后空位按列由顶部卡牌准备区下落补齐。
- 每次补牌至少保证掉落卡中有一张可以与场上剩余某张卡拼接,防止死局。
- 非 2 格消除时,若场上已有局部完成的半锁定拼接组,补牌不得破坏它。
- 半锁定拼接组可整体拖动;玩家用外部单格撞入组内某格时,只交换该格,组其余部分保留,组状态退回半完成。
- 超时只判当前关失败,可重试当前关;完成 35 次目标并清空当前棋盘后整局完成。
## 结果页
结果页展示:素材 atlas、中央场地底图、发布状态、试玩入口和失败重试。结果页不写功能说明类文案,不开放规则编辑器,不新增排行榜配置。
## 统计
首版只记录正式 `published` run
- 开局。
- 全局完成。
- 当前关失败。
- 耗时。
- 消除统计。
草稿试玩不写正式统计,不进入排行榜;v1 不做排行榜。
@@ -1,409 +0,0 @@
# 敲木鱼玩法模板 PRD 2026-05-20
## 1. 目标
新增一个可创作、可试玩、可发布的轻量休闲玩法模板:
```text
敲木鱼
```
模板按平台新增玩法 SOP 接入完整闭环:
```text
创作入口 -> 工作台 -> 生成页 -> 结果页 -> 试玩 -> 发布 -> 运行态 -> 公开详情/分享
```
首版默认屏幕中央展示内置卡通透明敲击物图案 `/wooden-fish/default-hit-object.png`。玩家点击运行态非功能区时触发一次敲击:播放敲击音效、敲击物图案执行被敲击动画,并在敲击物上方随机飘出一条祝福词。顶部只展示总数记录;子项计数收纳到总数卡片下方的折叠面板中,总数卡片点击后展开各子项计数,词条在面板中预置显示,未出现时初始值为 0,点击面板外收起。计数仅属于当前单次 run,不进入账号长期账本。
## 2. 模板定位
模板 ID
```text
wooden-fish
```
用户展示名:
```text
敲木鱼
```
公开作品号前缀:
```text
WF-*
```
体验关键词:
1. 单屏点击;
2. 轻量解压;
3. 飘字反馈;
4. 单局累计;
5. 可自定义敲击物、敲击音效和祝福词。
## 3. 与拼图创作流程的复用边界
可以复用:
1. 创作入口配置、入口开关和作品架;
2. 表单/图片输入工作台;
3. 生成过程页和生成中恢复;
4. 结果页的返回编辑、局部重生成、试玩、发布;
5. 公开列表、公开详情、分享码和推荐流分发;
6. 平台资产对象、OSS 私有读取换签和音频资产持久化能力。
不复用:
1. 拼图关卡、棋盘、拼块、排行榜和关卡推进语义;
2. 跳一跳地块图集和蓄力判定语义;
3. 抓大鹅物品消除、五视角图集和容器语义;
4. 任何长期功德账本、账号维度排行榜或全局累计。
## 4. 创作工具平台接入声明
- 工作台模式:表单/图片输入创作工作台
- 创作链路:入口 -> 工作台 -> 生成页 -> 结果页 -> 试玩 -> 发布 -> 运行态
- 单图资产槽位:
- `slotId=hit-object`
- `slotType=hit-object-image`
- `slotName=敲击物图案`
- 提示词来源:`hitObjectPrompt` 与可选 `hitObjectReferenceImageSrc`
- 写回字段:`hitObjectAsset`
- 是否允许历史图:允许
- 是否允许 AI 重绘:允许;上传图只作为 image2 参考,最终运行态只消费 image2 生成图
- `slotId=background`
- `slotType=background-image`
- `slotName=背景环境图`
- 提示词来源:第一步生成的敲击物图案与用户原始题材关键词 / 参考图主题
- 写回字段:`backgroundAsset`
- 是否允许历史图:不单独选择;由敲击物图案生成链路派生
- 是否允许 AI 重绘:允许;随敲击物图案一起重生成
- 系列素材槽位:无;首版只有敲击物图案与背景环境图两个单图资产,不生成图集
- 音频资产槽位:
- `slotId=hit-sound`
- `slotType=hit-sound-audio`
- `slotName=敲击音效`
- 来源:用户上传/麦克风录制音频,或使用默认木鱼音
- 写回字段:`hitSoundAsset`
- 默认兜底:`/wooden-fish/default-hit-sound.mp3`
- API 命名空间:
- `/api/creation/wooden-fish/...`
- `/api/runtime/wooden-fish/...`
- 业务真相:
- 后端裁决并持久化 session、work profile、发布状态、run 摘要和公开投影;
- 前端只负责点击低延迟表现、音频播放、动画、飘字渲染和定期 checkpoint。
- 创作工具模式例外:无
- 验证命令:
- `npm run check:encoding`
- `npm run typecheck`
- `cargo test -p shared-contracts wooden_fish --manifest-path server-rs/Cargo.toml`
- `cargo test -p module-wooden-fish --manifest-path server-rs/Cargo.toml`
- `cargo check -p api-server --manifest-path server-rs/Cargo.toml`
- `npm run spacetime:generate`
- `npm run check:spacetime-schema`
- `npm run dev:api-server` 后检查 `/healthz`
## 5. 创作输入
工作台提交结构化 payload,不提交聊天消息。
必填字段:
1. `templateId = "wooden-fish"`
2. `hitObjectPrompt`:用户想敲的对象关键词或描述,默认“默认敲击物图案,圆润木质质感,透明背景”;
3. `floatingWords[]`:祝福词,最多 8 条,不填或清空时使用默认祝福词。
可选字段:
1. `hitObjectReferenceImageSrc`:上传或历史图引用,只能作为 image2 参考,不可直接进入运行态;
2. `hitSoundPrompt`:历史兼容字段,当前创作流程不再使用;
3. `hitSoundAsset`:用户上传、录音或默认音频资产。
结果页补录字段:
1. `workTitle`:作品标题,默认值在结果页可编辑;
2. `workDescription`:作品简介;
3. `themeTags[]`:最多 6 个标签,样式对齐拼图结果页标签编辑器。
创作界面默认祝福词:
```text
幸运
```
用户可通过加号继续新增 7 个词条,总数最多 8 条。新增词条右侧提供减号 / 删除小按钮;默认的第一个词条保留为普通输入格。
`floatingWords[]` 保存词条名本身,不保存 `+1` 后缀;运行态每次敲击时再把飘字展示为“词条+1”。
## 6. 生成规则
### 6.1 敲击物图案、背景环境图与返回按钮图
默认模板在用户未自定义关键词且未上传参考图时,`compile-draft` 使用内置透明 PNG `/wooden-fish/default-hit-object.png` 写回 `hitObjectAsset``generationProvider="bundled-default"`。这张图来自 image2 对原始参考图的卡通风格化重绘,固定为模板默认资源,避免默认关键词在每次生成时改变造型。即使使用内置默认敲击物,首版仍需要生成 `backgroundAsset``backButtonAsset`,背景环境图和主题返回按钮图都使用默认敲击物作为主题和画风参考。
用户输入自定义关键词、上传参考图,或在结果页主动重生成敲击物时,`compile-draft``regenerate-hit-object` 必须先为敲击物图案生成 image2 单图资产,再基于新敲击物图案生成背景环境图,最后基于去绿后的敲击物主体和背景环境图生成主题返回按钮图,并由 `api-server` 注入写回 `hitObjectAsset``backgroundAsset``backButtonAsset`。前端 action 请求不得自带 `hitObjectAsset``backgroundAsset``backButtonAsset` 短路生成。如果用户上传参考图,后端只能把该图作为 image2 参考图或主题参考;运行态不得直接使用上传图。
敲击物图案生成流程固定为:
1. 调用 VectorEngine `/v1/images/edits`,模型固定为 `gpt-image-2`
2. multipart 参考图固定包含默认木鱼图 `/wooden-fish/default-hit-object.png`,作为基础结构和画风参考;
3. 若用户上传参考图,该图只作为新主题参考追加到同一次 image2 edits 请求,不直接进入运行态;
4. 尺寸固定 `1:1`,必须输出单一纯绿色 `#00FF00 / RGB(0,255,0)` 绿幕背景主体图,并显式禁止黑底、白底、棋盘格、纸板底或任何其它实底背景;
5. 提示词严格使用:
```text
生成敲木鱼新样式,要求结构,画风与参考图保持高度一致,新样式颜色搭配使用新主题对应的颜色。尺寸1:1,先输出单一纯绿色 #00FF00 / RGB(0,255,0) 绿幕背景主体图,背景必须严格使用 #00FF00 / RGB(0,255,0) 且平整无纹理、无渐变、无阴影、无道具,主体完整居中,主体边缘必须干净,不要直接输出透明底。随后由服务端对绿色背景主体图做抠图去除绿色背景。最终结果只保留单个敲击物图案,禁止黑底、白底、棋盘格、纸板底或任何实底背景;主体本身不要使用与绿幕接近的纯绿色,若新主题天然包含绿色,请改用偏深、偏黄或偏蓝的绿色并与绿幕清晰区分。
新主题为:(用户提供参考图或用户输入关键词)
```
敲击物图案落盘前,`api-server` 必须只对第一步生成的单一纯绿色 `#00FF00 / RGB(0,255,0)` 绿幕背景执行去绿处理,把绿色背景转成真实透明 alpha PNG;不得对黑底、白底或其它未知实底执行泛抠图,避免误伤玉米等主体像素。去绿处理必须保留主体内部深色结构和主题细节。
背景环境图生成流程固定为:
1. 调用 VectorEngine `/v1/images/edits`,模型固定为 `gpt-image-2`
2. multipart 参考图固定为第一步敲击物图案抠图完成后的透明图;默认未生成新敲击物时使用内置默认敲击物图案的透明兜底图;
3. 尺寸固定竖屏 `9:16`
4. 背景环境图只适配新敲击物主题和画风,背景中不得包含新敲击物本体,也不得增加木槌互动物品;中央主体预留区必须保持干净,画面中央 40% 区域禁止出现主题主体、主体局部特写、主体轮廓影子、重复元素或主题主体的局部碎片;运行态的敲击物只在前端叠放,不允许出现在背景图提示词里。
5. 提示词严格使用:
```text
生成敲木鱼背景,要求主题、画风与参考图保持高度一致,背景元素和颜色搭配与主题对应,只生成竖屏背景环境图,不生成、不描绘、不暗示新木鱼物品本体,也不要出现木槌互动物品。尺寸竖屏9:16。参考图必须是第一步敲击物抠图完成后的透明图,不继承任何绿色底色、绿幕底色或纯绿色画布,并要求最终输出完整不透明的背景环境图。中央主体预留区必须保持干净,中央区域是运行态叠放敲击物的留白区域,画面中央 40% 区域禁止出现主题主体、主体局部特写、主体轮廓影子、重复元素或主题主体的局部碎片;主题元素只允许出现在外围氛围,不得把主题物品画在画面中央,也不要把主题物品作为背景中心装饰。
主题为:(用户提供参考图或用户输入关键词)
```
返回按钮图生成流程固定为:
1. 调用 VectorEngine `/v1/images/edits`,模型固定为 `gpt-image-2`
2. multipart 参考图固定包含第一步去除绿色背景后的敲击物主体图,以及第二步生成的背景环境图;
3. 尺寸固定 `1:1`,必须输出单一纯绿色 `#00FF00 / RGB(0,255,0)` 绿幕背景主体图,后端落库前执行同一套去绿背景处理;
4. 按主题、画风、材质和配色生成左上角返回按钮图,但参考图只用于约束圆形底色和中央左箭头的颜色搭配,不得借鉴复杂造型、花纹、浮雕边、异形外框或装饰图案;按钮必须始终是标准圆形,主体视觉尺寸比当前模板再放大约 50%,圆形外沿必须有与主题色搭配的干净外描边,中央只保留单个清晰左箭头或返回箭头,不得包含文字、数字、水印、额外 UI 面板、木槌或敲击道具;
5. 提示词严格使用:
```text
生成敲木鱼左上角返回按钮图。要求以参考图-去除绿色背景后的敲击物主体和背景环境图为主题、画风、材质和配色参考,但参考图只用来约束圆形底色和中央左箭头的颜色搭配,不要继承复杂造型、花纹、浮雕边、异形外框或装饰图案。按钮必须始终是标准圆形,整体像单个圆形图标,按钮主体在画布中的视觉尺寸比当前模板再放大约 50%,圆心居中,圆形外沿加一圈和主题色搭配的干净外描边,让它更像一个按钮,但仍然只保留一个清晰、简洁、居中的向左返回箭头,不要出现文字、数字、水印、按钮外标签、额外 UI 面板、木槌或敲击道具。尺寸1:1,输出单一纯绿色 #00FF00 / RGB(0,255,0) 绿幕背景主体图,背景必须严格使用 #00FF00 / RGB(0,255,0) 且平整无纹理、无渐变、无阴影。按钮主体边缘干净,后续由服务端扣除绿色背景;按钮底色不要使用与绿幕接近的纯绿色,若主题天然包含绿色,请仅在圆形底色上使用偏深、偏黄或偏蓝的主题绿色,并用更高对比的箭头颜色区分。
主题为:(用户提供参考图或用户输入关键词)
```
落库链路固定为:`api-server` 调用 VectorEngine `/v1/images/edits` -> 服务端上传 OSS 私有对象 -> `confirm_asset_object` 登记资产对象 -> `bind_asset_object_to_entity` 绑定到 `entityKind='wooden_fish_work'`。敲击物绑定 `slot='hit_object'``assetKind='wooden_fish_hit_object'`,背景绑定 `slot='background'``assetKind='wooden_fish_background'`,返回按钮绑定 `slot='back_button'``assetKind='wooden_fish_back_button'`。写回时把 `legacyPublicPath` 分别写入 `hitObjectAsset.imageSrc``backgroundAsset.imageSrc``backButtonAsset.imageSrc`。不得只拼 `/generated-wooden-fish-assets/...` 占位路径;前端会对 generated legacy path 走 `/api/assets/read-url` 换签,OSS 中没有真实对象时图片无法显示。
默认图案要求:
1. 中央主体使用 `/wooden-fish/default-hit-object.png`
2. 透明背景;
3. 适合移动端居中展示;
4. 不包含 UI、按钮、说明文字、水印或品牌标识;
5. 图片主体需留出敲击动画缩放空间。
### 6.2 敲击音效
音效统一写回 `hitSoundAsset`
写回规则:
1. 若 payload 已包含上传/录音音频资产,`compile-draft` 跳过音效生成,直接持久化该资产;
2. 若 payload 已上传或录制音频,则直接写回 `hitSoundAsset`
3. 麦克风录制音频在保存前由前端自动裁掉开头连续静音段;上传音频不做裁剪,裁剪失败时保留原始录音继续保存;
4. 若两者都没有,后端写回默认木鱼音 `/wooden-fish/default-hit-sound.mp3`
5. 音效资产必须包含可播放地址、对象键、asset object id、来源和可选时长;
6. 通用创作音频接口当前对 `wooden_fish``hit_sound` 目标返回 `410 Gone`,不得在创作流程中按提示词生成音效;
7. `spacetime-client` 不得自行合成 `/generated-wooden-fish-assets/...` 音效占位路径;缺少真实 `hitSoundAsset` 时应使用默认木鱼音兜底展示与播放。
### 6.3 封面
首版封面使用 `hitObjectAsset.imageSrc` 作为 `coverImageSrc`。背景环境图与返回按钮图不作为封面图。
## 7. 契约草案
`WoodenFishDraft` 至少包含:
1. `templateId = "wooden-fish"`
2. `templateName = "敲木鱼"`
3. `profileId`
4. `workTitle`
5. `workDescription`
6. `themeTags[]`
7. `hitObjectPrompt`
8. `hitObjectReferenceImageSrc`
9. `hitSoundPrompt`,历史兼容字段,当前创作流程恒为 `null`
10. `floatingWords[]`
11. `hitObjectAsset`
12. `backgroundAsset`
13. `backButtonAsset`
14. `hitSoundAsset`
15. `coverImageSrc`
16. `generationStatus`
`WoodenFishImageAsset` 至少包含:
1. `assetId`
2. `imageSrc`
3. `imageObjectKey`
4. `assetObjectId`
5. `generationProvider`
6. `prompt`
7. `width`
8. `height`
`WoodenFishAudioAsset` 至少包含:
1. `assetId`
2. `audioSrc`
3. `audioObjectKey`
4. `assetObjectId`
5. `source = uploaded | recorded | bundled-default`
6. `prompt`
7. `durationMs`
`WoodenFishRunSnapshot` 至少包含:
1. `runId`
2. `profileId`
3. `ownerUserId`
4. `status = playing | finished`
5. `totalTapCount`
6. `wordCounters[]`
7. `startedAtMs`
8. `updatedAtMs`
9. `finishedAtMs`
## 8. API 草案
HTTP 路由:
```text
POST /api/creation/wooden-fish/sessions
GET /api/creation/wooden-fish/sessions/{sessionId}
POST /api/creation/wooden-fish/sessions/{sessionId}/actions
GET /api/creation/wooden-fish/works
GET /api/creation/wooden-fish/works/{profileId}
POST /api/creation/wooden-fish/works/{profileId}/publish
GET /api/runtime/wooden-fish/works/{profileId}
POST /api/runtime/wooden-fish/runs
POST /api/runtime/wooden-fish/runs/{runId}/checkpoint
POST /api/runtime/wooden-fish/runs/{runId}/finish
GET /api/runtime/wooden-fish/gallery
GET /api/runtime/wooden-fish/gallery/{publicWorkCode}
```
动作类型:
```text
compile-draft
regenerate-hit-object
replace-hit-sound
update-work-meta
update-floating-words
publish
start-run
checkpoint
finish
```
`compile-draft` 是长耗时动作。前端进入生成页后应展示可恢复进度;如果请求失败,标记失败前必须复读 session,确认后端是否已经生成并写回草稿。
敲木鱼创作请求在前端必须使用长等待窗口,避免 `createSession``executeAction` 仍沿用共享创作工厂默认的 15 秒超时。因为 `compile-draft` 会串行等待敲击物、背景、返回按钮三次 image2 和 OSS 落库,木鱼 client 需要单独配置与整条 image2 链路匹配的超时。本地测试中该 action 可能达到数分钟级;生成页进度必须按“整理草稿 -> 生成敲击物 -> 生成背景环境图 -> 生成返回按钮图 -> 写入正式草稿”展示,不展示“提示词生成音效”阶段,因为当前木鱼音效只支持上传、录音或默认音。
作品架使用 `GET /api/creation/wooden-fish/works` 读取当前用户草稿和已发布摘要,前端发布成功后必须刷新该列表和 `GET /api/runtime/wooden-fish/gallery` 公开列表,使刚发布作品立即出现在草稿 Tab 的已发布筛选和推荐 / 最新流中。
## 9. SpacetimeDB 表和 view
新增表:
1. `wooden_fish_agent_session`
2. `wooden_fish_work_profile`,其中 `background_asset_json` 保存背景环境图资产快照,`back_button_asset_json` 保存主题返回按钮图资产快照;
3. `wooden_fish_runtime_run`
4. `wooden_fish_event`
新增 view
1. `wooden_fish_gallery_card_view`:公开列表卡片投影,只暴露已发布作品;
2. `wooden_fish_gallery_view`:公开详情兼容投影,包含图案、背景、返回按钮、音效和祝福词配置。
新增或调整表、procedure、view 后必须同步 `migration.rs`、后端表目录、生成 bindings,并执行 `npm run check:spacetime-schema`
## 10. 结果页能力
结果页必须展示:
1. 作品标题和简介;
2. 竖屏背景环境图预览;
3. 敲击物图案;
4. 敲击音效试听;
5. 祝福词配置;
6. 标签;
7. 试玩;
8. 发布;
9. 返回编辑。
结果页必须支持:
1. 重生成敲击物图案;
2. 上传、录制或替换敲击音效;未提供时使用默认木鱼音;
3. 修改标题、简介和标签,并在试玩或发布前写回当前作品信息;
4. 修改祝福词,最多 8 条。
图案重生成是独立局部生成态,不得把已有可查看结果重新变成不可打开的全局生成中。音效替换只接受上传或录音资产,不触发提示词音效生成。
## 11. 运行态规则
运行态采用全屏单击模型。
功能区:
1. 顶部总数记录卡和其下拉的子项计数器面板;
2. 设置、暂停、返回、发布分享等按钮;
3. 结果弹层和音频授权提示。
点击规则:
1. 点击非功能区才算一次敲击;
2. 每次敲击立即本地累加 `totalTapCount`
3. 随机等概率从 `floatingWords[]` 中取一个词条;
4. 子项计数面板中预置展示所有词条,未出现词条初始值为 0;
5. 后续同词条出现时对应计数器 +1
6. 播放敲击音效;
7. 敲击物图案执行压缩、回弹或轻微震动动画;
8. 木鱼上方飘出“词条+1”并淡出,飘字只显示文字本体,不加底板、胶囊背景或说明面板。
运行态左上角返回按钮必须优先使用 `backButtonAsset` 渲染主题化按钮图;缺失时才回退通用图标按钮。运行态不提供右上角重开按钮。
音频播放:
1. 前端使用 10 路小复音池;
2. 设置最小播放间隔,避免极端连点导致浏览器抖动;
3. 点击计数不能因为音频节流而丢失;
4. 签名 URL 未就绪时先静音表现,不请求裸 generated 私有路径。
后端只保存 run 摘要,不保存每次点击的完整明细;`checkpoint``finish` 都写入总敲击次数与词条计数快照。
## 12. 公开链路
平台首页推荐、发现、公开详情、搜索、已玩作品和公开试玩统一按 `sourceType='wooden-fish'``WF-*` 公开作品号识别敲木鱼作品。
公开列表优先消费 `wooden_fish_gallery_card_view` 订阅缓存。公开详情如果卡片摘要不足以进入运行态,必须补读完整 work profile。
历史已发布且 `generationStatus=ready` 的木鱼作品如果仅缺 `backButtonAsset`,运行态启动前必须补齐内置默认返回按钮 `/UI/11_left_arrow.png`,并持久写回 work profile;这类历史作品不应通过推荐流过滤隐藏。
## 13. 验收
1. 创作入口能看到 `敲木鱼` 模板;
2. 工作台可以填写敲击物描述、上传参考图、上传或录制音效、配置祝福词;
3. 提交后按默认木鱼参考图生成 image2 敲击物图案;
4. 提交后按新敲击物图案参考图生成 9:16 背景环境图;
5. 提交后按去绿后的敲击物主体和背景环境图生成主题返回按钮图;
6. 上传图不会直接进入运行态;
7. 用户上传或录制音效时直接持久化该资产,未提供时使用默认木鱼音;
8. 结果页能看到背景、图案、试听音效、编辑祝福词并试玩;
9. 运行态功能区点击不触发敲击;
10. 运行态左上角使用主题返回按钮图,右上角不出现重开按钮;
11. 非功能区点击会计数、播放音效、播放敲击动画并飘出无底板大号文字;
12. 顶部总数卡点击后展开子项计数器面板,面板内预置全部词条且未出现词条初始值为 0,面板外点击可收起;
13. 连点不丢计数;
14. `checkpoint``finish` 只保存单次 run 摘要;
15. 作品可以发布、进入公开列表和公开详情;
16. `WF-*` 公开作品号能进入分享和运行态;
17. `npm run check:encoding` 通过;
18. schema 变更后 `npm run check:spacetime-schema` 通过。
@@ -1,198 +0,0 @@
# 跳一跳俯视角玩法模板 PRD 2026-05-19
## 1. 目标
`jump-hop` 重定义为竖屏俯视角平台跳跃游戏。创作者只输入主题,系统生成一张该主题的 `1024x1536` 立方体主题物体 UV 展开图集,按 `3列*6行` 容纳 18 个方块,每个方块内部再用自适应 blob+gradient 算法提取 top/front/right/back/left/bottom 六张面贴图;运行态使用 Three.js 复用标准 `1x1x1` 等比极小倒角立方体几何体,把六面贴图贴到立方体地板上组成无限平台流,同时使用陶泥儿 logo 透明 PNG 作为玩家角色。
首版目标:
1. 创作输入只保留主题,标题、简介、标签和提示词由系统派生;
2. image2 只生成一张 `1024x1536` 地板 UV 展开图集,后端切成 18 组、共 108 张面贴图 PNG
3. 角色不再单独生图,v1 使用 `public/branding/jump-hop-taonier-character.png` 陶泥儿 logo 透明 PNG
4. 运行态每屏只展示 2 个地块:当前地块、目标地块,不再展示下一预览地块;
5. 操作方式为长按屏幕蓄力,松手后角色朝下一块地块中心方向弹出;
6. 只要落点未命中下一个地块,本局立即失败并冻结计时;
7. 成绩记录成功跳跃次数和游戏时长;
8. 排行榜按作品维度展示玩家 ID、成功跳跃次数和游戏时长,排序为成功跳跃次数降序、游戏时长升序、更新时间升序。
## 2. 模板定位
- 模板 ID`jump-hop`
- 展示名:`跳一跳`
- 工程域:`jump-hop`
- 创作入口卡:`subtitle = 主题驱动平台跳跃``imageSrc = /creation-type-references/jump-hop.webp`
- 运行态:`Three.js 标准 1x1x1 等比极小倒角立方体地板 + Three.js Sprite 角色 + DOM HUD`
- 画面比例:移动端竖屏优先,桌面端居中承载 `9:16`
- 素材策略:18 个立方体主题物体 UV 展开包装 + Three.js 复用标准 1x1x1 等比立方体几何 + 陶泥儿 logo 透明角色
- 渲染分层:Three.js 场景层复用一份标准 `1x1x1` 等比极小倒角立方体几何体,`tileAssets[]` 切片只作为主题身份方块包装贴图;单块立方体统一绕玩法竖直 Z 轴自转 45°,让运行态稳定露出顶面和两个侧面,不得做 Y 轴偏航或把 x/y/z scale 压成扁盒子;Three.js 方块模型边长在当前基础上视觉放大 1 倍,只改变模型显示尺寸,不改变平台中心点、随机间距和蓄力换算;后端命中 footprint 必须同步等于当前视觉可见顶面,不得隐藏收缩;运行态视角采用约 `1.69x` 近距相机和 45° 下压视角,每屏只保留当前地块和目标地块,当前脚下地块会根据目标方向偏向场地反侧,给下一块留出足够视野;地块从出现开始就使用自身真实规格,不再按当前 / 目标 / 远近或预览状态叠加倍率缩放,视觉远近只由相机和 Three.js 投影决定;Three.js 平台层、Three.js Sprite 角色和 DOM fallback 层必须保持屏幕 X 轴同向,禁止通过反向相机 `up` 或镜像容器把平台左右翻转;DOM 地块图片层只用于换签、预加载、WebGL 不可用和测试 fallbackThree.js 平台层 ready 后必须隐藏 DOM 地块图片和 DOM 阴影,退出地块只随相机推进自然离屏,不播放独立飞走动画,超过屏幕后再销毁,避免旧地块退出期露出被放大的平面 DOM 贴图;角色主路径使用 Three.js Sprite 承载陶泥儿透明 PNG,Sprite 脚点必须落在当前方块顶面中心高度并且绘制顺序高于地块,DOM 角色层仅在 WebGL 或角色贴图加载失败时兜底
本玩法不是横版平台跳跃,也不是关卡制闯关。平台从屏幕下方向上无限延展,目标地块永远在当前脚下地块的正 45 度或负 45 度方向随机出现。
## 3. 创作工具平台接入声明
- 工作台模式:表单输入创作工作台
- 创作链路:入口 -> 工作台 -> 生成页 -> 结果页 -> 试玩 -> 发布 -> 运行态
- 单图资产槽位:无独立角色图槽位;v1 固定使用陶泥儿 logo 透明 PNG 角色
- 系列素材槽位:
- `batchId = jump-hop-tile-atlas`
- `sheetSpec = 1024x1536 / 3列*6行大单元 / 每格内自适应blob+gradient提取六面 / PNG / 纯洋红 #FF00FF 安全缝与外圈背景 / 后端切图为面贴图 PNG`
- `slotSpecs = tile-01 ... tile-18`,每个 tile 再包含 `top/front/right/back/left/bottom` 六个面 slot,所有 slot 必须对应唯一 OSS path / `assetObjectId`
- 切图规则:先通过 density 种子点精修自适应检测 3 列 6 行大单元边界(`SeedRefinement`);每个大单元内部先用 BFS 连通域提取主 blob、清除非主 blob 噪点,再对行 density 和列 height profile 做 gradient 分析检测边界(y0/y1/y2/y3、x0/x1/x2/x3),按此边界划分为 3x3 block 并保留 5 个有效 block,将含 Right+Back 的 block 从中点拆分为两块,对每个 block 取最大不透明矩形后缩放为 `256x256` 不透明 PNG
- 透明化规则:生成时要求纯洋红 key 安全缝和 UV 空位;后端先对图集做洋红去背(BFS 漫水 + 镂空洞检测),再对每个大单元内提取主 blob 后进行自适应面切分;切分后在 block 内取最大不透明矩形,消除透明边缘
- 失败回写:生成失败时 session 保持 failed,可从生成页重试
- 局部重生成:结果页允许重生成地板贴图图集,仍只调用一次 image2;前端展示生成图时以 `assetObjectId` 作为刷新键,避免同一路径重写后的旧签名或旧缓存
- API 命名空间:`/api/creation/jump-hop/*``/api/runtime/jump-hop/*`
- 业务真相:后端裁决落点、失败、成功跳跃次数、冻结时长和排行榜
- 创作工具模式例外:无
- 验证命令:`npm run check:encoding``npm run typecheck``cargo test -p module-jump-hop --manifest-path server-rs/Cargo.toml`
## 4. 创作输入
主题是唯一必填项。工作台不展示角色提示词、地块提示词、风格卡、难度卡、终点氛围或规则说明。
提交后系统自动派生:
1. 作品标题:主题为空白修剪后的短标题,默认前缀不外露;
2. 作品简介:基于主题生成一句短简介;
3. 标签:`跳一跳``休闲` 和主题关键词;
4. 地板贴图提示词:围绕主题生成 18 个风格一致的立方体主题物体 UV 展开包装,每个包装由 top/front/right/back/left/bottom 六面组成,供 Three.js 标准 1x1x1 等比极小倒角立方体地板复用;实际 image2 prompt 使用“立方体主题物体 UV 展开包装图集 / cube object UV unwrap atlas”措辞,要求六面共同表达同一个完整方块化主题物体,例如水果主题要生成可一眼辨认的方块苹果、方块香蕉、方块橙子、方块西瓜等,而不是单纯生成平铺材质、抽象纹理、平台、跳台、地块成品、单张图重复六面或游戏界面资源;
5. 初始平台流参数:固定 v1 标准参数,不让创作者手工调规则。
## 5. 地板贴图图集
image2 只生成一张 `1024x1536` 竖版图片,画面为 `3列*6行` 均匀分布的立方体主题物体 UV 展开包装;实际提示词必须先约束“画面只包含 18 个用于跳一跳地板的立方体主题物体 UV 展开包装图”,并明确这是供 Three.js 标准 1x1x1 等比极小倒角立方体使用的 cube object UV unwrap atlas。每个大单元格代表一个完整方块化主题物体,并在固定 `4列*3行` UV 网中提供六张面贴图(AI prompt 侧不变);后端通过自适应 blob+gradient 算法检测面的实际位置并切图,不再依赖固定像素坐标均分。不是单纯材质贴片、单张图重复六面、地块成品图、跳板、物体剪影、游戏界面、棋盘、背包、装备栏或图标集页面。
图集要求:
1. 每个大单元内部固定使用 `4列*3行` UV 网,只有六个位置有贴图:第 1 行第 2 列是 `top`;第 2 行第 1-4 列依次是 `left / front / right / back`;第 3 行第 2 列是 `bottom`;其它位置保持纯洋红 `#FF00FF`。以上为 AI 生图的 layout 要求(prompt 侧不变)。后端切图优先使用自适应 blob+gradient 算法检测面的实际像素区域,不依赖固定像素坐标均分;固定网格切片只作为测试对照和必要 fallback 参考。
2. 每个面都是 full-bleed 不透明正方形贴图,四角、边缘和中心都要有可识别内容;六个面共同组成同一个完整方块化主题物体,不能把同一张纹理重复六次,也不能六面各画互不相关的小图标;
3. 贴图不生成已经渲染好的透视 3D 块体成品,不包含摄像机角度、已烘焙侧壁、已烘焙厚度、自身投影、接触阴影或烘焙高光;真实倒角、侧壁、透视和阴影由运行态 Three.js 生成;
4. 18 个方块来自同一主题、同一哑光手绘包装体系,但应表达不同方块化主题物体或明显不同的包装识别特征;水果主题要混排方块苹果、方块香蕉、方块橙子、方块西瓜、方块草莓、方块葡萄、方块奇异果、方块菠萝、方块柠檬、方块桃子、方块梨、方块蓝莓、方块芒果、方块椰子、方块火龙果、方块樱桃、方块哈密瓜、方块石榴,不要 18 个方块都只是同一种果皮、果肉或叶脉纹理;
5. 大单元之间、UV 空位、六面之间和画布外圈为纯洋红 `#FF00FF`,方便后端安全切图;
6. 不包含角色、文字、水印、UI、游戏面板、棋盘、背包、装备栏、按钮、标题、外层边框、可见网格线、场景背景、落地投影、接触阴影、方形阴影、方形底板、白底、灰底或黑底;
7. 贴图不能跨格、贴边串色或进入相邻格;每个面贴图应尽量铺满自己的 UV 面,纯洋红只作为安全缝、UV 空位和外圈 key 色。
大单元切片顺序固定为:
```text
tile-01 tile-02 tile-03
tile-04 tile-05 tile-06
tile-07 tile-08 tile-09
tile-10 tile-11 tile-12
tile-13 tile-14 tile-15
tile-16 tile-17 tile-18
```
每个 `tile-XX` 再切出 `top/front/right/back/left/bottom` 六个面贴图并写入 `tileAssets[].faceAssets`。历史兼容字段 `imageSrc/imageObjectKey/assetObjectId` 保存 top 面;旧作品没有完整 `faceAssets` 时只走 DOM 图片 / 原型兜底层,不再把单张旧贴图强行贴到 Three.js 立方体所有面,避免旧平面素材被误表现成 UV 贴歪。运行态随机使用这 18 个地块作为后续平台外观。起点地块可复用第一个切片,其余平台从完整池中随机选择。
## 6. 运行态规则
### 6.1 平台流
运行态从底部初始地块开始,后续地块持续向屏幕上方生成。每次相机窗口只保留 2 个地块可见:
1. 当前地块;
2. 目标地块。
服务端保存当前 run 的路径缓冲,并在每次成功落地后按同一 seed 补齐后续地块。每个后续地块只能生成在当前地块的正 45 度或负 45 度方向上,世界坐标必须满足 `abs(next.x - current.x) == next.y - current.y`,左右方向由 seed 随机决定。当前版本已有的最远相邻地块间距作为各难度 `max_gap` 上限;每次新地块距离由 seed 在 `max_gap * 55%``max_gap` 之间随机,保证相对距离永远大于 0 且不会超过当前最大手感距离。前端只展示服务端快照,不自行生成正式路径;当前两块可见窗口必须按服务端真实相邻距离缩放屏幕投影,最大距离仍落在当前版本固定的左上 / 右上 45 度位置,较近距离则沿同一 45 度方向靠近当前脚下地块。当前脚下地块仍根据目标方向偏向目标反侧,避免前方同时暴露两块地块。角色开局时脚点必须锚定在初始地块顶面中心;Three.js 角色层通过立方体顶面高度定位脚点,DOM fallback 也使用同一顶面中心屏幕锚点,不得额外把角色吸附到地块侧面或阴影中心。
### 6.2 操作
1. 用户按住当前地块或画面开始蓄力;
2. 长按时长形成蓄力值,达到 `maxChargeMs` 后封顶;
3. 松手后角色从当前真实脚点出发,朝下一块地块顶面中心方向弹出;
4. 蓄力值决定跳跃距离,用户拖拽方向不决定跳跃方向;
5. 前端提交 `dragDistance`,并为兼容后端契约提交由角色当前真实脚点指向下一块地块顶面中心推导出的 `dragVectorX/dragVectorY`;这些方向字段不得来自用户手指拖拽方向。
手感参数固定由后端 `module-jump-hop` 提供:`chargeToDistanceRatio = 0.004`。该值表示蓄力时长到世界跳跃距离的换算系数;旧作品运行时若仍携带其它系数,开局归一化为 `0.004`。契约中的 `dragDistance` 语义是前端提交的蓄力值;`dragVectorX/dragVectorY` 仅用于兼容当前后端请求结构,玩法语义上不表示用户拖拽方向。
松手后前端必须立即生成 `visualJump`,用当前角色真实脚点作为起点、前端预测真实落点作为终点,播放约 `560ms` 的角色飞行动画;视觉预测必须使用当前显示窗口的 current/next 地块作为方向来源,即使后端最新 run 已提前返回,也不能拿新 run 目标配旧窗口角色导致下一跳反向;角色从当前真实脚点沿下一块地块顶面中心方向弹向预测真实落点,蓄力阶段角色只做垂直压缩,不沿目标方向拉长。当前调参验证阶段,按住蓄力时允许显示一枚实时预测落点指示器,位置必须复用同一套前端预测结果:先按真实脚点到下一块顶面中心计算 `landedX/landedY`,再把该世界坐标投影到当前窗口和 Three.js 顶面脚点屏幕位置;不得用当前地块中心或屏幕线性插值替代。松手或取消时隐藏指示器,不参与后端裁决、不写入作品配置。成功落地后必须保留 `lastJump.landedX/landedY` 对应的真实落点偏移,不得强制吸附回目标地块中心;落地后可以轻量回弹,但不能把角色位置拉离真实落点。动画期间显示窗口保持在本次起跳前的 2 块布局,动画路径不得等待后端新 run。若后端新 run 晚于飞行动画返回,角色必须停在预测真实落点等待;新 run 到达后应先使用后端真实落点对齐显示态,成功跳跃在飞行动画结束后保留约 `300ms` 落地停顿,再进入约 `1440ms` 的相机推进过渡,避免角色刚落地就立刻拉镜头。推进过渡中,地块层和角色层必须放在同一个相机层里统一位移,不允许 p1/p2 单独改 `top/left` 做过渡;旧当前地块只随相机推进保留在屏幕后方,不单独执行飞走动画,玩家继续向前跳时再被新的相机推进自然带出屏幕并销毁,新目标地块从上方自然露出,避免角色和地块不同步或闪现。相机推进必须同时携带 X/Y 偏移,从旧真实落点位置斜向滑到新当前地块聚焦位置,不允许先横向瞬切居中后再只做纵向滑动。地块从出现开始保持自身真实尺寸,不得通过当前 / 目标 / 远近 / 预览状态附加 CSS `scale(...)` 或深度倍率;推进期只做统一相机层位移,远近变化交给相机和 Three.js 真实投影。当前地块高亮不得额外通过 CSS `scale` 放大。该动画只属于表现层,命中、失败、成功跳跃次数和冻结时长仍以后端裁决为准。
### 6.3 判定
1. 目标永远是当前地块后的下一个地块;
2. 真实落点沿角色当前真实脚点到下一块地块顶面中心方向计算;开局脚点等于初始地块顶面中心,成功跳跃后脚点等于后端 `lastJump.landedX/landedY`,不得回退到当前地块中心;
3. 落点进入下一个地块完整可见顶面 footprint,则成功;footprint 使用当前路径里该地块 `width/height` 按 45° 顶面投影得到的完整菱形区域,必须严格和当前视觉方块顶面一致,不得再额外收缩或放宽;
4. 落点未进入下一个地块完整可见顶面 footprint,则失败;地块侧面、底面、投影阴影和旧半径范围都不算正确落点;旧 `landingRadius/perfectRadius` 字段仅保留兼容读写,不再作为当前 v1 成功判定;
5. 失败后状态改为 `failed`,计时冻结;
6. v1 没有通关状态、combo、perfect 或生命数。
### 6.4 计分与时间
- 成功跳跃次数:每成功落到下一个地块后 `+1`
- 游戏时长:`startedAtMs``finishedAtMs`,失败时冻结;
- 运行中时长由前端根据服务端 `startedAtMs` 展示;
- 失败后只展示冻结时长。
## 7. 排行榜
排行榜按作品维度生成。每位玩家只保留 1 条最佳记录。
排序规则固定为:
```text
successfulJumpCount desc -> durationMs asc -> updatedAt asc
```
展示字段:
1. rank
2. displayName
3. successfulJumpCount
4. durationMs
5. updatedAt。
排行榜 UI 禁止展示 `user_id` / `playerId` 这类内部身份键。后端可以继续用 `playerId` 做作品维度最佳成绩去重和 `viewerBest` 匹配,但 HTTP 响应必须补齐 `displayName`;已登录用户读取账号 `displayName`,匿名游客展示为“游客玩家”,账号失效或无法解析时展示为“失效玩家”。
草稿试玩可以展示本地结果,但正式排行榜只消费后端 run 记录。匿名 runtime guest 也按 guest subject 作为 playerId 参与当次作品维度排行。
## 8. 结果页
结果页展示:
1. 陶泥儿 logo 透明角色预览;
2. 18 个地块资源池预览;
3. 首屏 2 块平台预览;
4. 试玩;
5. 发布;
6. 返回编辑;
7. 重生成地块。
结果页不再展示角色图片生成槽位,也不提供独立角色重生成。
## 9. 契约要点
公开语义保留:
1. `themeText`
2. `tileAtlasAsset`
3. `tileAssets[]`
4. `defaultCharacter`
5. `path.platforms[]` 作为服务端路径缓冲;
6. `currentPlatformIndex`
7. `successfulJumpCount`
8. `startedAtMs` / `finishedAtMs` / `durationMs`
9. `leaderboard`
旧语义处理:
1. `characterAsset` 仅作为角色描述兼容字段,不再表示生成图片;前端固定使用陶泥儿 logo 透明 PNG;
2. `score` 兼容映射为成功跳跃次数;
3. `combo` 固定为 0,不作为公开玩法语义;
4. `cleared` 状态不再由 v1 产生;
5. 旧 finite path 只作为服务端路径缓冲兼容形态。
## 10. 验收
1. 创作页只显示主题输入;
2. 生成链路只调用一次地板贴图图集 image2,不再调用角色生图;
3. 地板贴图图集为 `1024x1536 / 3列*6行`,后端通过自适应 blob+gradient 算法切出 18 组、共 108 张面贴图 PNG
4. 结果页不依赖旧角色图片槽;
5. 运行态为竖屏俯视角,首屏保持 2 个地块可见;
6. 长按蓄力值影响落点距离,角色初始脚点在初始地块顶面中心,跳跃方向固定朝下一块地块中心,目标地块始终位于当前脚下地块的正 45 度或负 45 度方向;
7. 未落到下一个地块立即失败;
8. 成功跳跃次数累加,失败后计时冻结;
9. 排行榜按成功跳跃次数优先排序;
10. 作品可保存、发布、分享并从公开入口启动。
11. 运行态 Three.js 地板必须只在 `tileAssets[].faceAssets` 六面贴图完整时启用 Three 平台层;玩法坐标把 Z 轴作为立方体竖直高度,因此材质数组按 Three group 顺序写入 `right / left / back / front / top / bottom`,把逻辑 `top` 精确映射到 `+Z` 顶面,并按每面 UV 朝向做必要的翻转校正;六面贴图通过换签或 blob 异步解析时,Three.js 平台 mesh 的刷新签名必须包含 top/front/right/back/left/bottom 六个 texture URL,任一面 URL 变化都要触发材质重建,不能只监听旧单图 `imageSrc`。旧作品没有完整 `faceAssets` 时使用 DOM 图片 / 原型兜底层,不使用单图 3D 贴面 fallback。立方体统一绕玩法竖直 Z 轴自转 45°,让玩家稳定看到顶面和两个侧面,不做 Y 轴偏航,不得把 x/y/z 缩放成扁盒子;Three.js 方块模型边长视觉放大 1 倍,但平台中心点、随机间距和蓄力换算均保持原规则;后端命中 footprint 必须与当前视觉顶面完整对齐;地块材质使用 `alphaTest` 裁边但不得放进透明材质队列,避免透明排序把地块画到角色之上;角色主路径使用 Three.js Sprite 并与平台共用同一屏幕坐标投影,Sprite 脚点必须按当前方块半高抬到顶面中心高度,绘制顺序必须高于地块,DOM 角色仅作为 WebGL 或角色贴图加载失败兜底;相机保持约 `1.69x` 近距 45° 下压视角,当前脚下地块根据目标方向偏向场地反侧,可见当前 / 目标两块地板之间的屏幕间距必须形成正负 45 度关系;所有地块从出现开始保持真实规格,不按距离、深度或预览状态做倍率缩放;长按蓄力、计时刷新和角色位置更新不得销毁重建透明画布、平台贴图预加载层或角色层。
12. 同等世界距离的蓄力换算必须使用 `0.004` 系数,松手后必须先看到角色飞行动画,再保留约 `300ms` 落地停顿,随后看到地块窗口前移;成功落地显示必须保留真实落点偏移,且正确落点范围必须严格等于下一块地块完整可见顶面 footprint。
+11 -9
View File
@@ -1,8 +1,8 @@
# 项目记忆目录
本目录保存可以进入 Git 的项目级长期知识,供开发者和 Agent 读取`.hermes/`保留 Hermes 工具专用资源,不作为项目知识库。
本目录保存可以通过 Git 共享、并且对当前开发仍有效的项目知识`.hermes/` Hermes 工具资源,不作为项目知识库。
## 目录结构
## 当前结构
```text
docs/project-memory/
@@ -15,18 +15,20 @@ docs/project-memory/
│ ├─ decision-log.md
│ ├─ pitfalls.md
│ └─ handoff-template.md
├─ plans/
└─ todos/
├─ plans/ # 仅限正在执行的短期计划
└─ todos/ # 仅限仍开放且有退出条件的事项
```
## 使用原则
- 开发前先读 `AGENTS.md`;复杂任务继续读取 `docs/【协作规范】Agent工作入口与执行准则-2026-06-22.md`,再按任务读取 `docs/project-memory/shared-memory/` 和当前 `docs/` 文档。
- 长期有效的架构约定、接口变化、排障经验、开发流程和协作规则写入 `shared-memory/`
- 阶段性计划写入 `plans/`,已确定但暂未实施的共享 TODO 写入 `todos/`
- 如果本目录内容与代码或最新 `docs/` 冲突,以代码和最新 `docs/` 为准,并同步修正过期记忆
- 开发前先读 `AGENTS.md`;复杂任务再读 Agent 执行准则、共享记忆和任务对应的当前专题文档。
- 稳定架构、接口、流程和排障边界写入 `shared-memory/`;同一事实只保留一个当前口径,细节放在权威专题文档
- `plans/` 只保存正在执行、具有明确剩余项和验收门禁的计划;完成或作废后立即删除,稳定结论融合进当前专题或共享记忆
- `todos/` 只保存真实开放、有人接手即可执行的事项;每项应写明状态、下一决策点和关闭条件。已退役对象不保留未来 TODO
- 分支、提交、测试轮次和阶段流水账不进入长期记忆;需要追溯时使用 Git 历史。
- 若本目录与代码或最新 `docs/` 冲突,以代码和最新专题为准,并在同次变更中修正记忆。
- 禁止写入个人配置、API Key、Token、Cookie、会话记录、认证文件、本地私密路径、构建产物、日志、缓存和数据库 dump。
## RAG 索引
本目录是 Agent 本地 RAG 的高权重索引源。RAG 主要用于 Agent 检索上下文,不替代人工阅读入口或正式文档地图。索引脚本位于 `scripts/rag/`,本地生成的 `.rag/` 数据不提交 Git
本目录是本地 RAG 的高权重索引源,但检索结果只作为候选上下文。索引脚本位于 `scripts/rag/`;运行时依赖和 `.rag/` 数据默认不安装、不提交,启用前需先征得用户确认
@@ -1,188 +0,0 @@
# 音频生成 Composer 恢复共享分流方案
日期:`2026-08-06`
状态:`已实施`
## 一、目标
图片画布的音效与背景音乐恢复使用同一个音频 composer。`ImageCanvasGenerationComposerView.tsx` 内只保留一个 `ImageCanvasAudioGenerationComposerView`,并在组件内定义:
```ts
const isSoundEffect = dialog.mode === 'audio-sound-effect';
```
`isSoundEffect === true` 渲染现有 SFX 分支,`isSoundEffect === false` 渲染现有 BGM V1 分支。删除完整的独立 BGM composer 文件,但保留确有独立职责的 BGM 纯模型、助手 controller 和预设跑马灯组件。
这次只调整前端视图组织方式,不改变任何生成契约、业务规则、请求时序、计费或持久化语义。
## 二、范围与非目标
### 2.1 必须保留的 BGM 能力
- `gpt_description_prompt` 可见原文、Unicode `White_Space` canonicalization 和 200 字生成限制。
- 30 个预设、字符计数、AI 补全、一键简化和单层交换式撤销。
- AI 处理锁、同步正式提交锁、`generating` 锁和迟到响应隔离。
- 稳定 dialog ID、账号 / 项目 scope 校验和按 dialog ID 写回。
- 固定 `Suno`、当前动态泥点价格和隐藏 `make_instrumental` 的现状。
### 2.2 必须保持不变的现有 SFX 能力
- 固定 Vidu `audio1.0`Prompt 同值映射到现有 `prompt + sound` 请求字段。
- `210` 秒、步长 `1` 秒、默认 `5` 秒。
- 当前 Prompt 规范化、全空白时回退“游戏音效”、1500 字限制、价格和失败态。
- 现有提交 callback、生成占位和完成链路。
- SFX 中不出现 Suno、BGM 预设、AI 补全、一键简化、BGM 字符计数或撤销。
### 2.3 本次明确不做
- 不实现 SFX V2 独有的一键优化、自动中译英、ElevenLabs、自动时长、30 秒、Loop 或 SFX 预设。
- 不修改 BGM 或 SFX 需求原文。
- 不修改 BFF、队列、`platform-audio`、External v1、OpenAPI、SpacetimeDB schema、计费或重试。
- 不把 BGM Prompt controller 泛化为音频通用 controller。
- 不新建配置驱动的 composer 框架、第二套音频组件或其它顺带重构。
## 三、当前问题
当前 `ImageCanvasGenerationComposerView.tsx` 分别渲染 SFX 内部组件和 `ImageCanvasBackgroundMusicGenerationComposerView.tsx`。这层完整视图拆分让同一个音频入口形成两套 composer 边界,而 SFX V2 需求已经表明预设、AI 写回、撤销和锁定等交互并非 BGM 永久独占,继续用“BGM 专属交互较多”作为完整组件分叉理由不再成立。
同时,最近一次合并把共享架构中的 `isSoundEffect` 条件表达式带回了当前 SFX-only 组件,却没有带回变量定义,形成 `isSoundEffect is not defined`。该问题不是增加一个局部常量后就可以收口的长期架构问题;本次重构应恢复单一音频组件,使变量与它控制的两个分支重新处于同一组件边界。
## 四、目标结构
```text
ImageCanvasEditorView
└─ useImageCanvasGenerationSurface
└─ ImageCanvasGenerationComposerView
└─ ImageCanvasAudioGenerationComposerView
├─ isSoundEffect === true → 现有 SFX UI 与行为
└─ isSoundEffect === false → 现有 BGM V1 UI 与行为
└─ ImageCanvasBackgroundMusicPresetMarquee
```
继续保留的 BGM 专项模块:
- `ImageCanvasBackgroundMusicPromptModel.ts`canonicalization、计数、动作资格和 dialog 类型收窄。
- `useImageCanvasBackgroundMusicPromptAssist.ts`:按 dialog ID 隔离的异步助手状态与提交锁。
- `ImageCanvasBackgroundMusicPresetModel.ts`30 个预设与追加规则。
- `ImageCanvasBackgroundMusicPresetMarquee.tsx`:展开、滚动、hover、触摸和 reduced-motion。
删除的完整视图模块:
- `ImageCanvasBackgroundMusicGenerationComposerView.tsx`
- `ImageCanvasBackgroundMusicGenerationComposerView.test.tsx`
删除测试文件不等于删除覆盖;其中全部用例必须迁入总 composer 测试。
## 五、实现边界
### 5.1 单一渲染入口
`ImageCanvasGenerationComposerView``audio-sound-effect``audio-background-music` 只保留一个渲染条件和一个 `ImageCanvasAudioGenerationComposerView` 调用。组件内部以 `isSoundEffect` 选择两棵现有表单子树,不为本次重构新造配置层。
共享组件使用基于 dialog ID 与 mode 的稳定 `key`。连续切换 BGM dialog 时,预设展开、滚动、hover 和触摸状态不得继承;从 SFX 切到 BGM 时,音效时长菜单状态也不得泄漏。
### 5.2 Hook 与类型安全
- React Hook 不得放进 `isSoundEffect` 条件分支。`useState``useRef``useId``useImageCanvasFloatingOptionDismiss` 保持固定调用顺序。
- `GenerateDialogState` 不是可判别联合。BGM 分支继续通过 `toBackgroundMusicGenerationDialog` 取得带稳定 ID 的 `BackgroundMusicGenerationDialogState`
- BGM 缺少稳定 ID 或 `backgroundMusicPromptAssist` 时失败关闭,不渲染不完整的 BGM 表单;SFX 不依赖这两个条件。
### 5.3 两套状态写回不得合并
- SFX 继续走现有 `setGenerateDialog` 路径,保持按 mode 更新、失败态复位和时长写回语义。
- BGM 继续走 `updateCanvasGenerationDialogById(dialog.id, updater)`,不能降级成只比较 mode。助手响应、预设、撤销和提交锁仍按稳定 dialog ID 隔离。
- `backgroundMusicPromptAssist` 可以继续由 surface 传给共享 composer,但只允许 BGM 分支读取或调用。
### 5.4 锁定与提交资格不得串用
|分支|锁定条件|生成资格|
|---|---|---|
|SFX|沿用现有 `dialog.status === 'generating'`|沿用现有 SFX 提交入口和默认 Prompt 规则|
|BGM|AI processing、`submitting``generating` 任一成立|沿用 canonical Prompt 的有效字符与 `1200` code point 规则|
BGM 使用 `PlatformTextField + readOnly + aria-invalid`SFX 继续使用 `AutoGrowTextArea + disabled`。本次不统一这两个输入控件,也不改错误、可访问名称或按钮文案。
## 六、预计代码改动
|文件|最小改动|
|---|---|
|`ImageCanvasGenerationComposerView.tsx`|恢复共享 `ImageCanvasAudioGenerationComposerView``isSoundEffect`;移入现有 BGM JSX、常量和依赖;删除独立 BGM import 与双渲染入口|
|`ImageCanvasGenerationComposerView.test.tsx`|迁入独立 BGM composer 的全部测试,并增加双 mode 隔离与切换回归|
|`ImageCanvasBackgroundMusicGenerationComposerView.tsx`|删除|
|`ImageCanvasBackgroundMusicGenerationComposerView.test.tsx`|覆盖迁完后删除|
|`useImageCanvasBackgroundMusicPromptAssist.ts`|只修正指向独立 composer 的历史注释;不改 controller 行为|
以下生产文件预计不改:`useImageCanvasGenerationSurface.tsx` 的现有 props 接线、BGM Prompt / 预设模型、预设跑马灯、submission workflow、submission model、dialog model、`src/index.css` 的现有 BGM 样式,以及全部后端代码。
如实施时发现必须超出该清单才能保持现有行为,应先停下并重新确认边界,不能借本次组件归并顺带重构。
## 七、测试迁移与回归矩阵
### 7.1 BGM 原覆盖完整迁移
独立组件测试中的下列覆盖必须逐项迁入 `ImageCanvasGenerationComposerView.test.tsx`
- canonical preview 计数、超限展示和不改写输入框。
- 0 / 1 / 2 个有效字符及 200 / 201 / 2000 / 2001 边界。
- 补全、简化、撤销和预设按正确 dialog ID 路由。
- `preparePreset` 拒绝时不写回,预设成功时沿用追加和清快照语义。
- 助手错误与生成错误的展示顺序。
- Suno、泥点价格、生成允许 / 拒绝。
- `completing``simplifying``submitting``generating` 锁定。
- 完整单层撤销按钮矩阵和现有可访问属性。
### 7.2 mode 隔离与切换
- SFX 渲染时不存在 BGM 控件,也不存在本次明确排除的 SFX V2 控件。
- BGM 渲染时不存在 Vidu 和音效时长控件。
- SFX 仍保持 `audio1.0`、2–10 秒、默认 5 秒、当前价格和既有提交参数。
- BGM dialog A 展开预设后切到 dialog B,局部展开与滚动状态不继承。
- SFX 与 BGM 相互切换时,菜单、锁和 Prompt 助手状态不跨 mode 泄漏。
- 缺少稳定 ID 或 controller 的 BGM 失败关闭;同样条件不影响 SFX 正常渲染。
### 7.3 最小验证命令
```powershell
npm run test -- src/components/image-editor/ImageCanvasGenerationComposerView.test.tsx src/components/image-editor/ImageCanvasBackgroundMusicPromptModel.test.ts src/components/image-editor/ImageCanvasBackgroundMusicPresetModel.test.ts src/components/image-editor/ImageCanvasBackgroundMusicPresetMarquee.test.tsx src/components/image-editor/useImageCanvasBackgroundMusicPromptAssist.test.tsx
npm run test -- src/components/image-editor/useImageCanvasGenerationSurface.test.tsx src/components/image-editor/useImageCanvasGenerationSubmissionWorkflow.test.tsx
npm run typecheck
npm run check:encoding
git diff --check
```
删除旧测试文件后,还要确认测试收集清单中不再引用它。若本次改动触发其它现有图片画布测试失败,只修复由共享 composer 归并直接造成的回归,不扩大到无关模块。
## 八、实施顺序
1. 在总 composer 内恢复共享音频组件、`isSoundEffect` 和单一音频渲染入口。
2. 原样迁入 BGM 分支,保留按 ID 写回、锁定、错误顺序、Suno 与预设行为。
3. 迁移独立 BGM 组件测试,并补齐 SFX/BGM 隔离与切换用例。
4. 删除独立 BGM composer 及其测试文件,修正相关注释与文档引用。
5. 运行定向测试、typecheck、编码检查和差异检查;实现完成后再把实际结果补入 T6 后续记录。
## 九、完成定义
- 两个音频 mode 均从同一个 `ImageCanvasAudioGenerationComposerView` 渲染,且组件内存在唯一的 `isSoundEffect` 分流。
- 独立完整 BGM composer 文件和独立测试文件已删除,原测试覆盖无遗漏地迁入总 composer。
- BGM V1 所有已交付能力与正式提交语义不变。
- 现有 SFX UI、Prompt、Vidu、时长、价格、校验和提交链路无回归。
- 没有实现任何 SFX V2 独有功能,没有修改需求原文或后端契约。
- 规定的定向测试、typecheck、编码检查和 `git diff --check` 全部通过。
## 十、实施结果
2026-08-06 已按本文边界完成:
- `ImageCanvasGenerationComposerView.tsx` 恢复唯一 `ImageCanvasAudioGenerationComposerView`,由组件内 `isSoundEffect` 分流;BGM 继续按稳定 dialog ID 写回,SFX 继续走原 `setGenerateDialog` 路径。
- 删除 `ImageCanvasBackgroundMusicGenerationComposerView.tsx`,保留 BGM Prompt / 预设纯模型、助手 controller 和预设跑马灯。
- 把独立组件全部用例迁入 `ImageCanvasGenerationComposerView.test.tsx` 后删除旧测试文件;总 composer 现有 50 项测试同时覆盖 BGM 完整动作矩阵和 SFX/BGM 控件、状态、dialog 切换隔离。
- 只修正 `useImageCanvasBackgroundMusicPromptAssist.ts` 的组件归属注释;没有修改 controller、surface、submission workflow、样式、后端、契约或需求原文,也没有实现 SFX V2 独有功能。
实际验证:
- Prompt / 预设 / controller / 总 composer`121/121`
- surface 与 submission workflow`72/72`
- `npm run typecheck`、变更文件 ESLint、Prettier、`npm run check:encoding``git diff --check`:全部通过。
2026-08-06 已执行共享 composer 归并后的浏览器视觉 smoke,未发现阻断性问题;本轮未创建真实音频生成任务或产生扣费。
@@ -1,248 +0,0 @@
# 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 也会被美术、音频等前置依赖阻塞。
- 工作台仍展示“严格审批”,运行期间可以进入 `waiting-for-confirmation` 或要求用户继续,不满足无人值守目标。
- `game.static_smoke` 失败时,持久回执可能只剩 `safeDetail=null``detailUnavailable=true`;同一 owner 看不到失败项,只能猜测修补。
- 可修复的验证失败可能结束旧任务、留下空队列或失败卡片,未保证回到同一主 Run 继续“诊断 -> 修复 -> 重验”。
- 子任务可以先报告 completed,再在投影阶段发现正式产物缺失,造成 Runtime 终态、manifest 状态和文件事实不一致。
- `execution-owner` 对应进程消失后,持久 Runtime 仍可能显示 running,缺少自动对账和续跑闭环。
直接 Codex 能在数分钟内生成明显更完整的可运行雏形,说明首要瓶颈是 Runtime 的路由、反馈和验收控制,而不是基础模型完全不具备实现能力。
## 3. 范围
### 3.1 本次必须完成
1. **默认单主生成路由**
- 持久路由前零 child;持久路由后只启动 `code-prototype`
- 美术只在 `asset.list` 证明精确缺口后动态委派,且一次只处理一个依赖槽。
- 保留 `project-supervisor-gui` 给显式专业 DAG/开发诊断入口,不再作为普通生成默认值。
2. **无人值守安全策略**
- 该模式不得进入普通 `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. **有界端到端验收**
- 用确定性 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`
实施内容:
- 把 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`
实施内容:
- 对该来源的确认型动作做“安全自动执行或明确拒绝”二分,不能挂起等待。
-`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`
实施内容:
- 增加无确认、失败自修复、artifact 真实性和 owner-loss 恢复测试。
- 增加确定性 E2E;真实 Provider smoke 作为现场验收,不把 mock E2E 说成真实生成已经成功。
- 把新的默认路由、无人值守安全边界和复验命令写回权威文档。
## 6. 验收矩阵
| 场景 | 预期结果 |
|---|---|
| 素材完整 | 零美术委派、零额外扣费 |
| 缺少规范图和图集 | 先规范图后图集,一次一个 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 errorstatic + 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 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 必须 blockedSuppressed 且未形成 child 的失败前置记录不参与 capability、claim 与 completion barrier。
- Windows `.agent/project.lock` 不再对最终 `create_new` 目标做 metadata 预检,delete-pending 的 5/32/33 统一进入有界竞争等待;新增 delete-pending 回归,复现真实 `create_new` ACCESS_DENIED 后证明等待可收束。
- 真实 `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`、锁文件或用户产物。
@@ -1,419 +0,0 @@
# 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` 没有推进 sequenceRuntime 连续重试至 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-servercwd 绑定当前项目,使用 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 链路不隐藏触发该旧门禁,若要把多文件产物纳入旧门禁需另行设计读取工作区文件的验证契约。
## 7.1 默认纯转发收口(2026-08-19
### 已确认偏差
- 虽然普通聊天已经调用 `chat_with_game_creator_direct_codex``direct_runtime` 仍会在每条消息前自行判断美术、在消息后强制浏览器试玩、二次整改和版本登记。
- 这使“你好”“今天多少号”等非项目消息也被包装成游戏交付任务,用户看到了“准备运行当前本地游戏”“静态烟测”等旧 Runtime 痕迹;已有游戏的普通对话同样被强制拖入完整验收。
### 收口决策
1. 普通客户端默认链路固定为 `客户端消息 -> 同一项目 Codex app-server thread -> 原样可读回复`。客户端不根据关键词、文件存在性或模型回复推断/决定“新建、续做、生成美术、试玩、修复”。Codex 回合确实改动标准游戏文件后,客户端只按磁盘事实做资源与版本投影,不把投影本身当作另一次创作流程。
2. 默认 direct turn 只负责:项目根边界、同线程复用、系统提示词/skills 注入、进程与凭据隔离、协议异常安全错误、消息显示,以及实际文件变更后的确定性客户端投影。它不自动调用陶泥儿生图、浏览器预览、static smoke、二次 LLM 或隐藏返工;没有文件变化的普通聊天不得修改 manifest、revision 或版本。
3. Codex 是唯一执行主体:它根据用户消息、系统提示词、工程结构和自身可用工具判断是否聊天、修改已有游戏、创建游戏或执行验证;客户端不得恢复 Supervisor、专业 Agent、harness 或固定游戏流程作为补偿。
4. 系统提示词必须清楚区分:非项目问题直接正常回答且不触碰工作区;项目修改按需要读写当前项目;用户明确要求生成/验收时由 Codex自行执行或如实说明工具限制。客户端不以“安全”为由把任意消息重写成生成任务。
5. 回归验收至少覆盖同一实际项目中连续发送“你好”“今天多少号”:均不得触发平台美术、预览、试玩、版本登记或文件变更;再发送一个明确项目修改请求,必须仍复用同一 Codex thread 且由 Codex 自行处理,实际变更的 `game/` 文件随后应出现在客户端“游戏代码”和“项目版本”中。
## 7.2 当前桌面端验收的内置 Codex 侧车 staging 修复(2026-08-20
### 现场问题
- 当前 checkout 执行 `npm run agc` 后,前端 `127.0.0.1:3080`、本地 API `127.0.0.1:8082` 与 SpacetimeDB `127.0.0.1:3101` 均已健康,但桌面壳没有稳定出现。
- 原因是 `src-tauri/build.rs` 每次 Cargo 构建都无条件覆盖 `src-tauri/resources/codex/win-x64/codex.exe``manifest.json`。Tauri dev watcher 将资源写入识别为源码变化,再次启动 Cargo 构建,形成“构建 -> 覆盖约 300 MiB 侧车 -> watcher 重建”的循环。
### 修复与验收计划
1. 内置 Codex 侧车继续从锁定的 npm 原生包 stage 到正式 bundle resource,保留版本与 SHA-256 完整性清单;但仅当二进制内容实际变化时复制,且仅当清单文本变化时写入。
2. 不取消 `cargo:rerun-if-changed` 对上游侧车与声明文件的监听;上游升级仍必须触发重新 stage,运行时仍拒绝 hash 不匹配的内置可执行文件。
3. 真实回归:从干净的本次 AGC dev 进程重启,确认一次必要的首次构建后不再出现连续的 `codex.exe changed` 重建,Tauri 窗口稳定打开;再完成 direct Codex 普通对话与项目修改的客户端验收。
## 7.3 首页自动创建项目与项目内对话收口(2026-08-20)
### 收口契约
1. 首页保留单一“陶泥儿”创作输入口,并恢复“做游戏 / 做素材 / 做方案”三个创作类型,默认为“做游戏”。这三项只是用户显式选择的创作方向,不是 Agent Runtime 模式、Provider 选择或旧 Supervisor 路由;首页仍不渲染用户或助手消息气泡。
2. 每次提交非空正文或附件时,客户端对且只对本次提交调用一次 `create_automatic_local_game_project`,在系统文档目录的 `Genarrative GameAgent/` 下分配唯一 `gameagent-*` 工作区;不弹目录选择器,也不复用最近项目。
3. 工作区初始化后先把附件导入该项目,再立即进入项目开发工作台;用户原始正文作为 `initialPrompt` 原样交给 project-bound direct Codex thread,选中的 `creationType=game|art|doc` 作为独立结构化首轮上下文传入。客户端不得把类型改写为“初始意图”文本、不得把它拼进用户消息,也不得据此切换 Runtime。意图理解、是否修改工程以及后续验收均由项目内同一 Codex 自主完成,首页不运行 projectless Codex 对话。
4. 项目工作台产品文案统一使用“陶泥儿”“智能创作”,不显示“项目总控”“自动执行”“Supervisor”或“专业 Agent”。客户端只做项目创建、附件导入和确定性投影,不恢复旧多 Agent Runtime。
5. 首页的创建状态只显示在主输入区;“最近项目”使用独立静态说明,不能复用“正在创建工作区 / 正在回复 / 已回复”等全局状态。
### 验收合同
- 三个创作类型必须在桌面与窄视口下可见、可键盘操作并具有明确的选中态;切换类型同步更新输入占位与空输入提示,一次创建收口后恢复默认“做游戏”。
- 普通文本、三类创作需求和带附件需求都必须先创建项目,再在 `陶泥儿项目对话` 中出现同一条原始用户消息与 Codex 回复;首轮 direct command 必须同时携带原样 `prompt` 和受限 `creationType``chat_with_game_creator_home_direct_codex` 不得暴露为首页 Tauri handler。
- 连续点击或连续 Enter 只能创建一个工作区;创建进行中按钮禁用,但编辑器不得生成首页聊天气泡。
- 附件必须经 `upload_local_asset` 写入新项目后再交给项目 Codex;不得只把附件元数据留在首页,也不得把浏览器本地路径写入聊天正文。
## 7.4 真实项目验收发现的 Codex 原生组件闭包(2026-08-20
- 真实创建项目时,Codex 0.147.0 能启动 app-server,但首轮文件修改明确失败为缺少 `codex-code-mode-host.exe`;项目只有初始化占位页,未生成游戏。
- 根因是旧 staging 只复制 `bin/codex.exe`,没有保留同版本 npm 原生包依赖的 code-mode host、`rg`、command runner、sandbox setup 和 `codex-package.json` 相对布局。
- Windows x64 内置资源现按固定白名单 stage 完整原生组件闭包;清单升级为 `genarrative-codex-sidecar.v2`,逐文件记录并校验 SHA-256Tauri resources 保持 `bin/``codex-path/``codex-resources/` 布局。资源映射只属于 `tauri.windows.conf.json`,通用配置不得让其他平台在 Tauri build script 阶段校验 Windows 专属文件。API Key、登录状态和用户配置仍不进入安装包。
- 同次真实验收还发现 direct 项目页的可访问名称残留“项目总控”;视觉文案虽已是“陶泥儿”,读屏仍会暴露旧产品模型。direct 分支现统一使用“陶泥儿项目对话 / 陶泥儿消息 / 陶泥儿实时回复 / 陶泥儿对话内容”,旧名称只保留给显式 legacy 诊断入口。
- 修复后同一客户端已真实写入 `game/index.html``game/style.css``game/game.js`。客户端必须继续把这次真实文件变化确定性登记为游戏代码和项目版本;该步骤不启动 Supervisor、harness、平台美术或二次 LLM。
- direct 产品入口的显式“播放”只做用户授权、本地路径/权限边界和预览服务器启动,不再先执行旧 `game.static_smoke` 的 Canvas-only 形态合同;DOM、Canvas、WebGL 及外链 `game.js` 均可进入客户端运行视图。显式 legacy `/smoke` 与旧诊断入口仍保留原严格检查,不能冒充真实浏览器试玩。
## 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. 项目与首页 direct 系统提示词必须把对外产品身份固定为“陶泥儿”。询问身份、名称或能力时以陶泥儿自称,不把 Codex、ChatGPT、OpenAI、模型或通用 AI 助手当作名称;只有用户明确询问底层实现时才可说明内部使用 Codex app-server,并继续保持陶泥儿这一对外身份。direct 缺失 system message 时使用同一陶泥儿兜底,legacy ToolHost 的内部 Codex 技术提示保持独立。
7. 每次直连回合在游戏代码复核与登记成功后,必须在项目写锁内推进一次 durable project revision,并以该 revision 创建首个 `initial-*` 或后续 `agent-*` 正式版本。禁止修改 manifest 后沿用旧 revision;外层工作台会把同 revision 的不同 manifest 判为冲突并拒绝投影,表现为磁盘已有游戏代码和版本、客户端仍显示 0 项。
8. 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 整改。
- 身份合同测试覆盖项目 prompt、首页 prompt 与 direct 缺省 baseInstructions 均以陶泥儿为对外身份,同时证明 legacy ToolHost 的内部 Codex fallback 未被改写。客户端完整重启后,用同一项目分别询问“你是谁”和“你是不是 Codex”,回复必须以陶泥儿自称;仅在第二问可补充底层执行技术。
- 资源投影与 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 为当前 TokenUser;已有目录必须先严格核对 ownerowner 匹配当前 TokenUser 时由客户端自动收紧为禁止继承且仅当前用户 Full Control,owner 不匹配时仍失败关闭,不自动接管、改 ACL、覆盖或删除。
2. 若本机目录预检失败,客户端返回稳定的“本机开发者凭据存储目录未安全初始化;未创建远端凭据”分类,不请求远端创建接口、不发起美术生成、不写 operation 或账本,也不刷新登录态或自动重试。
3. 远端响应后原子写入仍可能因并发或磁盘故障失败;该极窄路径必须单独分类为“凭据已创建但未能安全保存”,提示用户在账户开发者凭据页面撤销后再试,不能自动创建第二把凭据。诊断和正式 UI 只展示上述安全摘要与恢复建议,不包含 access token、开发者凭据、响应正文、绝对路径或签名 URL。
4. 验收先在当前失败项目上恢复:对遗留的空且 owner 不匹配目录做可恢复隔离后,再复用同一项目发送“继续完成此前三消游戏”。成功标准包括本机私钥存在但不读取其内容、平台素材与版本登记完成、desktop/mobile Chromium 试玩证据和隔离进程恢复;此前已创建但无法恢复的远端孤儿凭据作为明确剩余风险,绝不自动撤销。
## 14. 审核 AGC Skill Pack、按需加载与真实工具内核(2026-08-20)
### 14.1 目标架构
普通项目链路固定为 `薄 Runtime + Codex 唯一执行 + 按需 Skill + 真实工具`。Runtime 不再通过关键词、固定步骤或产物字符串计数替 Codex 判断用户意图,也不恢复 Supervisor、专业 Agent 或 harness;它只负责工作区、凭据、不可逆副作用、进程协议和确定性客户端投影。
系统提示词只保留最小核心约束、当前项目文件的有界快照和一份审核 Skill 索引。不得再把项目中的 `.codex/skills``.agents/skills``.hermes/skills` 全文批量拼入 64 KiB 提示词,也不得把主站全部 Skill 复制给普通游戏项目。完整 `SKILL.md` 与直接引用文件由 Codex 原生 Skill 机制在命中意图后按需读取。
### 14.2 审核索引与五类 Skill
客户端内置 `agc-skill-pack.v1` 清单。每项只公开名称、用途、触发条件、所需工具、版本和内容 SHA-256;审核文本统一按 UTF-8 读取并将 CRLF 规范为 LF 后计算指纹和安装,避免编辑器产生的混合换行让同一 Git 内容在 Windows 与 Linux 上得到不同结果。审核文件的语义内容变化时必须在同次变更重算对应指纹并提升版本。启动时逐文件复核清单和编译进客户端的内容,任何缺失、额外文件、路径越界、非 UTF-8 内容或规范化后的指纹不匹配都失败关闭;路径边界显式拒绝反斜杠、Windows 盘符、UNC、绝对路径和 `..`,不能因测试运行在 Linux 就把 Windows 绝对路径当作普通相对文件名。审核包只包含:
1. `agc-project-structure`:项目根、`game/``assets/``.agent/` 的职责和禁止创建平行项目的约束。
2. `taonier-art-assets`:陶泥儿标准美术包、平台来源、警告语义和真实素材使用;`grid-2x2` 与四切片只是推荐路径,不是所有游戏的完成门。
3. `agc-web-game-development`:根据当前需求自由选择 DOM、Canvas 或 WebGL,并完成可玩的 HTML/CSS/JavaScript 实现。
4. `agc-browser-playtest`:调用客户端提供的真实双视口浏览器工具,读取截图、控制台、网络、Canvas/WebGL 和交互证据后自行修复。
5. `agc-client-projection`:解释客户端如何按磁盘事实投影代码、素材、revision 和版本;Codex 不直接伪造或改写 manifest 中的平台身份。
`genarrative-external-editor-api` 的异步、凭据、operation 和 warning 语义经审核后融入 `taonier-art-assets`;不把原始主站技能目录直接暴露给游戏项目。`gpt-image-2-apimart` 只有在对应受控工具真正配置时才能作为显式备用能力,首版不以文字假装可用。`genarrative-play-type-integration`、SpacetimeDB、微信支付和其它主站工程 Skill 明确排除。
### 14.3 渐进加载实现
DirectProject app-server 启动前,把上述审核包安装到本次隔离 HOME 的 `.agents/skills/`DirectHome 不安装项目创作 Skill,也不暴露项目工具。Codex 首轮只得到五项元数据和索引,不得到完整正文;触发后由原生 Skill 读取对应 `SKILL.md`,引用最多一层且只能命中清单文件。项目内任意 Skill 不再由 AGC 提示词构建器主动读取或拼接。
Skill 包版本与内容指纹参与 DirectProject app-server 连接池身份。客户端升级或 Skill 内容变化后必须建立新进程/新 thread,不能复用旧目录中的过期 Skill;同一版本的连续聊天仍复用同一 Codex thread。
### 14.4 真实工具与安全边界
DirectProject 仅配置客户端自身的本地 stdio MCP,首版暴露三个受控工具:
- `agc_read_skill_resource`:只读取审核清单中某个 Skill 直接声明的一层 `references/*.md`;不接受绝对路径、`..`、未声明文件、主站 Skill、项目文件或宿主文件。它补足禁用通用 shell 后的渐进引用读取能力,不扩大工作区权限。
- `taonier_prepare_game_art`:按 Codex 提供的游戏 brief 创建或恢复陶泥儿标准美术包。工具内部继续使用当前 External v1 请求、持久生成账本、稳定幂等键和 `operationId`;未知提交只轮询或以原请求/原 key 恢复,绝不因模型重试重新扣费。完整可信图集缺切片时返回 warning 并保留完整图集,不能伪造切片或阻断后续代码实现。
- `agc_browser_playtest`:由当前客户端启动 loopback 预览和受限 Chromium,对 desktop/mobile 采集真实截图、页面状态、控制台异常、失败请求、Canvas/WebGL 图片使用与有限交互探针,并把结构化证据和截图作为工具结果返回 Codex。该工具不使用旧固定玩法 harness。
MCP 子进程复用当前客户端二进制的专用无窗口模式,从工作目录取得唯一项目根;命令行不传项目路径或凭据。它只处理 MCP 和审核引用读取;真实浏览器与付费美术通过随机 loopback 地址回到持有项目上下文的客户端主进程执行,避免 Codex 隔离用户环境阻断 Chrome,也避免把 GUI 登录态复制给子进程。陶泥儿开发者 Key 只由客户端主进程按受信任 origin 从当前用户私有文件读取并在内存中使用,不进入 Codex 环境变量、系统提示词、argv、项目文件、日志或工具结果。凭据缺失时工具返回可行动的“先在客户端登录并准备本机开发者 Key”,不得假装生成成功。
DirectHome 继续禁用 MCP、命令和写入。DirectProject 仍禁用通用 shell、任意网络和多 Agent;文件修改只走 Codex 受限原生能力,外部副作用只走上述本地工具。付费生成、路径权限、文件事务、图片下载/解码、来源身份和客户端投影继续由确定性代码守住。
### 14.5 验收合同
- Rust 单测:清单五项精确、SHA-256 匹配、路径无越界;新项目没有本地 Skill 目录仍能安装审核包;DirectHome 不安装;项目中的主站/SpacetimeDB/支付 Skill 不进入系统提示词。
- 提示词测试:普通问候只包含索引,不包含任一完整 Skill 正文;美术 Skill 正文由 Codex 原生触发读取;API Key、Bearer、auth.json、宿主绝对路径不进入上下文。
- fake app-serverDirectProject 配置本地 MCP 且 DirectHome 保持 `mcp_servers={}`;连续回合复用 thread;MCP item 可完成而不是被当成协议违规;无 Supervisor/child/harness。
- MCP 协议测试:initialize、tools/list、tools/call 均为有界 JSON-RPC;未知工具、路径越界、缺凭据明确失败;美术调用复用同一账本/operation,不重复提交;浏览器调用返回双视口真实报告和截图内容。
- 回归:typecheck、AppSurface、Rust 定向与完整串行测试、编码检查、rustfmt 和 diff check 全部通过。
- 真实客户端:从当前 checkout 新建项目,由同一项目 Codex thread 自主选择陶泥儿美术 Skill、调用真实平台工具、写入游戏、调用真实浏览器试玩并按证据修复;客户端最终显示平台美术、游戏代码和项目版本。单独验证“你好”“今天多少号”不调用美术或浏览器工具、不改文件、不登记版本。
### 14.6 当前实施与验收状态(2026-08-20)
- 五项审核 Skill 已由版本化清单和逐 Skill SHA-256 编译进客户端;DirectProject 初始化后显式调用 `skills/extraRoots/set``skills/list`,缺项或解析错误直接失败。DirectHome 不安装该包。项目内 `.codex/.agents/.hermes` Skill 正文不再被系统提示词批量拼接。
- 本地 `agc_tools` MCP 已实际暴露 `agc_read_skill_resource / taonier_prepare_game_art / agc_browser_playtest` 三项工具并固定自动审批;引用读取严格限制为清单内一层 Markdown。真实 `gpt-5.6-sol max` 回合已读取 `agc-project-structure` 的直接引用并正确返回路径边界。
- 浏览器和美术副作用由随机 loopback 工具桥回到客户端主进程;真实 Codex 工具调用已得到 desktop/mobile `readyState=complete`、整体 `passed=true` 与 2 张截图。普通“你好,今天多少号”真实回合只回答日期,游戏文件、manifest、revision 均未变化。
- 开发网关会在 API Key Responses 成功响应中附带 `X-Codex-*` ChatGPT 额度头;隔离 app-server 会把它误判为余额 0。Direct conversation 现经只接受 Bearer `/responses` 的 loopback 流式代理转发,并剥离该组账户头;真实回合从 `usage-limit-exceeded` 恢复为完成。旧 ToolHost 不经过此代理。
- 2026-08-21 真实客户端复跑已由当前登录会话为所选服务端建立新的私有开发者 Key;旧失效文件只改名保留,不读取、不打印也不提交。Codex 经 `taonier_prepare_game_art` 成功生成并登记 `assets/art-spec.png``assets/direct-game-background.png``assets/art-spritesheet.png`,三项均带平台 Canvas 来源身份。首次回合中第三个 `art-spritesheet` operation 已以稳定幂等键受理;重启客户端后只恢复该 operation,随后再次调用完整美术包时仍只有同一账本和 operation,三个 PNG 时间戳不变、账户泥点不再下降,工具两次均返回 `status=completed`、3 个 `assetPaths`、3 张图片且无 warning。
- 同一真实项目已由 Codex 把平台背景、规范图棋子和核心图集实际接入 `game/index.html / style.css / game.js`。真实 Chromium 报告 `passed=true`desktop/mobile 均为 `readyState=complete`、Canvas 非空、无 console error 与 exceptiondesktop 仅有非致命 `favicon.ico` 404。两张截图确认桌面和手机均完整显示甜点星球三消画面,且结构化运行时证据观察到平台图片进入渲染。
- 真实复跑同时暴露并修复两个收尾缺陷:DirectProject 不能沿用普通 LLM 的 180 秒整回合超时,现改为 15 分钟基础空闲窗口、MCP 工具活动期 110 分钟空闲窗口、整个 turn 120 分钟硬上限;DirectHome 与旧 ToolHost 继续保持原超时。系统提示词和浏览器整改回灌同时明确 shell/unified_exec 被安全禁用时应使用已注入的游戏文件快照与结构化证据,不得误报“没有读取工具所以无法验收”,也不得要求 Codex 直接保存 `.agent` 版本。定向回归为 Direct Runtime 35/35、Codex app-server 23/23(另 1 项真实账号测试按设计 ignored)。
- 最后一轮改后 GUI 复验在桌面控制被物理 Escape 中止后未继续自动操作;非 UI CLI 又因不继承 GUI 登录态而得到 `usage-limit-exceeded`。因此本节只把已落盘的真实生图、幂等复用和双视口浏览器证据记为已完成,不把改后最终聊天回复或新增项目版本伪报为已验收;下次从当前客户端发送普通项目消息即可复核新的等待窗口与证据回灌文案。
## 15. Direct Interaction Event v1 合同(2026-08-22
### 15.1 现役缺口与目标
现役 direct 链路虽然在 app-server 内部能接收消息增量,但普通项目聊天仍主要等待 Tauri command 完整返回后才展示助手正文;旧 `game-creator-agent-progress` 只能表达少量阶段,不能作为 direct 回合的正文增量、顺序、终态和隔离合同。本次新增 Direct Interaction Event v1,让用户在终态返回前看到安全活动状态和已产生的用户可见回复,不恢复 Supervisor 或引入第二个 Runtime 真相源。
### 15.2 事件与字段
Tauri 事件名固定为 `game-creator-direct-turn-update`payload 只包含以下字段:
- `projectPath`:发起回合的项目键,只用于本地路由与隔离,不渲染到用户文案。
- `turnId`:本次 direct 提交的稳定回合标识,与项目键共同定位唯一的临时回复。
- `sequence`:回合内严格递增的非负整数,用于拒绝重复、迟到和乱序回退。
- `status`:只允许 `accepted | running | streaming | finalizing | completed | failed`
- `activity`:只允许 `request-accepted | understanding | project-inspection | file-change | controlled-tool | validation | response-finalization | none` 这些安全类别;它是粗粒度活动标识,不是工具日志。
- `accumulatedText`:截至当前序号的完整助手可见正文,前端原位替换临时回复,不将其追加为多条消息。
- `updatedAt`:事件产生时间,只用于展示和诊断,不参与顺序判定。
`activity` 及其对应的展示文案不得泄漏模型 reasoning、工具原始参数、内部路径、Provider、认证信息或未脱敏错误。`accumulatedText` 只能来自助手面向用户的正文增量,不得混入 reasoning、tool call/item、raw arguments、stderr 或内部诊断。
app-server 的 `turn/plan/updated`、reasoning summary、MCP progress、文件 patch/output、命令 output 和验证类通知只能按通知方法名映射为上述固定 `activity`,不得把通知 params 传入 observer。连续同类高频活动应在进入 turn channel 前有界合并;该合并不得影响 `AgentMessageDelta` 正文和 terminal 终态。
### 15.3 生命周期与前端门禁
1. 每次 direct 提交必须先建立 `projectPath + turnId` 的临时回复,生命周期按 `accepted -> running -> streaming -> finalizing -> completed` 前进;没有正文增量时可跳过 `streaming`,任一非终态都可进入 `failed`,终态后不再接受该回合事件。
2. 前端只处理 `projectPath` 等于当前项目且 `turnId` 等于当前活动回合的事件。对同一 `projectPath + turnId`,只接受 `sequence` 大于已接收最大值的事件;时间戳更新不能绕过该单调门禁。
3. 组件存活期内可保留一个全局 Tauri 事件监听。切换项目、切换活动 `turnId` 或 command 完成、失败时,必须清理对应的临时回复、活动文案和最大 `sequence` 等回合关联状态;组件卸载时再清理该全局监听。迟到事件不得污染新项目或新回合。
4. `failed` 必须结束流式态并清理未完成正文,失败展示继续经现有安全错误映射,不把增量文本伪装成已完成回复。
5. WorkspaceLauncher 实际项目工作台必须在消息列表内渲染持续可见的同回合过程卡:没有正文时展示当前安全活动,正文 delta 到达后在同一卡内展开累计正文。过程卡不能退化为输入框下方的小号 workspace 状态;用户位于列表底部时活动和正文更新应自动跟随,用户主动上滚后不得强制拉回。
### 15.4 权威与持久化边界
`game-creator-direct-turn-update` 是 Tauri 进程内的易失通知,只用于提升当前页面的过程可见性;不将事件本身写入项目对话、manifest 或其它 durable 状态,不用它推导跨进程回合已完成。
Tauri command 成功返回的 final `String` 是本次回合唯一的终态助手正文和持久化权威。前端收到 command 结果后,用该 `String` 原位收口同一 `turnId` 的临时回复,并且只持久化一条最终 assistant 消息。`completed.accumulatedText` 仍只是临时展示,不得先行或重复持久化,也不得覆盖 command 的 final `String`
本合同是 direct 链路的独立交互投影,不复用 legacy `AgentRuntimeResult`,不恢复 Supervisor 的任务、receipt 或消息真相。本次只保证当前 Tauri command 存活期内的流式展示与最终持久化,不宣称已实现 durable reconnect、跨客户端恢复增量或重连后继续同一未完回合。
### 15.5 验收合同
- terminal command 返回前,用户消息下方必须持续渲染同回合过程卡;纯工具阶段显示安全活动,真实正文 delta 到达时在同一卡内原位更新临时回复。
- 对同一 `projectPath + turnId` 注入重复、倒序和迟到的 `sequence`,页面必须拒绝小于或等于已接收最大值的事件,不得发生正文或状态回退。
- command 成功后只展示并持久化一条以 final `String` 为正文的 assistant 消息;临时回复、`completed` 事件和 command result 不得形成多条最终消息。
- command 失败、`failed`、项目切换和回合切换均必须清理临时回复、活动状态和序号门禁;组件卸载时必须清理全局监听;旧事件不得出现在新上下文。
- 单测、AppSurface 回归与真实客户端验收均要覆盖 WorkspaceLauncher 实际工作台、长工具通知 replay、自动跟随和手动上滚保护;事件和 UI 文案不得出现 reasoning、raw arguments、tool item、stderr、内部路径、Provider、凭据或未脱敏错误。
## 16. DirectProject 原生 Codex 工具解锁与薄 Runtime2026-08-24
本节 supersede 早期“DirectProject 关闭 shell / unified exec / 任意原生工具、预注入源码快照”的实现描述。它只适用于 `CodexAppServerWorkspaceMode::DirectProject`ToolHost 与 DirectHome 继续使用被动、只读、无 MCP 的旧合同。
- DirectProject 的系统提示词只保留身份、真实 `game/` cwd、可写边界、审核 Skill 索引和副作用归属,总上限收紧为 16 KiB;不再把项目提示词、AGENTS/README/CONTEXT 或 `index.html``style.css``game.js` 快照批量塞入上下文。Codex 按需读取真实文件,避免重复上下文和过时快照。
- DirectProject 恢复 Codex 原生文件/搜索/命令、图片查看、Skill 能力,并保留客户端审核的 `agc_tools` 本地 stdio MCP。`taonier_prepare_game_art`、资源登记、去背景、浏览器试玩和受控搜索仍走 `agc_tools`,由客户端负责权限、锁、账本、幂等、下载校验、回滚/对账和投影。
- `approvalPolicy=never``workspaceWrite(writableRoots=[真实 game/])` 让原生工具循环不再等待 AGC 泛化审批;原生命令网络保持关闭,联网资料继续走受控 `agc_web_search`。Codex 子 Agent、插件、Apps、图片生成、Goals、Workspace Dependencies、Tool Suggestion 仍显式关闭,因为这些能力尚未接入 AGC 的 durable lock、ledger、取消与 reconciliation。原生浏览器/电脑控制继续不作为未审计副作用入口;真实试玩以 `agc_browser_playtest` 为准。
- app-server 进程继续使用隔离 `CODEX_HOME`,只注入 `agc_tools`;不会继承用户配置的任意外部 MCP,且显式关闭 hooks。配置了 AGC LLM Key 或可解析的 `OPENAI_API_KEY` 登录态时,AGC 本地 provider proxy 持有真实凭据;前者仍走已配置上游,后者只走 OpenAI 官方 API,Codex 只拿连接级随机代理令牌。无法安全代理的 OAuth `auth.json` 继续关闭 native shell/unified exec。原生 shell 使用 Codex `shell_environment_policy` 的 core 继承与 glob 形式 secret/proxy/bridge 环境排除,provider API key、loopback bridge URL、受控搜索开关不能被 shell 子进程继承。`.agent/`、项目根和 `../assets/` 不可写;sandbox 没有 deny-read,提示词/Skill 约束与真实 smoke 共同验证客户端私有状态不被读取。
-`platform-agent-harness`、ToolHost 的 Runtime action、AGC durable delegation 与恢复链路不删除、不改作 Codex 的第二执行权威。多 Agent 仍必须使用现有 Runtime delegationDirectProject 的原生循环只负责其自身工作区内的即时推理和工具执行。
验收重点:DirectProject fake app-server 命令包含 `agc_tools`、原生 shell/unified exec 未被 disable、shell 环境策略和 `agents.enabled=false` 均存在;ToolHost/DirectHome 仍清空 MCP 并关闭原生主动工具;direct 系统提示词不含源码快照或项目 Skill 正文;浏览器工具结果只提供结构化事实证据,不强制固定整改循环。原生 shell 是即时项目检查路径,不产生 legacy `command.exec` receipt,不能据此伪造正式 verification gate 或版本完成证明。真实 smoke 还需确认 Codex 子命令无法读取 provider key、bridge URL 或 `.agent` 私有状态。
@@ -1,259 +0,0 @@
# SFX 生成优化 V2.0 任务拆解
日期:`2026-08-06`
状态:`T1–T6 工程实施已完成;生产配置确认、旧 Vidu 队列 drain、灰度和实际发布仍须按门禁人工执行`
开发分支:`feat/sound_opt`
合并基线:`origin/master@281c84b7bf2d`
权威设计:[`docs/【编辑器】画板音乐生成入口设计-2026-06-18.md`](../../【编辑器】画板音乐生成入口设计-2026-06-18.md)
决策入口:[`docs/project-memory/shared-memory/decision-log.md`](../shared-memory/decision-log.md)
> 本文是通过 Git 共享的脱敏实施计划。代码、OpenAPI、测试和运行配置只实现权威设计中冻结的最终口径,不依赖任何未进入仓库的本地资料。
## 文档可见性边界
- `local-docs/` 只供当前机器本地使用,由本机 Git exclude 排除,不进入仓库;其他开发者通过 Git 无法看到、读取或核验其中任何文件。
- 除本节用于声明隔离边界外,仓库中的 tracked 文档不得链接、引用、摘录或把 `local-docs/` 中的文件作为来源、证据或前置阅读材料;代码、OpenAPI、测试、配置和提交信息也不得依赖其内容。
- 所有参与实现、审查、测试和发布所需的规则与证据,必须自包含地写入 tracked 权威设计、决策日志或本共享计划。团队成员不需要、也不应被要求访问本地资料才能开工或验收。
## T0 退出条件
T0 只冻结设计、决策、任务归属、迁移 / 回滚门禁和安全记录;不要求当前 Vidu V1 代码、OpenAPI 或实际 API 在 T0 与 SFX V2 设计一致。实现差距在 T1–T5 收敛,T6 验收。
| T0 条件 | 状态 | 证据 / 剩余动作 |
| --- | --- | --- |
| 权威 SFX V2 设计已进入 tracked `docs/` | 已完成 | 画板音乐生成入口设计的 SFX V2 章节 |
| T1–T6 计划、基线、测试和迁移门禁已通过 Git 共享 | 已完成 | 本文 |
| External v1 `model` 完整矩阵已冻结 | 已完成 | 本文“请求与幂等口径” |
| 英文化具有 LLM 语义判断和程序 Script 门禁 | 已完成 | 本文“Prompt 与 LLM 口径” |
| 一键优化与翻译的 completion tokens 总预算和 `length` 行为已冻结 | 已完成 | 两类请求均为 `2048 × 4 = 8192`,预算包含 reasoning 与可见输出,见本文“Prompt 与 LLM 口径” |
| 旧 Vidu 队列 drain、发布顺序和回滚门禁已冻结 | 已完成 | 本文“发布与回滚” |
| 凭据安全边界已明确 | 已完成 | 秘密值只允许由服务端私密配置注入,不进入 Git、文档、日志或 fixture;凭据轮换不作为本次 T0 仓库门禁 |
| T0 放行状态已确认 | 已完成 | `2026-08-06` 项目负责人明确确认 T0 通过,可以进入 T1 |
T0 已通过,T1–T5 可以按本文依赖顺序进入实现;T0 通过不表示功能已上线。
## 安全边界与 T0 放行记录
该记录只保存日期、责任人 / 工单标识和布尔结论,禁止写入账号、密码、Key、Token、Cookie 或任何可恢复凭据的值。
| 记录 | 日期 | 责任人 / 工单 | 结论 |
| --- | --- | --- | --- |
| 凭据安全边界 | `2026-08-06` | 项目负责人确认 | 不在仓库记录秘密值;凭据轮换不作为本次 T0 仓库门禁 |
| 本地资料隔离 | `2026-08-06` | 本机 Git exclude | 已确认仅本机可见、未被 Git 跟踪且不作为团队证据源 |
| T0 放行 | `2026-08-06` | 项目负责人确认 | 已通过,可以进入 T1 |
## 目标和非目标
### 目标
-`/editor/canvas` 现有 `audio-sound-effect` 分支把新 SFX 任务从 Vidu `audio1.0` 切换为 ElevenLabs `eleven_text_to_sound_v2`
- 复用共享音频 composer、现有生成队列、计费、OSS、资源、素材库和画布完成态。
- 增加 52 个预设、一键优化、单层交换撤销、Worker 内统一英文化、自动 / 手动时长和 Loop。
- 稳定保存 `prompt = userPrompt``actual_prompt = actualPrompt`、实际时长、Loop、模型、provider 和平台 Task ID。
- 同批演进站内 DTO、External v1 OpenAPI、幂等语义、定价配置、部署配置和测试。
### 非目标
- 不修改 BGM Suno、BGM Prompt 助手、BGM 预设、提交锁或定价行为。
- 不新建 SFX 独立页面、平行 composer 或第二套音频业务真相。
- 不新建平行编辑器音频 DTO、正式生成 handler、BFF 或 `/api/editor/audios/*/generations` 路由;原地演进 `server-rs/crates/shared-contracts/src/assets.rs``server-rs/crates/api-server/src/vector_engine_audio_generation/generation.rs` 的现有正式链路。
- 不开放 Prompt Influence UI;服务端固定 `0.3`
- 不为新 SFX 任务提供 Vidu fallback,不删除其它未迁移调用方仍使用的 Vidu 通用能力。
- 不新增 SpacetimeDB 表或列,不向 External v1 暴露 Prompt 优化或翻译助手。
- 不执行未授权的真实付费生成。
## 当前 V1 差距与任务归属
| 领域 | 基线状态 | 收敛任务 |
| --- | --- | --- |
| SFX Prompt | `trim()`、空值回退“游戏音效”、1500 上限 | T1 实现 Unicode canonicalization、2048 上限和无默认回退 |
| SFX UI | textarea、Vidu 胶囊、210 整数时长 | T4 增加 52 预设、优化 / 撤销、自动 / 手动时长和 Loop |
| SFX DTO | `prompt + model + duration: u8` | T1 / T5 演进固定模型、nullable 小数时长、Loop 和响应字段 |
| Prompt 语义 | `prompt == actual_prompt` | T2 / T5 分离 userPrompt 和 actualPrompt |
| provider | Vidu submit + poll + URL download | T3 增加 ElevenLabs 同步二进制 adapterT5 接线 |
| 实际时长 | 请求时长同时作为结果时长 | T3 探测 MP3,T5 写回实际值 |
| Loop | 不存在 | T1 契约、T4 UI、T5 持久化与详情 |
| External v1 | nullable model 默认旧 `audio1.0`duration 为 210 integer | T1 类型基础,T5 同批修改 Rust / OpenAPI / 幂等与结果 |
| 定价 | 旧模型键 5 泥点 | T5 增加新模型键并保持 5 泥点 / 次 |
| 详情 | 通用 Prompt / Model / 时长 / Task | T5 增加中英 Prompt、Loop 和历史 Vidu 分支 |
## 冻结产品与技术口径
### Prompt 与 LLM 口径
- `userPrompt``actualPrompt` 上限均为 2048 Unicode code points。
- 只按 ECMAScript `String.trim()` 删除首尾空白和行终止符,包含 `U+FEFF`、保留首尾 `U+0085`;不做 NFC、内部空白折叠、换行转换、标点替换或静默截断。
- 一键优化固定 `gpt-5.6-luna``reasoning_effort = medium`Worker 翻译固定同模型、`reasoning_effort = low`。两类请求分别按各自 2048 Unicode code point 候选上限的 4 倍,固定 completion tokens 总预算 `8192`;该预算由隐藏 reasoning tokens 与可见 JSON 输出 tokens 共享,不包含输入 Prompt tokens,不是可见正文保证,也不按实际输入长度缩小。当前 VectorEngine OpenAI Chat wire 固定发送 `max_completion_tokens = 8192`;内部历史字段名 `max_output_tokens` 不是业务语义。两者均不发送 temperature 或 function tools。
- 翻译 envelope 固定 `prompt / isEnglish / isFaithfulTranslation / isDirectGenerationFormat / hasAddedOrRemovedRequirement`,只接受完整 `response.text` 中的唯一 JSON object。
- `isEnglish = true` 作为 LLM 语义判断,程序侧另外要求:候选至少含一个 Script=Latin 的 alphabetic code point,且所有 alphabetic code point 的 Script 均为 LatinCommon / Inherited 数字、标点、空白和符号允许。
- 日文假名、韩文、西里尔、希腊、阿拉伯等非 Latin alphabetic Script 候选失败。测试必须覆盖中文、英文、中英混合输入,以及 actualPrompt 2048 / 2049 边界。
- 首轮成功响应但候选不合格或 `finish_reason = length` 时,使用同一 userPrompt 唯一重试;首轮 `content_filter` 和 transport 最终失败不开启第二业务语义轮。
### 请求与幂等口径
- 自动时长默认开启,并预置最近手动值 `5s`;手动范围 `0.5-30s`、UI 步进 `0.1s`。自动模式发送 null 并保留最近手动值。
- Loop 默认 false,是独立 API 参数;系统不根据 Prompt 推断、同步或校验 Loop。
- provider body 固定 `text / model_id / duration_seconds / loop / prompt_influence=0.3`query 固定 `output_format=mp3_44100_128`
- provider POST 不 retry,浏览器正式 POST 不 unsafe retry,队列 `max_attempts = 1`,一个平台 job 最多一次 ElevenLabs POST。
External v1 `model` 先删除首尾 Unicode `White_Space`,再按大小写敏感矩阵 canonicalize
| 输入 | 结果 | canonical queue payload |
| --- | --- | --- |
| omitted / `null` / 空串 / 纯空白 | 接受 | `eleven_text_to_sound_v2` |
| 首尾空白包围的新模型 | 接受 | `eleven_text_to_sound_v2` |
| `eleven_text_to_sound_v2` | 接受 | `eleven_text_to_sound_v2` |
| `audio1.0` | `400 BAD_REQUEST` | 不入队 |
| 其它未知非空值 | `400 BAD_REQUEST` | 不入队 |
所有接受形态在定价、预扣和 enqueue 前收敛为同一个 model 字段,不得产生不同幂等 payload。拒绝形态必须证明零入队、零预扣、零 LLM 和零 provider。
### 结果、计费与数据
- 服务端重建 SFX V2 `generation_inputs_json`,不信任客户端的 actualPrompt、实际时长、model 或 Loop。
- 成功响应的 MP3 必须按现有 `MAX_GENERATED_AUDIO_BYTES = 40 MiB` 有界读取并验证,探测实际时长且只以独立技术异常上限 `600s` 拒绝过长结果;不把请求最大 `30s` 当作响应上限。平台 taskId 使用 operation / queue job ID,不伪造 provider task ID。
- 新模型按次保持 5 泥点,以后端入队时冻结价格为真相。
- 不修改 SpacetimeDB schema,复用 `prompt / actual_prompt / generation_inputs_json` 和画布 layout。
## 任务包
### T0:权威设计、共享计划、安全记录与迁移口径
- 仅修改 tracked 文档,不实现功能代码。
- 完成权威设计、本共享计划、决策日志、对 V1 差距的 T1–T5 归属、drain / 发布 / 回滚门禁。
- T0 放行记录必须真实且脱敏,不得为凭据轮换、责任人或工单虚构证据。
### T1Prompt 规则、52 预设、共享契约与 metadata 基础
- 实现前后端 ECMAScript `String.trim()` 等值 canonicalization、code point 计数、2048 边界和无默认 Prompt 回退。
- 增加 40 + 12 预设纯模型,锁定数量、ID、分类和可见文案。
- 原地演进现有 TypeScript / Rust 音频 DTOfixed model、nullable 小数 duration、Loop、实际时长和 V2 metadata;不得新增同义 DTO 或平行正式生成契约。
- 实现 External `model` canonicalizer 的纯函数与矩阵测试;实际 OpenAPI / handler 接线属于 T5。
实施记录(`2026-08-06`):T1 已完成。前后端共享 canonicalization fixture 已锁定 Unicode 边界与 `2048 / 2049` 行为;52 个预设、最小优化 DTO、固定模型、nullable duration、Loop 默认值、响应结果字段和强类型 V2 metadata 已落地。duration 纯校验接受自动 `null` 与手动 `0.530s`,拒绝非有限值和越界值。External `model` 当前只落地纯 canonicalizer 与输入矩阵测试,正式定价、预扣、enqueue、OpenAPI 和副作用测试仍严格归属 T5;在 T5 完成前不得发布当前中间态。
补充验收(`2026-08-06`):音频 compact 结果保留完整 DTO 必填的 `provider`SFX / BGM 均通过真实 compact → Agent reconcile 回归;正式 SFX 提交流程不再执行原生 `trim()` 或默认 Prompt 回退。Rust V2 metadata 只能经校验构造并拒绝错误版本、模型、时长组合与实际时长;共享 fixture 直接锁定 `1 / 2048 / 2049`52 个预设 ID 和非 `0.1s` 步进小数时长均有固定断言。
规则修订(`2026-08-07`):SFX Prompt 边界 canonicalization 改为 ECMAScript `String.trim()`;本条覆盖上段“不得执行原生 `trim()`”的旧口径。TypeScript 直接调用 `String.trim()`,Rust 以等值边界字符集合实现;首尾 `U+FEFF` 删除、首尾 `U+0085` 保留,BGM Prompt 与 External `model` 的 Unicode `White_Space` 规则不变。
### T2:一键优化 BFF 和 Worker 翻译 service
- 增加登录态 SFX Prompt 优化 BFF,固定 Luna + Medium + completion tokens 总预算 `8192`32 KiB body limit,严格唯一 JSON envelope,不调用音频 provider 或正式计费。
- 增加仅 Worker 可调用的 Luna + Low 翻译 service,每次业务尝试固定 completion tokens 总预算 `8192`,严格 `isEnglish` + Unicode Script 门禁、保真判断和最多一次业务重试。
- 测试覆盖中文 / 英文 / 中英混合输入,日文 / 韩文 / 西里尔等非 Latin 字母候选,actualPrompt 2048 / 2049,请求体精确 token 上限,以及优化直接拒绝 `length`、翻译首轮 `length` 重试一次 / 第二轮 `length` 最终失败和 `content_filter / transport` 行为。
实施记录(`2026-08-06``2026-08-07` 同步 master token 契约):T2 已完成。登录态 `POST /api/editor/audios/sound-effects/prompts/optimizations` 已按 `32 KiB` body limit、Luna + Medium + OpenAI Chat + completion tokens 总预算 `8192` 接入,并注册 User-scope tracking;当前 VectorEngine Chat wire 只发送 `max_completion_tokens=8192`,不发送 `max_tokens``max_output_tokens`。优化候选只接受完整唯一五字段 JSON object,拒绝 tool call、未完成响应、非 Han、生成参数内容、代码块、解释、额外 / 重复字段和超限结果,错误响应不暴露候选或内部 envelope。现有音频生成模块内已增加不注册 HTTP 路由的 Worker 翻译 service,固定 Luna + Low + completion tokens 总预算 `8192`,使用同一 Chat wire 字段,严格执行保真 / 直接生成格式 / Latin Script 门禁,首轮内容不合格或 `length` 只以原始 `userPrompt` 重试一次,`content_filter` 和 transport 最终失败不进入第二业务语义轮;typed failure 只暴露 `translation_invalid / translation_upstream_failed` 安全分类。T2 只交付可供 T5 调用的内部 service,尚未改变当前 Vidu 正式生成、队列、计费、持久化、External v1 或 OpenAPI,不是可发布切点。
### T3ElevenLabs adapter、配置、二进制与时长探测
-`platform-audio` 增加独立 ElevenLabs settings、endpoint normalizer、request builder 和 direct binary client,不伪装 Vidu / Suno poll task。
- 固定 model、influence、format、header 与 query;按 `40 MiB` 做 Content-Length 预检和 `limit + 1` 流式读取,执行 MIME / MP3 验证和纯 Rust duration probe,并以 `600s` 作为独立技术异常时长上限。
- 配置增加 `ELEVENLABS_BASE_URL / ELEVENLABS_API_KEY / ELEVENLABS_REQUEST_TIMEOUT_MS`Key 只在服务端。
- 测试断言 429 / 5xx / timeout / 读取失败都只有一次 provider POST,不执行真实付费请求。
实施记录(`2026-08-07`):T3 已完成。`platform-audio` 已增加独立 ElevenLabs 直接二进制 adapter,固定 endpoint、header、query、model、influence、nullable 小数时长和 Loop;专用 HTTP client 禁止重定向且没有 retry。成功响应先做 `40 MiB` Content-Length 预检,再以 `limit + 1` 有界读取,严格执行 MIME / 真实 MP3 门禁,并以纯 Rust MP3 probe 取得有限正实际时长和独立 `600s` 上限;请求格式 `mp3_44100_128` 不扩展为返回码率硬校验。配置、环境模板和 fail-closed settings guard 已落地,持久化准备已把 provider / file stem 从轮询任务枚举中最小解耦;正式 handler、Worker、计费、OSS 写回、External v1 和 OpenAPI 均未接线,继续归属 T5。
### T4SFX 前端 controller、预设与参数 UI
- 新增 SFX Prompt 纯模型、预设纯模型和 dialog-scoped controller;抽取音频预设跑马灯内核,BGM / SFX 保留各自 wrapper。
- 在共享 composer 的 SFX 分支增加计数、52 预设、一键优化、单层交换撤销、自动 / 手动时长、Loop 和 ElevenLabs 胶囊。
- 在第一个 await 前取得 AI / 提交 operation,只锁当前 SFX dialog;迟到响应和 scope 切换不写新面板。
- T4 不切换 provider,不是可发布切点;与 T5 同一发布列车。
实施记录(`2026-08-07`):T4 已完成。前端增加独立于 BGM 的 dialog-scoped SFX Prompt 状态模型与 controller,优化和提交都在第一个 `await` 前同步取得 operation;账号、项目、dialog、mode 和 `AbortController` 共同隔离迟到响应。优化成功形成一层 canonical Prompt 交换快照,失败清除本次临时快照且不恢复更早快照,预设写入清快照。现有 BGM 跑马灯已抽出无业务语义的音频内核,BGM / SFX 各保留 wrapperSFX wrapper 展示 T1 冻结的 `40 + 12` 预设。
共享音频 composer 的 SFX 分支现已展示 `0 / 2048` 计数、一键优化、单层撤销、自动 / 手动时长、`0.5-30s``0.1s` 步进的 slider、Loop、固定 `ElevenLabs` 胶囊和新模型前端 `5` 泥点兜底。dialog layout 保存并恢复 `soundDurationMode / soundDurationSeconds / soundLoop`;历史 Vidu dialog 和改造入口统一打开 SFX V2 模型面板。同步提交 claim 冻结 canonical Prompt、时长模式、最近手动值和 Loop,只锁当前 dialog,并在 scope 失效后拒绝旧 UI 写回。
T4 没有修改 Worker、provider 调用、正式请求的 nullable duration / Loop 映射、服务端动态定价、计费、OSS、持久化详情、External v1、OpenAPI 或 SpacetimeDB schema;这些继续严格归属 T5。T4 单独合入仍不是可发布切点,也未执行真实 LLM、ElevenLabs 或付费生成。
### T5:正式提交、Worker、计费、持久化、详情和 External v1
- 前端提交冻结 canonical Prompt、duration 和 Loop,正式 POST 不 unsafe retry。
- 原地演进 `server-rs/crates/api-server/src/vector_engine_audio_generation/generation.rs` 的现有 handler,在定价 / 预扣 / enqueue 前 canonicalize External model,入队 payload 不含提前翻译的 actualPrompt;保留现有路由注册、queue / inline 分流和计费边界。
- Worker 执行翻译、单次 ElevenLabs、MP3 时长探测、OSS 和权威 metadata / 画布写回;任一阶段失败进入现有退款链路。
- 实现新模型定价键、历史 Vidu 只读 / 重绘兼容、中英 Prompt + Loop 详情和真实时长。
- 同批更新 External v1 Rust DTO / handler / OpenAPI / Idempotency-Key 重放 / compact result;任一字段不一致时 T5 不完成。
实施记录(`2026-08-07`):T5 已完成。站内与 External SFX 请求在定价、预扣和 enqueue 前统一 canonicalize 为固定模型、canonical userPrompt、nullable 小数时长与 Loop;正式浏览器 POST 不再配置 unsafe retryqueue payload 不包含提前翻译的 actualPrompt。Worker 在既有冻结计费上下文内执行 Luna 英文化、单次 ElevenLabs POST、MP3 校验与实际时长探测、OSS、项目资源 / 账号素材 / 画布完成态写回,并使用 queue job ID 或 inline 预生成的平台 ID 作为 Task ID。服务端重建 `generation_inputs_json`,客户端自报的实际英文 Prompt、实际时长、模型与 Loop 不进入权威 metadata。
新定价键 `eleven_text_to_sound_v2` 已加入默认 JSON、api-server 与 SpacetimeDB 值校验,旧 `audio1.0` 键继续保留;历史 SpacetimeDB 定价快照仅缺新键时由受控本地定价补齐读取,下一次后台保存写回完整矩阵,不修改 schema。详情展示中英 Prompt、实际时长、Loop、生成模型与完整平台 Task IDSFX V2 重绘恢复 userPrompt、duration mode / requested duration 和 Loop,自动时长不会把实际输出时长误作下一次手动值。
External v1 Rust handler、共享 DTO、OpenAPI、compact result 与 Agent Skill 已同步 nullable `0.5-30` 时长、Loop、固定模型和实际 `durationSeconds`;接受的 model 形态生成同一 canonical queue payload,旧 / 未知模型在 enqueue 前返回 `400`。External compact 继续隐藏 provider 与 Prompt,只保留稳定资源引用、实际时长和 Loop。T5 定向 Rust、TypeScript、External/OpenAPI、Agent、定价与 SpacetimeDB WASM build 已通过,未执行真实 LLM、ElevenLabs 或其它付费请求;完整失败矩阵、端到端与发布 smoke 继续归属 T6。
### T6:测试、文档、灰度和发布门禁
- 汇总 T1T5 分层测试,增加 mock LLM + mock ElevenLabs + mock OSS 失败矩阵、端到端等值、刷新 / 重绘、计费退款、无重试、External 幂等和 BGM 回归。
- 更新后端架构、前端专题、开发运维和共享项目记忆。
- 执行定向 TypeScript / Rust / OpenAPI、`npm run typecheck``npm run check:encoding``git diff --check``npm run check:spacetime-schema``npm run dev:api-server` + `/healthz`
- 不将 mock 测试写成真实 provider 验收,不执行未授权付费生成。
实施记录(`2026-08-07`):T6 已完成工程侧测试缝、组合失败矩阵、跨入口补齐、稳定失败分类和发布 runbook。正式 SFX Worker 现由同一编排函数串联计费、翻译、ElevenLabs、OSS、asset object / bind 候选和原子资源 / 素材 / 画布 / job 提交;生产 adapter 继续调用原实现,测试 adapter 覆盖自动 / 手动时长 × Loop、余额不足零外部副作用、翻译 / provider / MP3 / OSS / asset candidate / 原子项目资源 / 账号素材 / 画布写回失败、一次退款和单 job 最多一次 provider POST。ElevenLabs HTTP / 无效音频 / 时长探测分别稳定归类为 `elevenlabs_http_failed / invalid_audio / duration_probe_failed`OSS 与后续写回归类为 `oss_failed / writeback_failed`;普通用户继续只看到稳定短文案。
T6 盘点发现并修复画布 Agent 遗留的 Vidu 参数边界:`generate-sound-effect` 现与站内和 External v1 共用 canonical Prompt、固定模型、`duration = null | 0.5-30``loop`,显式 `duration: null` 不再被通用 null-default 兼容层错误恢复为手动 `5s`。完整验证和生产门禁记录见 [`docs/【实施记录】SFX生成优化V2.0T6测试与发布门禁-2026-08-07.md`](../../【实施记录】SFX生成优化V2.0T6测试与发布门禁-2026-08-07.md)。本阶段没有调用真实 LLM / ElevenLabs、没有执行付费生成、没有连接生产 SpacetimeDB,也没有执行发布;因此“工程 T6 完成”不等于“生产门禁已放行”。
## 依赖和发布列车
```text
T0 -> T1
T1 -> T2 + T3 + T4
T2 + T3 + T4 -> T5
T5 -> T6
```
- T2 / T3 可在 T1 契约稳定后并行;T4 可与两者后半程并行。
- T4 与 T5 之间不存在可发布切点。
- 不修改 SpacetimeDB schema;如实际实现发现必须修改,立即停止并按 schema 迁移规则重新评审,不得带入本计划默认实施。
## 测试门禁
| 层级 | 必要覆盖 |
| --- | --- |
| canonical | 空 / 全 ECMAScript trim 字符(含 U+FEFF)、首尾 U+0085 保留、U+200B、内部 U+FEFF、换行、组合字符、ZWJ emoji、2048 / 2049 |
| 预设 | 40 + 12、ID / label 唯一、文案等值、逗号追加、重复、清快照、超限保文 |
| 优化 | Luna + Medium + completion tokens 总预算 `8192`Chat wire 只含 `max_completion_tokens=8192`,唯一 JSON、布尔门禁、length 直接失败、content_filter、无 tool call、无候选泄漏、dialog / scope 迟到响应 |
| 翻译 | 每轮 Luna + Low + completion tokens 总预算 `8192`Chat wire 只含 `max_completion_tokens=8192`,中文 / 英文 / 中英混合输入,日文 / 韩文 / 西里尔候选,isEnglish + Script 门禁,2048 / 2049,首轮 length 唯一重试、第二轮 length 最终失败且 provider 0 次 |
| 跨入口 / External model | 登录态、External v1、画布 Agent 共用 canonical SFX queue payloadomitted / null / 空串 / 纯空白 / 包围空白新模型 / 显式新模型共用幂等 payload;`audio1.0` / 未知值为 400 + 零副作用 |
| ElevenLabs | auto / manual × Loop false / true,固定 model / influence / formatKey 不泄漏,网络 / HTTP / body 失败均只有一次 POST |
| 二进制与时长 | `40 MiB` 接受 / `40 MiB + 1 byte` 拒绝,Content-Length / chunked 超限、空 / HTML / JSON / 损坏 MP3、允许与 fallback MIME;有限正时长、30.5 / 60 / 600s 接受,>600s / NaN / 无穷拒绝 |
| 持久化 | prompt / actual_prompt / model / provider / task / actual duration / Loop 权威等值,客户端伪造值失效 |
| 计费 | 余额不足零 LLM / provider;翻译 / provider / MP3 / OSS / DB 失败一次退款 |
| 回归 | BGM Suno、助手、预设、锁和定价不变;其它 Vidu 调用方仍可编译和测试 |
## 发布与回滚
### 发布前
- 不打印值地确认生产 `ELEVENLABS_BASE_URL / ELEVENLABS_API_KEY / ELEVENLABS_REQUEST_TIMEOUT_MS` 均已配置。
- 确认定价 override 包含 `eleven_text_to_sound_v2` 且价格已批准。
- 只读查询 `external_generation_job``job_kind = 'editor_sound_effect_generation'``status IN ('pending', 'running')` 的旧 Vidu payload。非零时先 drain,不得让新 Worker 按 V2 nullable duration / Loop payload 解析旧任务;命令必须显式指定 `--server` / `--server-url`
- 先部署 api-server / worker,再部署 web;两者之间使用维护窗或暂时关闭 SFX 提交入口。
- External v1 变更提前通知调用方并完成 contract smoke。
### 观测
- 区分 `translation_invalid / translation_upstream_failed / elevenlabs_http_failed / invalid_audio / duration_probe_failed / oss_failed / writeback_failed`
- 只记录 operation ID、阶段、HTTP status、耗时、响应字节数和实际时长;不记录 Key 或完整 provider 错误正文。
- 对账 job 完成数、退款数、ElevenLabs 调用数和完成资源数,识别重复调用和孤儿资源。
### 回滚
- 回滚时不自动切回 Vidu;先停止新 SFX 入队。
- 等待或人工收口 V2 queued / running job,避免旧 Worker 无法解析 V2 payload。
- 协同回滚 web、api-server、worker 和 External v1 文档,禁止只回滚一层。
- 新生成的 ElevenLabs 素材继续按通用 audio / model / generation inputs 只读展示,不做数据迁移回滚。
- 没有 SpacetimeDB schema 变更,回滚不执行表迁移或字段删除。
## 完成定义
- T0 已通过,T1–T5 按依赖顺序实现并分别完成测试门禁。
- T1–T5 完成各自分层测试,T6 完成全部发布门禁。
- 新编辑器 SFX 不调用 Vidu,历史 Vidu 数据仍可读和按新模型重绘。
- 翻译最终失败时 ElevenLabs 调用为 0;成功 job 最多一次 provider POST。
- MP3 经过有界读取、验证和实际时长探测,权威 metadata 跨队列、OSS、素材、画布、响应和刷新一致。
- External v1 Rust、OpenAPI、幂等 payload、副作用和最终响应逐字段一致。
- 配置、日志、fixture、差异和提交不包含真实账号、Key、Token、Cookie 或其它凭据值。
@@ -1,19 +0,0 @@
# AGC 开发态单窗口启动收口计划
日期:`2026-08-17`
## 目标
`npm run agc` 启动时只打开标题为“陶泥儿”的正式客户端窗口,不再自动额外打开 Agent 聊天开发窗口。
## 范围与边界
- 删除 Tauri setup 中仅 debug 生效的自动 developer 窗口调用,以及已无调用方的 developer 窗口构造代码与专属路由测试。
- 不删除前端 `?agent-chat` 调试页面;它不再是 `npm run agc` 的自动入口。
- 同步原生壳静态门禁、技术方案和长期决策记录,防止自动双窗口回归。
## 验收
1. Tauri 定向 Rust 测试和前端类型检查通过。
2. 配置门禁、编码检查和差异检查通过。
3. 实际运行 `npm run agc` 后,仅存在标题为“陶泥儿”的客户端窗口,不存在 Agent 聊天开发窗口。
@@ -1,48 +0,0 @@
# Agent Swarm 纯聊天验证入口计划
更新时间:`2026-07-14`
## 目标
提供一版不依赖正常客户端 GUI 的终端聊天入口,让开发者选择一个父 Agent,通过真实 Agent Runtime 验证静态委派、动态隔离子 Agent、并行执行、确认动作、回执汇总和多轮持久化。
## 范围
- 新增 `--swarm-chat [--init] <本地项目绝对路径> [parentAgentId]`,省略时默认进入 `project-supervisor`
- 新增总控短命令 `npm run agc:chat -- --config-dir <项目外 AppData 绝对路径> [--init] <project>`;保留 `agc:swarm` 显式父 Agent 调试入口。
- 普通输入进入父 Agent background Runtime;不使用一次性 `--agent-chat`
- 复用 External Runner、active Session、现有 conversation、Agent 私有记忆、项目黑板、`agent.delegate``agent.spawn_isolated`、terminal receipt 和 all-join。
- 展示全部 Agent 的状态、事件、父子身份和委派关系,并支持在终端批准或拒绝待确认动作。
- 提供 `/help``/agents``/status``/history``/quit`
## 非目标
- 不新增 Tauri 窗口、浏览器页面或本地 HTTP / SSE bridge。
- 不新增 Provider 调用路径、Agent 数据库或 conversation 格式。
- 不伪造 token streaming;首版展示 Runtime 状态 / 事件流和最终回复。
- 不在终端退出时取消 Runner、run 或 Runner-owned process session。
## 实现步骤
1. 扩展 CLI command、参数解析和项目外 `--config-dir` 门禁。
2. 新增独立终端 REPL 模块,复用项目初始化、Runtime resume、任务投递和 conversation 读取。
3. 轮询全 Agent Runtime,按身份去重输出状态和事件;待确认时走现有 confirm / reject。
4. 用“全 Runtime 非活跃 + 全队列为空 + 稳定观察窗口”判断一轮收束,再读取父 Agent 当前 Session 的新增 assistant 消息。
5. 增加 npm 短命令、确定性测试、真实启动 smoke 和文档同步。
## 验收清单
- CLI parse、绝对路径、项目初始化、`--config-dir`、空输入、EOF 和 slash command。
- 同一父 Agent 连续两轮使用同一 Session,退出重进后历史可见。
- 两个静态 Agent 并行委派,多个动态 child 并行并形成唯一 all-join。
- approve / reject 均能在终端完成,拒绝后父 Agent 能继续修正计划。
- 父 Agent 暂时 idle、child 仍运行或 receipt 尚未认领时不提前结束。
- Runner 或终端重启后恢复同一 run / session,不重放副作用。
- 真实 Provider transcript 与 task / event / Agent DB / receipt / conversation 一致,最终父回复唯一且无密钥泄漏。
## 当前进度
- 已完成终端入口、短命令、Runtime 状态 / 事件输出、approve / reject、active Session 历史、same-run steer、活跃 `/quit`、启动 / 收束恢复扫描和 Runner 失联阻断。
- 已用真实 `gpt-5.5` 观察到两个静态 Agent 并行、两条 child result、receipt 排队与重启恢复;终端确认、拒绝和活跃退出均生效。同一父 Session 连续 4 轮固定回复及 8 条消息历史恢复通过,最终双安静窗口收束返回 `FOURTH_OK`
- 未通过父 Agent 最终汇总:全量 `agent.run_status` 输出截断导致第一轮预算耗尽;第二轮 receipt continuation 未恢复原始只读目标并请求文件写入,已拒绝。
- 待办:修复定向状态查询或 receipt continuation 目标恢复,复验唯一最终父回复;再补动态 isolated child 并行、唯一 all-join 和 Runner 强杀恢复。
@@ -1,399 +0,0 @@
# Genarrative(陶泥儿)项目架构优化计划书
**文档版本**v1.0
**编制日期**2026-05-26
**项目名称**Genarrative(陶泥儿)
**文档密级**:内部
---
## 一、项目概况
| 维度 | 详情 |
|---|---|
| **项目名** | Genarrative(陶泥儿) |
| **项目定位** | AI Native 互动视觉 RPG 平台——支持多种玩法模板的 AI 创作、运行与分享("玩法类型平台" |
| **核心玩法** | 拼图、视觉小说、Match3D、Bark Battle、Big Fish、Jump-Hop、Square Hole、木鱼、教娱等 10+ 种玩法模板 |
| **代码规模** | 前端 ~823 个 TS/TSX 文件,后端 ~1532 个 Rust 文件,属于大型项目 |
### 1.1 计划目的
本计划书基于对 Genarrative 项目当前架构的全面分析,识别架构层面的关键问题,并提出分阶段、可落地的优化方案。旨在:
- 统一前端架构模式,降低团队认知成本和新人上手门槛
- 提升模块内聚性,减少不必要的耦合与依赖
- 建立自动化契约保障机制,降低跨语言同步出错风险
- 优化工程基础设施,提高开发效率和运维可观测性
---
## 二、技术栈总览
| 层级 | 技术选型 | 版本 |
|---|---|---|
| **前端框架** | React + TypeScript + Vite | React 19 / TS 5.8 / Vite 6 |
| **样式** | TailwindCSS | v4 |
| **3D / 动画** | Three.js、Motion、cannon-es | - |
| **后端 HTTP** | Rust + AxumBFF 门面) | Axum 0.8 |
| **游戏状态 DB** | SpacetimeDB(实时反应式数据库) | v2.2 |
| **AI / LLM** | LangChain-Rust + LLM Proxy | - |
| **小程序** | 微信小程序(含微信支付) | - |
| **容器化** | Docker ComposeNginx + API Server + OTel Collector | - |
| **运维** | systemd、Nginx、Jenkins CI/CD、k6 压测 | - |
| **可观测性** | OpenTelemetryOTLP → Grafana | - |
---
## 三、当前架构分层图
```
┌──────────────────────────────────────────────────────────────┐
│ 入口层 │
│ index.html → main.tsx → resolveAppRoute() → RouteComponent │
│ (多入口路由:平台主页 / 拼图 / BigFish / Match3D / ...) │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ 前端应用层 (src/) │
│ ┌─────────────┐ ┌──────────────┐ ┌──────────────────────┐│
│ │ components/ │ │ services/ │ │ games/ ││
│ │ *-creation │ │ *-creation │ │ bark-battle/ ││
│ │ *-result │ │ *-runtime │ │ domain/ ││
│ │ *-runtime │ │ *-works │ │ application/ ││
│ │ common/ │ │ storyEngine │ │ infrastructure/ ││
│ │ auth/ │ │ payment │ │ ui/ ││
│ └─────────────┘ └──────────────┘ └──────────────────────┘│
│ ┌─────────────┐ ┌──────────────┐ ┌──────────────────────┐│
│ │ hooks/ │ │ data/ │ │ routing/ ││
│ │ persistence/│ │ functionCat. │ │ config/ editor/ ││
│ └─────────────┘ └──────────────┘ └──────────────────────┘│
└──────────────────────────────────────────────────────────────┘
│ Vite Proxy (/api/*)
┌──────────────────────────────────────────────────────────────┐
│ Rust 后端 (server-rs/) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ api-server (Axum HTTP / SSE / BFF 门面) │ │
│ └──────────────────────────────────────────────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────────────┐ ┌──────────────┐ │
│ │ platform │ │ module-* │ │ shared │ │
│ │ -auth │ │ -puzzle │ │ -contracts │ │
│ │ -llm │ │ -visual-novel │ │ -kernel │ │
│ │ -image │ │ -match3d │ │ -logging │ │
│ │ -oss │ │ -bark-battle │ └──────────────┘ │
│ │ -speech │ │ -big-fish ... │ │
│ │ -agent │ │ -runtime │ │
│ └──────────┘ │ -combat/npc │ │
│ └──────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ spacetime-module + spacetime-client → SpacetimeDB │ │
│ └──────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ 辅助子系统 │
│ apps/admin-web (React 后台管理) │
│ miniprogram/ (微信小程序) │
│ packages/shared (前后端共享契约/LLM工具) │
│ deploy/ (Docker/Nginx/systemd/OTel) │
│ scripts/ (40+ 构建/部署/检查脚本) │
│ jenkins/ (CI/CD Pipeline) │
└──────────────────────────────────────────────────────────────┘
```
---
## 四、架构亮点
1. **清晰的"玩法模板"平台模式**
每种玩法遵循统一的 `creation → result → runtime` 三段式生命周期,前端 `components/``services/` 均按此模式组织。新增玩法可快速套用模板,极大降低了横向扩展成本。
2. **后端严格的分层约束**
`api-server`(门面)→ `module-*`(领域)→ `spacetime-module`(持久化),`module-*` 不直接依赖 Axum、HTTP、SpacetimeDB table、LLM、文件系统,保证了领域纯净性和可测试性。
3. **SpacetimeDB 作为游戏状态核心**
采用反应式实时数据库替代传统 Redis + PostgreSQL 组合,天然适合多人实时游戏状态同步,减少了中间层复杂度和延迟。
4. **前端 DDD 探索**
`src/games/bark-battle/` 采用 `domain / application / infrastructure / ui` 四层 DDD 结构,为复杂玩法的前端架构提供了良好范本。
5. **完善的多入口路由体系**
通过 `resolveAppRoute()` 按 URL path 分发到不同的 lazy-loaded 组件,实现了按需加载和良好的首屏性能。
6. **运维体系完备**
Docker Compose + systemd + Nginx + OpenTelemetry + k6 压测 + Jenkins CI/CD,覆盖了构建、部署、监控、压测全链路。
---
## 五、问题诊断与改进方案
### 问题 1:前端 services/ 与 components/ 的耦合不统一
**现状**
大部分玩法遵循 `services/` + `components/` 分离模式,但部分玩法运行时直接放在 `components/` 下,services 层职责模糊——有的承担了业务逻辑编排,有的仅作简单 API 调用。
**影响**
- 新人阅读代码时无法预判某个逻辑应位于哪个目录
- 单元测试困难:services 与组件耦合的业务逻辑无法独立测试
- 跨玩法复用时需要额外的迁移成本
**改进方案**
1. 制定规范:`services/` 仅负责纯 API 调用和数据转换,不包含业务判断逻辑
2. 业务逻辑统一归到 `hooks/``games/<play-type>/application/`
3. 以 puzzle 玩法为样板,先行重构并形成迁移指南,再推广至其余玩法
4. 在 CI 中增加 ESLint 规则,禁止 `components/` 直接 import `services/` 之外的外部模块
**预期收益**
- 职责边界清晰,降低认知成本约 30%
- services 层可独立单测覆盖率达到 80%+
- 新玩法开发上手时间从 2 天缩短至 0.5 天
---
### 问题 2:前端 DDD 与模板模式并存,架构不统一
**现状**
`bark-battle` 采用 DDD 四层结构(`domain/application/infrastructure/ui`),其余玩法散落在 `components/` + `services/` 下,存在两种截然不同的组织范式。
**影响**
- 团队内部对"正确"的代码组织方式缺乏共识
- 代码审查时需要切换判断标准
- DDD 玩法的优势无法在全局范围内发挥
**改进方案**
1. 所有玩法统一迁移到 `src/games/<play-type>/` 下,采用 `domain / application / ui` 三层结构(infrastructure 按需保留)
2. 以 puzzle 为样板完成首例迁移,产出迁移 Checklist 和模板生成脚本
3. 新增玩法脚手架直接生成 DDD 结构目录
4. 旧玩法分批次迁移,每批次 2-3 个玩法,在 4 个迭代内完成
**预期收益**
- 架构一致性提升至 100%
- 跨玩法逻辑复用变得可能(domain 层可共享)
- 为后续 monorepo 改造打下基础
---
### 问题 3:后端 module-* 粒度偏细,存在潜在循环依赖风险
**现状**
后端共 35 个 crate。`module-runtime` 被拆分为 3 个独立 crate`module-combat / npc / inventory` 各自独立。部分紧密协作的模块之间可能存在隐式耦合。
**影响**
- 编译时间增长(35 个 crate 独立编译)
- 跨 crate 重构时需要同时修改多处
- 循环依赖风险增加,可能在特定组合下触发编译失败
**改进方案**
1. 评估合并方案:
- `module-runtime-*` 系列合并为单 crate `module-runtime`,内部用 `mod` 做逻辑隔离
- `module-combat / npc / inventory` 评估合并为 `module-combat`npc 和 inventory 作为子模块
2. 保留 trait/interface 抽象层,确保 module 之间不直接依赖具体实现
3. 在 CI 中引入 `cargo-deny` 或自定义脚本,自动检测 module 间的依赖方向是否违反分层约束
4. 目标:将 35 个 crate 精简至 25 个以内
**预期收益**
- 全量编译时间预计缩短 15%-20%
- 循环依赖风险归零
- module 内部重构成本降低
---
### 问题 4:根目录 env 文件过多且混乱
**现状**
根目录存在 4 个 env 文件(`.env``.env.example``.env.production` 等),且 `deploy/` 下另有多个 env 文件。配置分散在多处,部分文件之间字段不一致。
**影响**
- 排查配置问题时需要翻阅多个文件
- 新人无法快速确定本地开发需要哪些环境变量
- 部署时可能遗漏或错误覆盖某项配置
**改进方案**
1. 收敛为三层配置体系:
- `.env.example`:包含所有可配置项的说明和默认值(唯一提交到仓库的 env 文件)
- `.env.local`:本地开发覆盖(加入 .gitignore
- `deploy/env/<env-name>.env`:各部署环境专用配置
2. 引入 config crate,支持层次覆盖(default → local → env-specific),启动时自动校验必填字段
3. 在 CI 中加入 env 校验步骤:对比 `.env.example` 与部署环境的 env 文件,标记缺失或多余字段
**预期收益**
- 配置查找时间从分钟级降至秒级
- 部署配置遗漏导致的线上事故减少 90%+
- 新成员本地环境搭建时间从 30 分钟缩短至 10 分钟
---
### 问题 5scripts/ 目录膨胀为"万能工具箱"
**现状**
`scripts/` 目录共 42 个文件,涵盖构建、部署、检查、迁移、生成、压测等,全部平铺在同一层级,缺乏分类。
**影响**
- 难以快速定位所需脚本
- 同类脚本缺乏命名规范
- 新增脚本时不知道放在何处
**改进方案**
1. 按功能域分类重组:
```
scripts/
├── build/ # 构建相关(vite、cargo、wasm 等)
├── deploy/ # 部署相关(docker、systemd、rsync
├── check/ # 检查/校验(lint、format、type-check
├── spacetime/ # SpacetimeDB 相关(migration、seed
├── generate/ # 代码生成(scaffold、proto、types
└── loadtest/ # 压测脚本(k6 配置及辅助)
```
2. 为每个子目录添加 README.md,说明各脚本用途和调用方式
3. 将重复逻辑抽取为共享函数库
**预期收益**
- 脚本查找效率提升 60%+
- 降低脚本重复概率
- 便于 CI Pipeline 直接引用标准化路径
---
### 问题 6:前端路由系统缺乏统一的"玩法注册"机制
**现状**
`appRoutes.tsx` 中硬编码 `switch-case` 逻辑,每新增一种玩法需手动修改路由文件、入口组件、资源加载等多个位置。
**影响**
- 新增玩法的接入点分散,容易遗漏
- 路由文件随玩法增多持续膨胀
- 无法实现"按需注册"——即使某环境不包含某玩法,路由代码仍然存在
**改进方案**
1. 建立 `PlayTypeRegistry` 模式:每个玩法导出一个注册项对象,包含 `path``lazyComponent``preload` 等字段
2. `resolveAppRoute()` 改为动态聚合所有注册项,替代硬编码 switch-case
3. 支持环境级玩法开关:通过配置控制某环境启用哪些玩法,路由系统自动忽略未启用的
**预期收益**
- 新增玩法零侵入路由系统,只需在玩法目录内添加注册文件
- 路由文件体积与玩法数量解耦
- 灰度发布和 A/B 测试变得可能
---
### 问题 7:前端缺少统一的状态管理层
**现状**
前端状态管理依赖 React hooks + props drilling + services 层手动管理。未使用任何状态管理库(如 Zustand、Jotai、Redux)。
**影响**
- 全局状态(用户认证、会话、通知)通过多层 props 传递,组件耦合度高
- 跨页面状态无法优雅共享
- 状态变更难以追踪和调试
**改进方案**
1. 引入 Zustand(轻量、无 boilerplate、TS 友好)管理全局状态:
- `useAuthStore`:认证状态
- `useSessionStore`:当前会话/游戏状态
- `useNotificationStore`:全局通知
2. 玩法内状态继续使用 React hooks + `useReducer`,保持局部自治
3. 全局 store 与玩法内 state 通过事件总线松耦合通信
**预期收益**
- props drilling 层级从 5+ 层降至 1-2 层
- 全局状态可追溯,支持 Redux DevTools 调试
- 跨玩法状态共享(如用户余额、道具)变得自然
---
### 问题 8shared-contracts 的实际复用程度待验证
**现状**
前后端通过 `packages/shared` 共享 DTO 类型定义,但依赖手动同步 TypeScript 类型。可能存在前后端契约不一致但编译期无法检出的情况。
**影响**
- 后端修改 DTO 字段后,前端可能遗漏更新导致运行时错误
- 手动同步耗时且易出错
- Code Review 时难以判断契约一致性
**改进方案**
1. 引入 `ts-rs`:从 Rust 结构体自动生成 TypeScript 类型定义
2. 将生成步骤集成到 CI Pipeline
- 每次 Rust PR 触发 `ts-rs` 重新生成 TS 类型
- 对比生成的类型与仓库中的类型是否一致,不一致则 CI 失败
3. 长期考虑引入 Protobuf / OpenAPI 作为跨语言契约的单一事实来源
**预期收益**
- 前后端契约不一致导致的线上 bug 减少 95%+
- 手动同步工作量归零
- PR Review 时契约一致性问题自动拦截
---
## 六、改进优先级路线图
| 优先级 | 改进项 | 涉及层 | 建议时间 | 预期收益 |
|---|---|---|---|---|
| **P0** | 统一前端 services/hooks/components 职责边界 | 前端 | 第 1-2 周 | 降低认知成本,提升可测试性 |
| **P1** | 建立 PlayType 注册机制 | 前端 | 第 2-3 周 | 新增玩法零侵入路由 |
| **P1** | 评估 module-* 合并方案并执行 | 后端 | 第 3-4 周 | 减少编译时间 15%-20% |
| **P1** | 引入 Zustand 全局状态管理 | 前端 | 第 4-5 周 | 改善状态追踪与跨组件共享 |
| **P2** | 清理 scripts/ 目录结构 | 工程 | 第 5-6 周 | 提高可发现性 |
| **P2** | 前端玩法统一迁移至 DDD 结构 | 前端 | 第 5-8 周 | 架构一致性 100% |
| **P2** | env 配置收敛 | 工程 | 第 6-8 周 | 减少部署配置事故 |
| **P3** | 前后端共享 DTO 自动化(ts-rs) | 全栈 | 第 6-8 周 | 消除契约不一致风险 |
| **P3** | CI 分层约束检查(cargo-deny | 后端 | 第 8-10 周 | 循环依赖归零 |
> **说明**:P0 为阻塞项,必须最先完成。P1 项可部分并行推进(PlayType 注册与 module 合并互不依赖)。P2/P3 为优化项,可在日常迭代中穿插推进。
---
## 七、架构健康度评分卡
| 维度 | 评分 | 当前状态 | 目标状态 |
|---|---|---|---|
| **分层清晰度** | ★★★★☆ | 后端分层严格,前端分层存在不一致 | ★★★★★ 前后端均严格分层 |
| **模块化程度** | ★★★★☆ | 后端 35 crate 粒度偏细,前端结构化较好 | ★★★★☆ 后端精简至 25 crate |
| **可扩展性** | ★★★★★ | 玩法模板模式使新增玩法成本低 | ★★★★★ 维持 |
| **代码复用** | ★★★☆☆ | shared 层作用有限,services 层有重复 | ★★★★☆ DDD 统一后 domain 可复用 |
| **DevOps 成熟度** | ★★★★★ | Docker + k6 + OTel + Jenkins 覆盖完整 | ★★★★★ 维持 |
| **文档完备性** | ★★★★★ | docs/ 分类清晰,基线文档齐全 | ★★★★★ 维持 |
| **技术债务管控** | ★★★★☆ | 有明确的"历史残留"标记和废弃策略 | ★★★★★ 增加自动化检测 |
**综合评级:A-(优秀,存在可优化空间)**
---
## 八、附录:代码规模统计
| 维度 | 数量 |
|---|---|
| **前端 TypeScript/TSX 文件** | ~823 个 |
| **后端 Rust 源文件** | ~1532 个 |
| **后端 Crate 数量** | 35 个 |
| **核心玩法类型** | 10+ 种 |
| **scripts/ 脚本数量** | 42 个 |
| **根目录 env 文件** | 4 个 + deploy 下多个 |
### 模块规模明细(后端)
| Crate | 职责 | 建议 |
|---|---|---|
| `api-server` | Axum HTTP 门面,路由聚合 | 保持 |
| `platform-*` (auth/llm/image/oss/speech/agent) | 平台级跨玩法能力 | 保持 |
| `module-puzzle` | 拼图玩法 | 作为 DDD 迁移样板 |
| `module-visual-novel` | 视觉小说 | 后续迁移 |
| `module-match3d` | Match3D 三消 | 后续迁移 |
| `module-bark-battle` | 犬吠对战 | 已对接前端 DDD |
| `module-big-fish` | Big Fish | 后续迁移 |
| `module-runtime*` (3 crates) | 通用运行时 | **建议合并为单 crate** |
| `module-combat / npc / inventory` | 战斗系统 | **建议合并** |
| `spacetime-module` + `spacetime-client` | SpacetimeDB 接入 | 保持 |
| `shared-contracts / kernel / logging` | 共享基础设施 | 保持 |
---
> **文档结束**
> 本计划书由 Genarrative 架构分析报告衍生,所有改进项均基于对当前项目代码库的实际分析。执行过程中如遇阻力或新发现,应及时更新本计划书并同步相关方。
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
@@ -1,25 +1,6 @@
# 文档地图与阅读索引
更新时间:`2026-08-10`
## 当前文档入口
| 场景 | 优先阅读 |
| --- | --- |
| 建立项目背景 | `README.md``AGENTS.md``docs/project-memory/shared-memory/project-overview.md` |
| Agent 复杂任务执行规则 | `AGENTS.md``docs/【协作规范】Agent工作入口与执行准则-2026-06-22.md` |
| 找当前文档 | `docs/README.md` |
| 产品、命名、UI、协作和废弃路线 | `docs/【项目基线】当前产品与工程约束-2026-05-15.md` |
| 后端、DDD、API、SpacetimeDB schema 和表目录 | `docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md` |
| 创作入口、草稿架和玩法链路 | `docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` |
| 创作流程统一阶段计划 | `docs/planning/【玩法创作】创作流程统一总计划-2026-05-30.md` |
| 宿主壳、移动 App、桌面 App 与 AI H5 沙箱边界 | `docs/【前端架构】宿主壳能力统一协议-2026-06-17.md``docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md` |
| AI 游戏创作独立 App、立项策划、Agent Runtime、Runner、浏览器验证与动态隔离子 Agent | `docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md``docs/technical/【技术方案】立项策划AgentFast GDD-2026-08-10.md``docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md` |
| 本地启动、验证、部署、埋点和运营查询 | `docs/【开发运维】本地开发验证与生产运维-2026-05-15.md` |
| 微信小程序虚拟支付 | `docs/【技术方案】微信虚拟支付接入-2026-05-26.md` |
| UI 像素资产与 9-slice 规范 | `UI_CODING_STANDARD.md` |
| 图片画布生成面板与模型定价 | `docs/【编辑器】生成类面板Lovart统一改造方案-2026-06-17.md``docs/【编辑器】模型定价配置管理方案-2026-06-22.md` |
| 图片画布右侧 Agent 对话、会话消息 OSS 持久化、普通 JSON 消息、工具任务懒回填及侧栏并存规则 | `docs/【编辑器】画布Agent对话面板-2026-07-03.md``docs/adr/【ADR】画布Agent会话消息存OSS-2026-07-03.md` |
更新时间:`2026-08-25`
## 阅读顺序
@@ -27,42 +8,44 @@
1. `AGENTS.md`
2. `docs/【协作规范】Agent工作入口与执行准则-2026-06-22.md`
3. `docs/project-memory/shared-memory/`
4. `docs/README.md`
5. 与任务匹配的当前融合文档
3. `docs/README.md`
4. `docs/project-memory/shared-memory/`
5. 与任务匹配的当前专题合同
后端 / 数据真相 / SpacetimeDB
1. `docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`
2. `docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`
3. 对应 crate README 源码
3. `server-rs/crates/api-server/src/app.rs``server-rs/crates/api-server/src/modules.rs`对应 crate README / 源码
4. `docs/openapi/genarrative-external-v1.openapi.json`(涉及 External v1 时)
玩法 / 创作入口 / 运行态
1. `docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`
2. 若任务涉及跨玩法创作流程统一,读取 `docs/planning/【玩法创作】创作流程统一总计划-2026-05-30.md`
3. `docs/【项目基线】当前产品与工程约束-2026-05-15.md`
4. 相关前端组件、service、shared contract 和后端 module
AI 游戏创作独立 App / 立项策划 / Agent Runtime
AI 游戏创作 / DirectProject / UI workflow
1. `docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`
2. 涉及立项策划、Fast GDD、审批或构建基线时,读取 `docs/technical/【技术方案】立项策划AgentFast GDD-2026-08-10.md`
3. 涉及 Runtime 工具、持久化、恢复或 Profile 时,读取 `docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md`
4. 涉及正式工作台 UI 时,读取 `docs/prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md`
2. `docs/prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md`
3. `docs/technical/【技术方案】立项策划AgentFast GDD-2026-08-10.md`
4. `docs/technical/【技术方案】GameAgent资源自由画板与快速编辑-2026-08-20.md`
5. `docs/【技术方案】UI工作流资源桥接与Runtime执行-2026-08-24.md`
6. UI 编辑器、宿主壳和当前测试专题文档
图片画布 / 媒体生成:
1. `docs/technical/【技术方案】客户端素材创作无限画布阶段一合同-2026-08-05.md`
2. `docs/【编辑器】图片画布结构化持久化与迁移回滚方案-2026-07-19.md`
3. `docs/technical/【后端架构】编辑器生成结果原子提交与幂等重放方案-2026-08-06.md`
4. `docs/【编辑器】画板音乐生成入口设计-2026-06-18.md`
生产部署 / 服务器 / Jenkins
1. `docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`
2. `deploy/env/api-server.env.example`
3. `deploy/nginx/README.md`
2. `docs/technical/【开发运维】Jenkins容器预览部署控制面技术方案-2026-08-15.md`
3. `deploy/` 当前脚本、systemd unit、Nginx README 和实际主机状态
## 维护规则
## 生命周期规则
- 当前 `docs/` 只保留少量融合文档
- `AGENTS.md` 只保留最高优先级入口;Agent 执行细则优先沉到 `docs/【协作规范】Agent工作入口与执行准则-2026-06-22.md` 或对应专题文档
- 新增工程实现时,如果已有对应当前文档,必须同步更新
- 如果没有合适位置,新文档文件名必须使用 `【标签名】中文标题-YYYY-MM-DD.md`
- 阶段性流水账、一次性修复记录和已关闭实验不要再新增为长期文档
- 阶段性计划和一次性 TODO 不再作为长期文档目录;需要保留的决策、流程和坑点应进入 `docs/` 当前文档或 `docs/project-memory/shared-memory/`
- 如果文档与代码冲突,先确认代码事实,再更新过期文档和共享记忆。
- `docs/README.md` 是人工阅读入口;代码和当前专题冲突时,以代码和最新专题为准
- `shared-memory/` 只保留稳定事实、唯一决策、通用流程和已验证坑点
- `plans/` 只保留正在执行且有明确下一门禁的计划;完成或作废后删除或融合
- `todos/` 只保留真实开放、有人负责且有关闭条件的事项;退役对象不保留未来准入 TODO
- 一次性实施记录、阶段测试数字、分支历史和旧方案不进入长期入口,追溯使用 Git 历史
- 新增 Markdown 文件名使用 `【标签名】中文标题-YYYY-MM-DD.md`;不为历史文件做无关批量重命名

Some files were not shown because too many files have changed in this diff Show More