From d04339ad7f821b4279a5fc5530af1081d11303db Mon Sep 17 00:00:00 2001 From: menghao Date: Fri, 7 Aug 2026 13:46:16 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=87=AA=E4=B8=BB=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E5=90=88=E5=90=8C=E6=B5=8B=E8=AF=95=E7=AB=9E=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 隔离 readiness 状态投影,避免测试重复调度 preview-playtest child 补充 Runtime 终态投影测试的竞态避坑说明 --- .../autonomous_completion_contract_tests.rs | 11 ++++++++--- docs/project-memory/shared-memory/pitfalls.md | 7 +++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/autonomous_completion_contract_tests.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/autonomous_completion_contract_tests.rs index 21ac01088..cd27fd58e 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/autonomous_completion_contract_tests.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/autonomous_completion_contract_tests.rs @@ -5418,11 +5418,16 @@ fn preview_playtest_terminal_registers_a_runnable_snapshot_before_downstream_pub }; append_game_creator_agent_runtime_task_record(&root, &readiness_terminal) .expect("persist completed preview readiness record"); - project_autonomous_manifest_ready_task_terminal_at( + // This test isolates runnable-version registration. Calling the production + // terminal projector here would asynchronously schedule preview-playtest; + // the explicit child fixture below could then race it and create a second + // logical run with a generated `-dup-*` run id. + update_manifest_task_status_at( &root, - &agent_runtime_state_from_task_record(&readiness_terminal), + "preview-readiness", + GameCreationAppTaskStatus::Completed, ) - .expect("project preview readiness completion"); + .expect("project preview readiness completion without scheduling the next wave"); update_manifest_task_status_at( &root, diff --git a/docs/project-memory/shared-memory/pitfalls.md b/docs/project-memory/shared-memory/pitfalls.md index e5a118125..d4dd1615e 100644 --- a/docs/project-memory/shared-memory/pitfalls.md +++ b/docs/project-memory/shared-memory/pitfalls.md @@ -4393,3 +4393,10 @@ - 原因:冲突两侧代表不同组件架构,逐行保留看似有用的 JSX 会把一个架构中的局部条件拼进另一个架构。import 排序、格式检查和只覆盖单一 mode 的测试都不能证明这种组合成立。 - 处理:先确定权威组件边界,再按完整调用链解决冲突。图片画布音频入口当前决策是恢复一个共享 `ImageCanvasAudioGenerationComposerView`,由组件内 `isSoundEffect` 分流;BGM/SFX 的 validator、写回、锁和提交契约仍分别保持。不要只补一个常量后继续维持已经废弃的双 composer 边界。 - 验证:同时渲染 `audio-sound-effect` 与 `audio-background-music`,覆盖两个 mode 的正向控件和互斥负向断言、dialog / mode 切换、BGM 稳定 ID 与 controller 缺失的失败关闭,并运行 `ImageCanvasGenerationComposerView.test.tsx` 与 typecheck。 + +## Runtime 终态投影测试不能再手工入队下一波 child(2026-08-07) + +- 现象:自主完成合同测试单独运行通过,在完整 native shell CI 中却偶发报“autonomous ready-task child journal 存在重复逻辑 Run”,重复项带有通用入队生成的 `-dup-*` runId。 +- 原因:`project_autonomous_manifest_ready_task_terminal_at` 在非 game-chat child 完成后会异步调度下一波;测试调用真实终态投影后,又用非幂等夹具手工入队同一个下一波任务。异步调度先落盘时,通用唯一 runId 逻辑会把手工夹具改成第二个逻辑 Run,正式 exactly-once 门禁随后按设计失败关闭。单测隔离执行时异步任务未必在断言前取得调度机会,因此容易掩盖竞态。 +- 处理:测试若关注终态投影与下一波调度,必须读取并复用生产 scheduler 创建的确定性 child;若只关注下游完成合同,应持久化所需的真实 terminal journal、验证凭证与 manifest 状态,但不要调用会启动异步下一波的终态投影后再手工入队。不得通过放宽生产侧重复逻辑 Run 门禁修复测试竞态。 +- 验证:先定向运行失败用例,再重复运行相关自主完成合同切片和完整 `npm run check:native-shells`;保留同一父 Run、taskId 与 scheduler source 下最多一个 logical child 的断言。