Merge branch 'master' into opt/win-ssache
Project CI / AI game creator shell Rust tests (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled

This commit is contained in:
2026-09-14 16:16:49 +08:00
8 changed files with 554 additions and 168 deletions
@@ -3,6 +3,15 @@
> 用途:记录已经确认、会影响后续开发的长期技术/产品/协作决策。短期讨论不要写在这里。
> 当前口径:历史条目的旧路径、旧版本和已退役对象只用于追溯,不构成现行实现依据;如与当前代码或 `docs/README.md` 冲突,以当前代码和最新专题文档为准。
## 2026-09-14 客户端 CI 按门禁组拆成三个 job,AGC 的 web / rust 两段并行
- 背景:`Project CI / Native shell tests` 把微信壳、Expo 移动壳、Tauri 桌面壳、H5 HostBridge 与 AI 游戏创作壳的全部门禁串在一个 job 里,实测 18 分 37 秒;同一次运行的 Repository / Frontend / Backend 分别只要 3 分 21 秒、4 分 16 秒、6 分 14 秒,其余三个 job 结束后客户端 job 还要再跑十几分钟。日志时间戳显示门禁段 932 秒里:AGC `ai-game-creator-shell:check` 占 654 秒(其中壳内 Rust 套件 2451 个用例 `--test-threads=1` 单跑 441.58 秒、编译 79 秒),AGC vitest 75 秒,两个发布构建 smoke 加落盘断言 230 秒,而 h5 / 微信 / 移动 / 桌面壳的全部运行时门禁加起来不到 50 秒。
- 决策:`scripts/check-native-shells.mjs` 引入 `--groups=`,把门禁分成 `contract`(静态契约断言)、`shells`(H5 / 微信 / Expo / 桌面壳运行时门禁)、`agc-web`(AGC typecheck 与壳内测试)、`agc-rust`(共享 / 平台 crate 测试、AGC 串行壳测试、agent-run smoke)、`release`(AGC 与桌面壳发布构建 smoke、落盘产物断言)五组,每组暴露一个 `check:native-shells:<group>` 根脚本;不带 `--groups=` 时仍然串行跑全部分组,本地 `npm run check:native-shells` 语义不变。CI 据此把原客户端 job 拆成 `Native shell tests`(contract + shells + release)、`AI game creator shell web tests`(agc-web)、`AI game creator shell Rust tests`(agc-rust)三个 job,并把最长的 AGC Rust job 声明在最前,使 runner 领取顺序与关键路径一致。
- 命令等价:`npm run ai-game-creator-shell:check` 拆成 `:check:web`(typecheck + 壳内测试)与 `:check:rust`(agent-runtime 两个独立 crate + `platform-llm` + `shared-contracts` + AGC 壳串行测试),聚合脚本仍是 `web && rust && agent-run:smoke` 同序同命令,本地与文档入口不变。`agent-run:smoke` 会用 `src-tauri/Cargo.toml` spawn `cargo`,因此归入 `agc-rust` 分组,与 AGC 依赖预热同 job。
- 影响范围:`.gitea/workflows/project-ci.yml`(六个 job)、`scripts/check-native-shells.mjs`、根 `package.json` 门禁脚本、`scripts/project-ci-workflow.test.ts`(校验分组清单、根脚本内容与 job 覆盖,防止新增分组时静默漏跑)、开发运维文档与开发流程记忆。门禁覆盖不变,只有执行位置改变;Gitea `master` 分支保护的 required context 是追加式的(旧四个继续上报,需补上两个新 AGC context)。
- 验证方式:`npx vitest run scripts/project-ci-workflow.test.ts`(11 条);`node scripts/check-native-shells.mjs --groups=contract` 本地 0.6 秒通过;`--groups=` 未知组与空组都要报错关闭。实测耗时按拆分前同一 run 的日志时间戳折算:关键路径从 18 分 37 秒收敛到 AGC Rust job 的约 13 分钟量级(若 runner 并发槽位 ≥ 6,可压缩到约 10.5 分钟)。
- 关联文档:[开发运维](../../【开发运维】本地开发验证与生产运维-2026-05-15.md)、[踩坑记录](pitfalls.md)。
## 2026-09-10 策划 Agent 迁移只复用生产基建
- 决策:待实施的生产迁移以自由协作策划原型为行为基线,仅复用 Provider、恢复、文件操作、审计和 UI 通信;不继承旧 Planning V2 的强制工具、问询轮数、GDD 内容校验和版本审批。保留五阶段与顾问态、当前阶段资源注入和产物存在性检查,系统阶段空必需清单不增加解析或登记功能。
@@ -74,4 +74,4 @@ SpacetimeDB 任务统一先读取 `.codex/skills/genarrative-spacetimedb/SKILL.m
## Gitea CI 依赖闭合
`.gitea/workflows/project-ci.yml` 的 `Native shell tests` 在运行原生壳门禁前,必须使用 `cargo fetch --locked` 预取 `server-rs/Cargo.toml`、桌面壳和 AGC 壳三份依赖。Backend host workspace tests 使用 `cargo test --locked --workspace --exclude spacetime-module --no-fail-fast`,避免 `spacetime-module` 的 `spacetime-types` feature 统一污染普通领域 crate 的 host 测试;随后单独执行 `cargo test --locked -p spacetime-module --no-fail-fast`,由 `spacetime-module/src/active.rs` 在 host 测试构建期间提供仅测试期的 SpacetimeDB ABI 链接支持,使该 crate 的纯单元测试也纳入 Backend 门禁。`spacetime-module` 的 reducer / procedure 运行时行为仍必须通过真实 SpacetimeDB runtime/integration harness 验证,host 链接支持不得被当作运行时替身。Backend 另外执行 `cargo check --locked -p spacetime-module` 验证模块源码。AGC 壳检查还会运行 `platform-llm` 与 `shared-contracts` 的 server-rs workspace 测试,这些命令以及 AGC 壳测试必须带 `--locked`,避免在测试阶段重新解析 registry index;锁文件发生变化时应先更新受信任 CI 镜像缓存,再重跑门禁。
`.gitea/workflows/project-ci.yml` 的客户端门禁拆成三个 job,每个 job 只预热自己会构建的那几份依赖:`AI game creator shell Rust tests` 用 `cargo fetch --locked` 预取 `server-rs/Cargo.toml` 与 AGC 壳 manifest(`agent-run` smoke 会用 `src-tauri/Cargo.toml` spawn `cargo`,因此必须同 job),`Native shell tests` 预取桌面壳与 AGC 壳 manifest,`AI game creator shell web tests` 不触碰 Cargo,不预热。两个被 `server-rs/Cargo.toml` 排除、且没有提交 `Cargo.lock` 的独立 crate(`agent-runtime-core`、`agent-runtime-orchestration`)只能在 `AI game creator shell Rust tests` 里用不带锁标志的 fetch。Backend host workspace tests 使用 `cargo test --locked --workspace --exclude spacetime-module --no-fail-fast`,避免 `spacetime-module` 的 `spacetime-types` feature 统一污染普通领域 crate 的 host 测试;随后单独执行 `cargo test --locked -p spacetime-module --no-fail-fast`,由 `spacetime-module/src/active.rs` 在 host 测试构建期间提供仅测试期的 SpacetimeDB ABI 链接支持,使该 crate 的纯单元测试也纳入 Backend 门禁。`spacetime-module` 的 reducer / procedure 运行时行为仍必须通过真实 SpacetimeDB runtime/integration harness 验证,host 链接支持不得被当作运行时替身。Backend 另外执行 `cargo check --locked -p spacetime-module` 验证模块源码。AGC 壳检查还会运行 `platform-llm` 与 `shared-contracts` 的 server-rs workspace 测试,这些命令以及 AGC 壳测试必须带 `--locked`,避免在测试阶段重新解析 registry index;锁文件发生变化时应先更新受信任 CI 镜像缓存,再重跑门禁。
@@ -1,5 +1,22 @@
# 踩坑与排障记录
## 2026-09-14 客户端 CI 拆分后,选组运行会跳过未选分组,且必须同步分支保护
- **现象**:把 `Native shell tests` 拆成客户端三个 job 后,如果只跑 `npm run check:native-shells:release`,静态契约和壳运行时门禁都不会执行;如果只跑 `--groups=contract`,`desktop-release-binary-artifact` 又会因为缺少 `build/native/desktop/` 产物而失败。
- **原因**:分组是执行范围,不是"额外检查"。`desktop-release-binary-artifact` 断言依赖同 job 内的 `desktop-shell-stage-release-binary` 步骤,所以它归 `release` 组,不能放进 `contract`;反过来,任何"只跑一组"的命令都不能被当成完整门禁。
- **处理**:分组与 job 的对应关系固定为 `contract`+`shells`+`release` → `Native shell tests`,`agc-web` → `AI game creator shell web tests`,`agc-rust` → `AI game creator shell Rust tests`;`scripts/project-ci-workflow.test.ts` 校验"每个分组恰好被一个 job 调用一次"和"CI 不再调用全量 `npm run check:native-shells`",新增分组必须同步门禁脚本、根脚本与 workflow 三处。
- **易错点**:① 拆 job 后 Gitea `master` 分支保护的 required context 要补齐两个新 AGC context,只改 workflow 不改分支保护会让新门禁在合并前不生效;② 每个 job 只预热自己会构建的 Cargo 依赖,`agent-run:smoke` 因为会 spawn `cargo` 必须留在 `agc-rust` 所在 job;③ 本地全量 `npm run check:native-shells` 仍会串行跑完所有分组,用它作为本地完整门禁,不要用单组脚本冒充。
- **关联**:`.gitea/workflows/project-ci.yml`、`scripts/check-native-shells.mjs`、`scripts/project-ci-workflow.test.ts`、`.gitea` 分支保护设置。
## 2026-09-14 `check:native-shells` 的调用链扫描在 Windows 上恒假
- **现象**:Windows 本机运行 `npm run check:native-shells:contract` 时,`production-shell-dev-scaffold-scan` 报 `H5 HostBridge call chain scan is missing required files: src/ActiveApp.tsx, ...`,而仓库里这些文件都存在,Linux CI 从不报。
- **原因**:`collectFiles` 在 Windows 上返回 `src\ActiveApp.tsx`,调用链扫描把该路径原样放进 `scannedFiles`,再与 POSIX 写法的期望清单(`h5HostBridgeRequiredCallChainFiles` 的 `src/ActiveApp.tsx`)比较,成员判断恒假。注意 `normalizeModulePath` 不能直接复用:它还会去掉 `.ts/.tsx` 后缀。
- **处理**:新增 `normalizeScannedFilePath`(只统一分隔符、保留后缀)用于 `scannedFiles` 的登记;Linux 上 `split('/').join('/')` 是恒等变换,行为不变。
- **验证**:`node scripts/check-native-shells.mjs --groups=contract` 在 Windows 上 0.6 秒通过(修复前同一条命令必红)。
- **同一类限制(未改)**:Windows 本机跑 `shells` / `agc-web` / `agc-rust` / `release` 这些**带步骤**的分组会在第一条 npm 步骤直接失败:`spawnSync npm.cmd EINVAL`(Node 24 起不能不带 shell 直接执行 `.cmd`;而根 `npm run test` 另有 chmod/0600 语义的 Windows 专属失败)。因此 Windows 本机可用的只有 `--groups=contract`,完整门禁交给 Linux CI;不要为此把 `spawnSync` 改成 `shell: true`(步骤参数里含空格与中文字符串,会被 shell 重新解析)。
- **关联**:`scripts/check-native-shells.mjs` 的 `collectH5HostBridgeCallChainFiles` / `normalizeScannedFilePath`。
## 2026-09-14 项目写锁的同进程复用判据不能只看 pid
- **现象**:`master` 的 `Project CI / Native shell tests` 红在 `cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml -- --test-threads=1`,12 条用例失败(`2439 passed; 12 failed`)。断言分三类:① 另一线程持锁时快照读 / `project.diff` / `action_history` / `command.output_read` / steer 不再等待(`... must wait for the project consistency lock`);② 并发写不再串行化——4 路并行直写撞项目 revision 侧车报 `File exists (os error 17)`,8 线程并发 steer 拿到 `[1, 1, 1, 1, 1, 1, 1, 2]`;③ 别的写通道持锁时 `file.write` 与恢复安装必须失败关闭,实测变成 `ok` / 不再报占用。