修复自主完成合同测试竞态
Project CI / Repository checks (pull_request) Successful in 1m23s
Project CI / Native shell tests (pull_request) Successful in 12m15s
Project CI / Frontend tests (pull_request) Successful in 3m45s
Project CI / Backend tests (pull_request) Successful in 4m12s

隔离 readiness 状态投影,避免测试重复调度 preview-playtest child
补充 Runtime 终态投影测试的竞态避坑说明
This commit is contained in:
2026-08-07 13:46:16 +08:00
parent 6fe52a92bb
commit d04339ad7f
2 changed files with 15 additions and 3 deletions
@@ -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,
@@ -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 的断言。