修复AGC依赖锁文件缺失 (#174)
Project CI / Repository checks (push) Successful in 3m30s
Project CI / Backend tests (push) Successful in 4m14s
Project CI / Frontend tests (push) Successful in 4m16s
Project CI / Native shell tests (push) Successful in 15m42s

## 问题

合并后的 `master` 连续暴露了三个既有的 AGC 原生构建 blocker:

1. `npm ci --prefix apps/ai-game-creator-shell` 因 lockfile 缺少 `@emnapi/core` / `@emnapi/runtime` 嵌套节点而失败。
2. 修复安装后,Linux Tauri build 又因通用配置无条件引用未生成的 Windows Codex 侧车而失败。
3. Native shell 全量测试继续暴露三项内置 Skill 指纹从初次提交起即与最终文件字节不一致,以及 Linux 会把 Windows 路径语法误判为普通相对路径。

这些问题都在画布优化合并前的 AGC 集成提交中已经存在;画布优化未修改 AGC manifest、lockfile、Tauri 配置或 Skill Pack。

## 修复

- 使用子包 manifest 重新生成独立 package-lock 元数据
- 恢复 Tailwind oxide WASM bundled `@emnapi` 节点并保留 npm 元数据规范化
- 把 Codex Windows x64 侧车映射从通用配置迁到 `tauri.windows.conf.json`
- 配置门禁同时约束通用配置无 Windows resource、Windows 配置保留完整白名单
- 重算三项内置 Skill 内容指纹并提升审核包版本
- Skill 引用路径按平台无关规则拒绝反斜杠、盘符、UNC、绝对路径和父目录段
- 补充 MCP 回归,并同步技术方案、迁移计划和长期排障记录

## 验证

- npm 10.9.7 / npm 9.2.0:`npm ci --prefix apps/ai-game-creator-shell` 通过
- Linux:`npm run ai-game-creator-shell:build -- --no-bundle` 通过
- Skill 指纹 5/5 复算匹配;Skill / MCP 定向测试通过
- `npm run check:native-shells` 完整通过:AGC Rust `2159 passed / 0 failed / 15 ignored`,最终输出 `[check:native-shells] OK`
- `npm run check:encoding`、`npm run check:rustfmt`、本次目标文件 Prettier、`git diff --check` 通过
- AGC、desktop、server-rs Cargo.lock 与两份 package-lock 均无漂移

Reviewed-on: #174
Co-authored-by: kdletters <kdletters@qq.com>
Co-committed-by: kdletters <kdletters@qq.com>
This commit was merged in pull request #174.
This commit is contained in:
2026-08-21 17:38:58 +08:00
committed by 段舒康
parent c39d63b65f
commit e8d9367df7
10 changed files with 172 additions and 62 deletions
@@ -150,7 +150,7 @@
- 真实创建项目时,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-256,Tauri resources 保持 `bin/`、`codex-path/`、`codex-resources/` 布局。API Key、登录状态和用户配置仍不进入安装包。
- Windows x64 内置资源现按固定白名单 stage 完整原生组件闭包;清单升级为 `genarrative-codex-sidecar.v2`,逐文件记录并校验 SHA-256,Tauri 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` 与旧诊断入口仍保留原严格检查,不能冒充真实浏览器试玩。
@@ -316,7 +316,7 @@
### 14.2 审核索引与五类 Skill
客户端内置 `agc-skill-pack.v1` 清单。每项只公开名称、用途、触发条件、所需工具、版本和内容 SHA-256;启动时逐文件复核清单和编译进客户端的内容,任何缺失、额外文件、路径越界或指纹不匹配都失败关闭。审核包只包含:
客户端内置 `agc-skill-pack.v1` 清单。每项只公开名称、用途、触发条件、所需工具、版本和内容 SHA-256;审核文件变化时必须在同次变更重算对应指纹。启动时逐文件复核清单和编译进客户端的内容,任何缺失、额外文件、路径越界或指纹不匹配都失败关闭;路径边界显式拒绝反斜杠、Windows 盘符、UNC、绝对路径和 `..`,不能因测试运行在 Linux 就把 Windows 绝对路径当作普通相对文件名。审核包只包含:
1. `agc-project-structure`:项目根、`game/`、`assets/`、`.agent/` 的职责和禁止创建平行项目的约束。
2. `taonier-art-assets`:陶泥儿标准美术包、平台来源、警告语义和真实素材使用;`grid-2x2` 与四切片只是推荐路径,不是所有游戏的完成门。
@@ -4216,6 +4216,27 @@
- 处理:CONNECT 一开始就为 client socket 注册 `error / close`,解析完成后为 upstream socket注册同样的双向销毁处理;DNS 返回、写 200 和开始 pipe 前都检查 client 是否已销毁。任一端 error、close 或 timeout 都幂等 destroy 两端,不把普通客户端 reset 写成错误日志。不要用进程级 `uncaughtException` 吞掉问题,也不要只增加 npm/Cargo 重试掩盖 gateway 崩溃。
- 验证:在独立 canary 和正式 gateway 上分别并发制造至少 500 次“CONNECT 后立即断开”,随后确认容器仍运行、restart count 不增加、日志无 EPIPE;再通过同一 proxy 对 npm registry 与 crates index 建立完整 TLS 隧道。切换前仍须确认 Gitea 无活跃 run 且 Runner 内层无 job 容器。
## 独立 AGC lockfile 不能丢失可选 WASM 包的 bundled 依赖节点(2026-08-21)
- 现象:`npm ci --prefix apps/ai-game-creator-shell` 在安装前失败,报告 lockfile 缺少 `@emnapi/core` / `@emnapi/runtime`;错误版本可能是 registry 当前满足 `^1.11.1` 的最新版,而不是原 lock 中曾记录的版本。
- 原因:重写或解决 `apps/ai-game-creator-shell/package-lock.json` 冲突时,保留了 `@tailwindcss/oxide-wasm32-wasi` 对 bundled `@emnapi` 包的声明,却删掉了对应嵌套 package 节点。npm 会重新解析当前 registry 版本并判定 manifest 与 lock 不同步;这不是单一 npm 版本问题,也不表示应用应直接依赖两个 `@emnapi` 包。
- 处理:只在最新目标分支执行 `npm install --package-lock-only --ignore-scripts --prefix apps/ai-game-creator-shell`,保留 npm 对 bundled 节点及 `peer` / `optional` 标记的完整规范化结果;确认子包 `package.json` 没有变化,不要手工只补报错中的两个版本。
- 验证:至少用 Jenkins 对应 npm major 和当前开发 npm 分别执行干净的 `npm ci --prefix apps/ai-game-creator-shell`,再运行 AGC typecheck、编码检查和 `git diff --check`;根目录 `npm ci` 不能替代独立子包 lock 验证。
## Windows 专属 Tauri resource 不能写进通用配置(2026-08-21)
- 现象:Linux CI 已完成 AGC `npm ci`,却在 Tauri custom build command 中报 `resources/codex/win-x64/...exe doesn't exist`;Windows 侧车的 Rust staging 受 `cfg(windows)` 保护,因此非 Windows 构建不会生成这些文件。
- 原因:Tauri 会在所有平台校验通用 `tauri.conf.json` 的 bundle resource 源路径;把 Windows x64 资源映射写进通用配置,等于要求 Linux / macOS 也预先拥有不属于其安装闭包的 Windows 可执行文件。
- 处理:通用配置只保留跨平台 bundle 项;Windows 原生侧车的完整白名单放入 Tauri 自动合并的 `tauri.windows.conf.json`。不要提交二进制占位文件,也不要让非 Windows build script 下载或伪造 Windows 资源。
- 验证:配置门禁断言通用配置没有 Windows resource、Windows 平台配置保留完整固定白名单;Linux 运行原生壳门禁必须越过 Tauri resource 校验,Windows release 仍由 build script 对 npm 原生包、SHA-256 清单和目标布局失败关闭。
## AGC Skill 指纹与相对路径校验必须跨平台一致(2026-08-21)
- 现象:内置 Skill 文件集合没有缺失,原生测试却统一报内容指纹不匹配;另一个测试在 Linux 上把 `C:\\temp\\SKILL.md` 判为安全相对路径,受控资源工具可能继续处理 Windows 盘符或反斜杠遍历形式。
- 原因:审核文件定稿后未按最终字节重新生成 manifest SHA-256;同时 `std::path::Path` 只按当前宿主语义解析路径,Linux 不会把 Windows 盘符和反斜杠视为绝对路径或分隔符。
- 处理:Skill 文件变化与 manifest 指纹更新必须同次提交,并提升审核包版本;资源引用只接受使用 `/` 的普通相对段,显式拒绝反斜杠、冒号盘符、UNC、绝对路径和父目录段,再查询审核清单。不要先把反斜杠替换成 `/` 后再做安全检查。
- 验证:逐项按排序后的 `relativePath + NUL + file bytes + NUL` 重算并核对 manifest;Rust 单测同时覆盖 POSIX 绝对路径、`..`、`C:\\...`、`C:/...`、UNC 和反斜杠相对路径,受控 MCP 工具也必须把 Windows 绝对路径投影为 `isError=true`。
## Gitea CI 预构建镜像不能只靠 tag 判断内容
- 现象:宿主已重建带日期修订 tag 的 `genarrative/gitea-project-ci` 镜像,但 `genarrative-ci` job 仍跑旧内容,或直接报 image not found;另一种危险操作是只改 runner label,没把对应镜像装入 rootless runner 的内层 Docker。