修复 DirectProject 空历史注入导致新项目第一条消息失败
Project CI / AI game creator shell Rust crates (push) Successful in 1m30s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m49s
Project CI / Backend tests (push) Successful in 4m20s
Project CI / Frontend tests (push) Successful in 2m13s
Project CI / Native shell tests (push) Successful in 6m19s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 9m1s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 9m23s
Project CI / AI game creator shell web tests (push) Successful in 1m41s
Project CI / Repository checks (push) Successful in 2m16s
Project CI / AI game creator shell Rust crates (push) Successful in 1m30s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m49s
Project CI / Backend tests (push) Successful in 4m20s
Project CI / Frontend tests (push) Successful in 2m13s
Project CI / Native shell tests (push) Successful in 6m19s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 9m1s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 9m23s
Project CI / AI game creator shell web tests (push) Successful in 1m41s
Project CI / Repository checks (push) Successful in 2m16s
- build_direct_project_history_injection_params 在历史为空时返回 Ok(None),调用方跳过 thread/inject_items(codex app-server 0.155.1 起拒绝 items: []) - 新增两条单测:空历史不得构造载荷、有历史仍构造 1 条;cargo test direct_project_history_wire 3 passed、cargo fmt --check 通过 - 复验:真 AGC CLI → 真 app-server → loopback Responses 夹具从「4 秒失败、requests=[]」变为「requests=3、markers.ready=true、exit=0」 - 记录第二层未解决问题:同一用例账本仍落 phase=interrupted(app-server 收尾连接终止),两条运行时验收继续未勾选 - decision-log 与 pitfalls 记录缺陷、修复与证据;DirectProject 里程碑补本轮核对
This commit is contained in:
@@ -9711,6 +9711,13 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
|
||||
- 决策(Windows 侧也要能核产物内部身份):新增 `scripts/pe-version-info.mjs`(纯 Node 解析 PE `RT_VERSION`,无第三方依赖),核对脚本下载 Windows 安装包后断言 `ProductName` 与 `FileVersion` 等于本渠道身份与本轮版本。理由与 mac 侧一致:文件名可以改,PE 版本资源是产物自己写的;两侧对称以后「产物里的渠道身份」不再只靠源码级用例。实测 `dev-win` 0.1.155 → `陶泥儿开发版`/`0.1.155`,`release-win` 0.1.150 → `陶泥儿 Release`/`0.1.150`。
|
||||
- 事实(同日稍后):`dev-win` 的 0.1.155(commit `3702e0f8e`)在 14:26:13 发布完成,总号、渠道清单与旧协议指针三者对齐;该构建的源码早于 `assertArtifactVersionMatches()`,所以那条守卫仍待下一次真实渠道构建验证。
|
||||
- 决策(旧协议指针也要线上核对):`agc/latest.json` 是全局单对象,只属于 dev 的 Windows 系统;核对任何非 dev 的 Windows 渠道时,脚本断言它仍指向 `/agc/dev-win/…`。本轮 `release-win` 通过(指针指向 `dev-win/0.1.155` 的安装包),把「release 不能写 dev 桥」这条从单测扩到线上状态。
|
||||
|
||||
## 2026-09-28 DirectProject 空历史不再发 `thread/inject_items`
|
||||
|
||||
- 背景:用 `direct-execution-production-fixture.mjs`(真 AGC CLI → 真 app-server → loopback Responses fixture)跑基线时,全新项目的第一次对话直接失败:`Codex app-server JSON-RPC 失败:items must not be empty`,AGC 进程 4 秒退出、loopback Provider 一次都没被调用。根因是 `thread_created` 时无条件发 `thread/inject_items`,空项目没有 `.agent/conversations/project.jsonl`,载荷成了 `items: []`;codex app-server 0.155.1 起拒绝空数组。GUI 路径因为前端先写用户消息才没暴露,CLI / 无前端宿主没有这一步。
|
||||
- 决策:`build_direct_project_history_injection_params()` 在历史为空时返回 `Ok(None)`,调用方跳过注入(空历史本来就没有可注入内容);有历史时行为不变(仍按原载荷、原大小前置校验)。
|
||||
- 验证:`cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml direct_project_history_wire` → 3 passed(新增「空历史不得构造载荷」「有历史仍构造 1 条」);同一条夹具命令从「4 秒失败、`requests=[]`」变成「`requests=3`、`markers.ready=true`、AGC exit=0」——但账本仍落 `interrupted`(app-server 收尾连接终止,`stderrBytes=1242`),是另一层问题,未在本次一并修。
|
||||
- 影响范围:`apps/ai-game-creator-shell/src-tauri/src/agent/codex_app_server/{direct_project_history_wire.rs,mod.rs}`、`docs/project-memory/shared-memory/pitfalls.md`、DirectProject 里程碑。
|
||||
- 决策(口径回归):macOS 现行契约是 arm64 单架构(2026-09-21 决策),里程碑里「两个 macOS 平台键指向 universal 产物」的旧文字按现行决策改写;不得据此重新切回 universal,除非按该决策给出的恢复路径补齐按架构的 Node 运行时。
|
||||
- 影响范围:`apps/ai-game-creator-shell/scripts/build-macos-ci.mjs`、新增 `apps/ai-game-creator-shell/scripts/macos-release-identity.mjs` 与其 `.test.mjs`、`apps/ai-game-creator-shell/scripts/prepare-macos-codex.test.mjs`、`jenkins/Jenkinsfile.ai-game-creator-shell-macos-build`、`scripts/check-agc-update-channel-manifests.mjs`、两份里程碑与本文件、pitfalls。
|
||||
- 验证:`node --test apps/ai-game-creator-shell/scripts/*.test.mjs` → **110 passed / 0 failed**(其中定向批次 `macos-release-identity / prepare-macos-codex / verify-updater-signature / build-release / cargo-features` 60 passed;新增的 mac 身份回归用例直接喂线上那份 0.1.139 release 身份 plist,必须抛错;新增的产物版本守卫用例喂 `_0.1.153_` 残留安装包,必须抛错);`npm run check:production-ops`、`check:encoding`、`check:doc-index`、prettier、eslint、`git diff --check` 通过;只读核对对线上 `dev-win` 全 PASS(含 158 MiB 产物下载验签与旧协议 sha256 一致),对线上 `dev-mac` 精确报出上面两条 FAIL。
|
||||
|
||||
@@ -6106,3 +6106,11 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/`
|
||||
- **判据**:只读核对要**打开产物看身份**,不能只看「地址存在 + 签名匹配」。`npm run check:agc-update-channel-manifests`(`AGC_UPDATE_VERIFY_DOWNLOAD=1`)现在会解出 mac 包的 `Info.plist`、以及 Windows 安装包的 PE `RT_VERSION`(`scripts/pe-version-info.mjs`),断言「产物内版本 == 清单版本」且「产物内产品名/identifier == 本渠道身份」,并额外断言**不同渠道的更新包不得字节相同**;本轮对线上取样得到三条 FAIL,正是这个缺陷。字节级佐证:`dev-mac/0.1.142/陶泥儿 Release.app.tar.gz` 与 `release-mac/0.1.139/陶泥儿 Release.app.tar.gz` 的 sha256 完全相同(`1dfc9deb79f7…`),说明 dev 分区里放的就是 release 那一次构建的产物。
|
||||
- **处理(2026-09-28 已修)**:构建前按后缀清空 `macos/` 下的 `*.app.tar.gz`、`*.app.tar.gz.sig`、`*.dmg`、`*.dmg.sha256`;构建后读 `.app/Contents/Info.plist` 断言版本/identifier/产品名;生成清单后再断言 `release.artifact` 就是本轮那一个。守卫在 `apps/ai-game-creator-shell/scripts/macos-release-identity.mjs`,回归用例直接用线上那份 0.1.139 release 身份包(`node --test` 59 passed)。
|
||||
- **教训**:凡是「按目录扫描挑产物」的发布步骤,都要么先清空同类产物、要么按本轮预期路径断言;只删「本轮要写的名字」等于把上一轮的坏包留在候选集里。现在共享入口 `generateUpdateManifest()` 也补了与平台无关的 `assertArtifactVersionMatches()`(文件名带 `_0.1.153_` 这类版本段时必须是本轮版本),所以即使将来某个流水线不再 `git clean -fdx`,旧安装包也会被拒绝而不是被发出去。还有一条更一般的:核对线上清单时,先看 decision-log 的现行口径(这里 macOS 已是 arm64 单架构),别拿过期里程碑文字当契约。
|
||||
|
||||
## 2026-09-28 DirectProject 空历史注入被新版 app-server 拒绝:新项目第一条消息直接「执行通道中断」
|
||||
|
||||
- **现象**:用 `apps/ai-game-creator-shell/scripts/direct-execution-production-fixture.mjs`(真 AGC CLI → 真 app-server → loopback Responses fixture,无账号/无付费 Provider)跑 `--cases completed` 时,AGC 进程 4 秒就退出、`requests=[]`,stderr 只有 `Codex app-server JSON-RPC 失败:items must not be empty` + `agent.runner.failed`,夹具因此报「AGC did not reach the loopback fixture」。
|
||||
- **根因**:`codex_app_server/mod.rs` 在 `thread_created` 时无条件调用 `thread/inject_items`,载荷由 `build_direct_project_history_injection_params()` 从 `.agent/conversations/project.jsonl` 构造;**全新项目该文件不存在 → `items: []`**,而 codex app-server 0.155.1 起把空数组当协议错误拒绝。GUI 路径之所以没暴露:前端会先调 `append_direct_project_conversation_message` 把用户消息写进历史,注入时至少有 1 条;`--direct-codex-chat` 这类无前端宿主(以及任何直接调用 `run_direct_game_creator_turn_at` 的夹具/CLI)没有这一步。
|
||||
- **处理(2026-09-28 已修)**:`build_direct_project_history_injection_params()` 在历史为空时返回 `Ok(None)`,调用方跳过 `thread/inject_items`;新增两条单测(空历史不得构造载荷、有历史仍构造 1 条)。
|
||||
- **复验**:同一条夹具命令下,AGC 进程从「4 秒失败、`requests=[]`」变成「走到 loopback Provider、`requests=3`、`markers.ready=true`、exit=0」——第一层缺陷确实修掉了。
|
||||
- **仍未解决(第二层,另一个问题)**:同一个夹具的 `completed` 用例仍断言失败,原因是执行账本 `phase=interrupted`(期望 `completed`),stderr 为 `agent.runner.failed: Codex app-server 连接终止 … exitStatus=unknown;stderrBytes=1242`,CLI 回执文本也是「执行通道已断开,不能自动重放未确认操作」。看起来是 CLI 收尾阶段的关闭竞态(账本被记成宿主终止),与空历史注入不是同一件事;要动它需要先抓 app-server 的 stderr 内容(应用目前只记字节数与摘要,不落原文)。
|
||||
|
||||
Reference in New Issue
Block a user