同步 AGC 资源 kind 枚举化的实施计划、里程碑与扫描清单
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Successful in 5m22s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Successful in 5m16s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Successful in 5m4s
Project CI / Backend tests (pull_request) Failing after 10s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 1m39s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Successful in 4m40s
Project CI / Repository checks (pull_request) Failing after 11s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m1s
Project CI / AI game creator shell web tests (pull_request) Successful in 3m3s
Project CI / Frontend tests (pull_request) Successful in 4m35s
Project CI / Native shell tests (pull_request) Successful in 6m44s

- 实施计划:记录已落地内容(kind 由 `String` 收紧为枚举的破坏性变更、写入与读取统一正式成员、资源编辑源身份词汇表、`cargo test export_bindings` 生成路径、TS 穷举派生)
- 实施计划:修正「明确不修改」与验证命令,去掉与当前代码不符的表述
- 里程碑:验收标准除旧 alias 读边界一项外全部勾选,并补记 ts-rs 生成与退役类型导出两项证据
- 扫描清单:把「当前未决项」逐条落成结论(`asset`、`art-spritesheet*`、`game-*`、`ui*`、`Unknown` trace、生成路径),只保留 CI verify 接入一项待办
This commit is contained in:
2026-09-16 19:08:28 +08:00
parent f9bc2d917c
commit 7eee89ded3
3 changed files with 30 additions and 21 deletions
@@ -18,33 +18,39 @@
本切片已落地:
- `GameCreationAppAssetManifestEntry.kind` `GameCreationAppAssetKind`;manifest 反序列化未知值收口为 `Unknown`
- `GameCreationAppAssetManifestEntry.kind` `String` 收紧`GameCreationAppAssetKind`:这是公开 Rust 类型的破坏性变更,按「不写历史兼容代码」直接改类型,不加兼容层、不做数据迁移;manifest 反序列化未知值收口为 `Unknown`
- 上传内容推断的字体写入 `Font`,未知上传类型写入 `Unknown`;图集切片 manifest 写入 `Icon`
- shell TS 资源引用边界开始消费生成绑定,并为未知值保留原始值与上下文日志
- shell 内 manifest kind 的写入侧与读取侧统一为正式枚举成员:资源登记、字体导入、direct runtime 产物、平台美术登记与恢复、manifest 必填校验、资源编辑派生、UI 设计桥接与工作流
- 资源编辑请求的 `sourceSubtype` 只传正式枚举成员;资源编辑内部源身份拆成「正式 kind / 项目版本 / Agent 回执」三类,项目版本与 Agent 回执不再冒充 manifest kind。
- ts-rs 绑定改由 `cargo test export_bindings` 生成:枚举自带 `#[ts(export, export_to = …/src/contracts/generated/)]`;退役的 `BindingDTO` / `BindingChange` 不再导出,手写的 `exports_ui_editor_types` 已删除。
- `src/contracts/generated/` 加入 `.prettierignore` 与 eslint `ignorePatterns`,生成文件保持 ts-rs 原始格式,`cargo test export_bindings` 可幂等复现且不再污染工作树。
- shell TS 资源引用边界消费生成绑定,资源 kind 集合从生成的 union 穷举派生,并为未知值保留原始值与上下文日志。
明确不修改:
- manifest 结构体的 `kind: String` 字段及所有调用方(留给下一个小提交);
- `category``mediaType``source.kind``source.generationKind`
- api-server、SpacetimeDB schema、OpenAPI
- alias/fallback 删除和 Unknown writer 处理(留给后续切片)。
- shared-contracts 的 canonical alias 表与读时自愈:本次不新增、不扩展,留给独立词汇收敛切片;
- `packages/shared` 中重复的资源 kind 手写契约与其余前端裸 `string` 字段(后续切片)。
## 实现顺序
1. 新建独立 kind 模块,定义当前正式成员:17 个现有 canonical kind + `font` + `Unknown`serde 使用 kebab-case。
2. 为 enum 增加可选 ts-rs derive,默认 shared-contracts 构建不引入 ts-rs。
3. 让 shell 的 shared-contracts 依赖打开绑定 feature,在 shell 专属 contracts/generated 目录生成 TS。
4. 增加 Rust serde round-trip 与 Unknown 解析/序列化测试;增加 TS 生成文件存在和值集合测试
未知值通过 `parse_with_context` 收口到 `Unknown`,并在启用 shell 的 `kind-observability` feature 时记录原始值与解析上下文。
5. 运行 shared-contracts 与 shell 定向测试;通过后暂停,等待下一个内部字段收紧切片。
4. 增加 Rust serde round-trip 与 Unknown 解析/序列化测试;TS 侧不再手写生成值集合,改为从生成 union 穷举派生
未知值通过 `parse_with_context` 收口到 `Unknown`,并在启用 shell 的 `kind-observability` feature 时记录原始值与解析上下文。
5. 运行 shared-contracts 与 shell 定向测试,并用 `export_bindings` 复现生成文件;通过后暂停,等待下一个内部字段收紧切片。
## 验证命令
1. `cargo fmt --all -- --check`
2. `cargo test --locked -p shared-contracts game_creation_app --manifest-path server-rs/Cargo.toml`
3. `cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml exports_game_creation_app_asset_kind`
4. `npm run check:encoding`
5. `git diff --check`
3. `cargo test --locked -p shared-contracts --features ts-bindings export_bindings --manifest-path server-rs/Cargo.toml`(生成 `apps/ai-game-creator-shell/src/contracts/generated/GameCreationAppAssetKind.ts`
4. `cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml export_bindings`(生成 shell 自己的 ts-rs 绑定)
5. `npx vitest run apps/ai-game-creator-shell/tests/assetKind.test.ts apps/ai-game-creator-shell/tests/assetKindCanonicalMapping.test.ts`
6. `npm run check:encoding`
7. `git diff --check`
## 风险与回滚点
@@ -31,8 +31,10 @@
## 验收标准
- [ ] Rust enum 与生成的 TS 绑定值逐项一致,JSON 使用 kebab-case;正式资源成员为当前 17 个 canonical kind 加 `font`,另有 `Unknown` 解析成员。
- [ ] 未知输入得到 `Unknown`,日志包含原始值与调用上下文。
- [ ] 生产 writer 不再接受裸 `string` 作为 GameCreationApp kind。
- [ ] `font``audio``sound-effect``background-music` 均有真实生产路径或明确的测试证据
- [ ] 旧 alias 不再由共享契约转换为 canonical
- [x] Rust enum 与生成的 TS 绑定值逐项一致,JSON 使用 kebab-case;正式资源成员为当前 17 个 canonical kind 加 `font`,另有 `Unknown` 解析成员。TS 侧不再手写值集合,改为对生成 union 做穷举 `Record`
- [x] 未知输入得到 `Unknown`,日志包含原始值与调用上下文`parse_with_context` + `kind-observability`
- [x] 生产 writer 不再接受裸 `string` 作为 GameCreationApp kindmanifest 写入、资源登记、direct runtime、平台美术登记、资源编辑派生均只传枚举成员)
- [x] `font``audio``sound-effect``background-music` 均有真实生产路径(字体导入、上传音频推断、资源编辑音频派生)
- [x] ts-rs 绑定由 `cargo test export_bindings` 生成,生成目录加入 `.prettierignore` / eslint `ignorePatterns`,可幂等复现且不污染工作树
- [x] 退役的 `BindingDTO` / `BindingChange` 不再导出,手写的 `exports_ui_editor_types` 已删除。
- [ ] 旧 alias 不再由共享契约把非 canonical 输入收口成 canonical(该表属读边界,本次未新增也未扩展,留给独立词汇收敛切片)。
@@ -78,12 +78,13 @@
## 当前未决项
- [ ] 逐处确认 `asset` 是错误 fallback 还是其他领域标识
- [ ] 逐处确认 `art-spritesheet` / `art-spritesheet-slice` 是 manifest kind 还是图集 workflow 标识
- [ ] 逐处确认 `game-background` / `game-art` / `illustration` / `character-art` 的写入边界
- [ ] 逐处确认 `ui` / `ui-prototype` 是否仍有生产 manifest writer。
- [ ] 确认 `Unknown` 的 tracing 字段和 writer 禁止规则
- [ ] 确认 ts-rs 生成文件的实际路径、生成命令和 CI verify 实现
- [x] `asset`:确认是上传推断的兜底值,已改为无法判断时写 `Unknown`,不再回落到 `asset`
- [x] `art-spritesheet` / `art-spritesheet-slice`:确认是平台请求与图集 workflow 词汇;manifest 写入分别收口为 `IconSpritesheet` / `Icon`,协议标识只留在各自字符串字段
- [x] `game-background` / `game-art` / `illustration` / `character-art`:确认只出现在平台请求词汇;写入 manifest 前经显式转换函数收口为 `scene` / `image` / `character`
- [x] `ui` / `ui-prototype`:确认 UI 设计桥接与工作流已无生产 manifest writer,只写 `ui-design` / `ui-design-doc`
- [x] `Unknown` 的 tracing 字段`raw_kind` + `source_context`,由 `kind-observability` feature 控制;生产 writer 只传正式枚举成员
- [x] ts-rs 生成路径为 `apps/ai-game-creator-shell/src/contracts/generated/`,命令为 `cargo test -p shared-contracts --features ts-bindings export_bindings`(枚举自带 `export_to`),生成目录已在 `.prettierignore` / eslint `ignorePatterns` 中保持原始格式
- [ ] 接入 CI verify(在 CI 中跑一次 `export_bindings` 并断言生成文件无 diff)。
## 已确认的 manifest kind 入口(M0 审计结果)