diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools.rs index a40e23674..7954fea9d 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_tools.rs @@ -34,6 +34,8 @@ pub(in crate::agent) use project_ops::*; pub(in crate::agent) use run_status::*; pub(in crate::agent) use task_ops::*; +#[cfg(test)] +pub(crate) use delegation::observe_agent_runtime_agent_delegate_at_locked; #[cfg(test)] pub(crate) use delivery::{ build_static_delegate_result_for_child_at, wake_waiting_static_delegate_parent_run_for_test_at, diff --git a/apps/ai-game-creator-shell/src-tauri/src/tests/collaboration/delegation.rs b/apps/ai-game-creator-shell/src-tauri/src/tests/collaboration/delegation.rs index 13ce2dca3..7e321f4c9 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/tests/collaboration/delegation.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/tests/collaboration/delegation.rs @@ -2501,12 +2501,18 @@ fn autonomous_direct_child_collaboration_mutations_require_the_current_root() { ); let action_id = "stale-direct-child-delegate"; + // 本文件这四处「先持项目写锁、再调 agent.delegate」的用例走 `_at_locked`,不走同名薄壳。 + // 薄壳在 M1C-2b(`152cc40c7`)里被改成入口自取项目写锁——把锁的所有权上提,是为了让 + // planning 子 session 的投影按 project -> session 的顺序取锁。而 `.agent/project.lock` 是 + // `create_new(true)` 的文件锁、不可重入:调用方已持锁再进薄壳,会死等满 10s 预算然后报 + // 「无法取得一致项目快照」。生产侧两个调用方(`action_execution.rs`、`pending_recovery.rs`) + // 也都是持锁后调 `_at_locked`,薄壳如今已无生产调用方;用 `_at_locked` 钉的才是真实形状。 let project_lock = acquire_game_creator_agent_runtime_project_write_lock_with_wait( &root, "test.stale-direct-child-delegate", ) .expect("acquire delegate project lock"); - let stale_delegate = observe_agent_runtime_agent_delegate( + let stale_delegate = observe_agent_runtime_agent_delegate_at_locked( &root, child_agent_id, &child_run_id, @@ -2516,6 +2522,7 @@ fn autonomous_direct_child_collaboration_mutations_require_the_current_root() { "task": "旧根 child 不得创建委派", "runId": "stale-direct-child-target" }), + &project_lock, ); drop(project_lock); assert_eq!(stale_delegate.status, "failed", "{stale_delegate:?}"); @@ -2574,7 +2581,7 @@ fn autonomous_delegate_descendant_inherits_and_enforces_the_current_root_guard() "test.current-descendant-delegate", ) .expect("acquire current descendant delegate project lock"); - let delegated = observe_agent_runtime_agent_delegate( + let delegated = observe_agent_runtime_agent_delegate_at_locked( &root, ready_agent_id, &ready_run_id, @@ -2584,6 +2591,7 @@ fn autonomous_delegate_descendant_inherits_and_enforces_the_current_root_guard() "task": "在当前自主根下执行只读质量检查", "runId": descendant_run_id }), + &project_lock, ); drop(project_lock); assert_eq!(delegated.status, "ok", "{delegated:?}"); @@ -2667,7 +2675,7 @@ fn autonomous_delegate_descendant_inherits_and_enforces_the_current_root_guard() "test.stale-descendant-delegate", ) .expect("acquire descendant delegate project lock"); - let stale_delegate = observe_agent_runtime_agent_delegate( + let stale_delegate = observe_agent_runtime_agent_delegate_at_locked( &root, descendant_agent_id, descendant_run_id, @@ -2677,6 +2685,7 @@ fn autonomous_delegate_descendant_inherits_and_enforces_the_current_root_guard() "task": "旧根 descendant 不得继续派生", "runId": "stale-descendant-target" }), + &project_lock, ); drop(project_lock); assert_eq!(stale_delegate.status, "failed", "{stale_delegate:?}"); @@ -2728,7 +2737,7 @@ fn standard_delegate_collaboration_mutations_remain_compatible() { "test.standard-delegate", ) .expect("acquire standard delegate project lock"); - let delegated = observe_agent_runtime_agent_delegate( + let delegated = observe_agent_runtime_agent_delegate_at_locked( &root, parent_agent_id, parent_run_id, @@ -2738,6 +2747,7 @@ fn standard_delegate_collaboration_mutations_remain_compatible() { "task": "标准 Run 的兼容委派", "runId": "standard-delegate-child" }), + &project_lock, ); drop(project_lock); assert_eq!(delegated.status, "ok", "{delegated:?}");