diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions.rs index a8d5d0854..46a909b82 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions.rs @@ -140,8 +140,7 @@ pub(crate) use structured_plan::{ retry_agent_runtime_active_plan_step, sanitize_agent_runtime_plan_update, AgentRuntimePlanUpdateOutcome, }; -// 不带 agentId 的三个解析入口走 `"__all_agents__"` 哨兵、跳过按身份的工具面 -// 复核,只对测试开放;生产代码必须用 `_for_agent`。 +// 测试入口沿用正式解析规则,只将协议错误转成断言使用的字符串。 #[cfg(test)] pub(crate) use tool_plan_protocol::parse_game_creator_agent_tool_plan_llm_response; #[cfg(test)] diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/provider_request_builders.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/provider_request_builders.rs index 1c74612fa..3647d5979 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/provider_request_builders.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/provider_request_builders.rs @@ -176,9 +176,10 @@ pub(in crate::agent) fn remove_relaxed_autonomous_platform_validation_tools( Ok(()) } -fn build_game_creator_agent_background_tool_plan_request_at( +// 调用方在构建请求及前后读取 manifest 期间持有项目锁;保留借用作为入口约束。 +pub(in crate::agent) fn build_game_creator_agent_background_tool_plan_request_locked( root: &Path, - project_lock: Option<&ProjectWriteLock>, + _project_lock: &ProjectWriteLock, agent_id: &str, session_id: &str, run_id: &str, @@ -252,9 +253,7 @@ fn build_game_creator_agent_background_tool_plan_request_at( observations_json = observations_json, ); let mut function_tools = - crate::agent_native_tools::build_agent_runtime_native_function_tools_for_project( - root, agent_id, - )?; + crate::agent_native_tools::build_agent_runtime_native_function_tools_for_project(root)?; remove_relaxed_autonomous_platform_validation_tools(&mut function_tools)?; // Platform-backed generation remains an optional capability. A // relaxed run may proceed with all ordinary project tools when no @@ -492,9 +491,7 @@ fn build_game_creator_agent_background_tool_plan_request_at( .with_max_output_tokens(AGENT_RUNTIME_TOOL_PLAN_MAX_OUTPUT_TOKENS) .with_response_text_verbosity(platform_llm::LlmResponseTextVerbosity::Low) .with_function_tools( - crate::agent_native_tools::build_agent_runtime_native_function_tools_for_project( - root, agent_id, - )?, + crate::agent_native_tools::build_agent_runtime_native_function_tools_for_project(root)?, ) .with_tool_choice(platform_llm::LlmToolChoice::Required); if runtime_owner_artifact_validation_available { @@ -614,37 +611,6 @@ fn build_game_creator_agent_background_tool_plan_request_at( )) } -pub(in crate::agent) fn build_game_creator_agent_background_tool_plan_request_locked( - root: &Path, - project_lock: &ProjectWriteLock, - agent_id: &str, - session_id: &str, - run_id: &str, - task: &str, - observations: &[AgentRuntimeToolObservation], - loop_index: usize, -) -> Result< - ( - GameCreatorLlmConfig, - String, - LlmRunRequest, - String, - AgentRuntimeToolPlanRequestSnapshot, - ), - String, -> { - build_game_creator_agent_background_tool_plan_request_at( - root, - Some(project_lock), - agent_id, - session_id, - run_id, - task, - observations, - loop_index, - ) -} - pub(in crate::agent) fn build_game_creator_agent_background_final_reply_request( root: &Path, agent_id: &str, diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/provider_tool_plan.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/provider_tool_plan.rs index 7d158612d..c883b864c 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/provider_tool_plan.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/provider_tool_plan.rs @@ -479,10 +479,7 @@ pub(in crate::agent) async fn request_game_creator_agent_background_tool_plan_at Sha256::digest(response_handoff.provider_request_id.as_bytes()) ); let mut supervisor_collaboration_candidate_actions = None; - let parsed = parse_game_creator_agent_tool_plan_llm_response_classified_for_agent( - agent_id, - &response, - ) + let parsed = parse_game_creator_agent_tool_plan_llm_response_classified(&response) .map(|mut parsed| { let merged = merge_supervisor_collaboration_repair_actions( if supervisor_collaboration_repair_active { @@ -972,7 +969,7 @@ pub(in crate::agent) async fn request_game_creator_agent_background_tool_plan_at || force_autonomous_pre_mutation { request.function_tools = - crate::agent_native_tools::build_agent_runtime_native_function_tools_for_project(root, agent_id)?; + crate::agent_native_tools::build_agent_runtime_native_function_tools_for_project(root)?; if runtime_owner_artifact_validation_available { remove_autonomous_owner_manual_verification_tools( &mut request.function_tools, diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/tool_plan_protocol.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/tool_plan_protocol.rs index 8a79d3feb..5b3bd1d5f 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/tool_plan_protocol.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_actions/tool_plan_protocol.rs @@ -13,7 +13,7 @@ pub(crate) fn parse_game_creator_agent_tool_plan_response_classified( parse_game_creator_agent_tool_plan_payload(payload, false) } -/// 只允许测试使用(沿用下方 `_classified` 的哨兵约束)。 +/// 只允许测试使用。 #[cfg(test)] pub(crate) fn parse_game_creator_agent_tool_plan_llm_response( response: &platform_llm::LlmRunResponse, @@ -22,21 +22,8 @@ pub(crate) fn parse_game_creator_agent_tool_plan_llm_response( .map_err(|error| error.to_string()) } -/// 不带身份的解析入口,**只允许测试使用**。 -/// -/// `"__all_agents__"` 哨兵会跳过按身份的工具面复核;生产代码必须走 -/// `_for_agent` 并传真实 `agentId`。`#[cfg(test)]` 让漏改在编译期就失败, -/// 而不是在运行时静默放行本该被收窄的调用。 -#[cfg(test)] pub(crate) fn parse_game_creator_agent_tool_plan_llm_response_classified( response: &platform_llm::LlmRunResponse, -) -> Result { - parse_game_creator_agent_tool_plan_llm_response_classified_for_agent("__all_agents__", response) -} - -pub(crate) fn parse_game_creator_agent_tool_plan_llm_response_classified_for_agent( - agent_id: &str, - response: &platform_llm::LlmRunResponse, ) -> Result { if response.tool_calls.is_empty() { let plan = parse_game_creator_agent_tool_plan_response_classified(response.text.as_str())?; diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver.rs index 9fe5f6889..54da51648 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver.rs @@ -390,8 +390,6 @@ pub(super) const AGENT_RUNTIME_FINALIZATION_STATUS_ASSISTANT_PERSISTED: &str = pub(super) const AGENT_RUNTIME_FINALIZATION_STATUS_RUNTIME_COMPLETED: &str = "runtime-completed"; pub(super) const AGENT_RUNTIME_PROVIDER_REQUEST_LIFECYCLE_SCHEMA_VERSION: &str = "game-creator-provider-request-lifecycle.v2"; -pub(super) const AGENT_RUNTIME_PLAN_PROVIDER_REQUEST_LIFECYCLE_SCHEMA_VERSION: &str = - "game-creator-provider-request-lifecycle.v3"; pub(super) const AGENT_RUNTIME_PROVIDER_REQUEST_LIFECYCLE_RECORD_TYPE: &str = "agent.runtime.provider_request.lifecycle"; pub(super) const AGENT_RUNTIME_PROVIDER_REQUEST_RECONCILIATION_PREFIX: &str = diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/finalization.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/finalization.rs index 19f919b5d..22614b5e5 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/finalization.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/finalization.rs @@ -3,11 +3,6 @@ use super::*; pub(crate) enum AgentRuntimePendingActionResume { NotFound(AgentRuntimeTaskLock), Handled(AgentRuntimeResult), - /// 本轮无法在不破坏锁序的前提下推进:为了按 project -> execution 顺序取锁, - /// 执行锁已经被放掉,重取时又被别处占住。返回时不带锁——两把锁都已释放。 - /// 这不是失败:锁被占恰恰说明别处正在推进,调用方应跳过该 Agent 等下一轮, - /// 而不是把整轮恢复判失败。 - Deferred, } pub(in crate::agent) enum AgentRuntimeFinalizationResume { diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/pending_recovery.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/pending_recovery.rs index a46ddef59..d9b7bdac5 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/pending_recovery.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/pending_recovery.rs @@ -1302,7 +1302,6 @@ pub(crate) fn resume_game_creator_agent_provider_action_batch_for_test_at( match resume_game_creator_agent_provider_action_batch_at(root, agent_id, runtime_lock)? { AgentRuntimePendingActionResume::Handled(_) => Ok("handled"), AgentRuntimePendingActionResume::NotFound(_) => Ok("not-found"), - AgentRuntimePendingActionResume::Deferred => Ok("deferred"), } } diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/recovery_scan.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/recovery_scan.rs index 370c90dda..cc9152047 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/recovery_scan.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/recovery_scan.rs @@ -1089,7 +1089,6 @@ pub(in crate::agent) fn resume_game_creator_agent_background_tasks_unredacted_at continue; } AgentRuntimePendingActionResume::NotFound(runtime_lock) => runtime_lock, - AgentRuntimePendingActionResume::Deferred => continue, }; let runtime_lock = match resume_game_creator_agent_pending_tool_action_at( root, @@ -1102,7 +1101,6 @@ pub(in crate::agent) fn resume_game_creator_agent_background_tasks_unredacted_at } AgentRuntimePendingActionResume::NotFound(runtime_lock) => runtime_lock, // 锁序重排窗口里没抢到锁。跳过该 Agent,本轮其余 Agent 照常恢复。 - AgentRuntimePendingActionResume::Deferred => continue, }; match resume_game_creator_agent_provider_action_batch_at(root, &agent_id, runtime_lock)? { @@ -1111,7 +1109,6 @@ pub(in crate::agent) fn resume_game_creator_agent_background_tasks_unredacted_at continue; } AgentRuntimePendingActionResume::NotFound(runtime_lock) => runtime_lock, - AgentRuntimePendingActionResume::Deferred => continue, } }; let Some(task) = @@ -1536,11 +1533,6 @@ pub(crate) fn resume_game_creator_agent_pending_action_for_agent_at( AgentRuntimePendingActionResume::NotFound(_runtime_lock) => { Err("Agent Runner 未找到可继续的精确待处理动作".to_string()) } - // 这条入口是「继续这一个动作」的定向请求,不是批量扫描:没抢到锁只能如实 - // 报错。文案沿用执行锁自己的措辞,让上游的 transient 判据仍能认出它。 - AgentRuntimePendingActionResume::Deferred => Err(format!( - "Agent Runtime 正在执行该 Agent 的其他任务:{agent_id}" - )), } } diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/task_start.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/task_start.rs index 465b2b328..2b6b56999 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/task_start.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver/task_start.rs @@ -169,17 +169,32 @@ pub(in crate::agent) fn start_game_creator_agent_background_task_with_link_at( run_profile: Option<&str>, task_link: Option<&AgentRuntimeTaskLink>, ) -> Result<(AgentRuntimeResult, String), String> { - start_game_creator_agent_background_task_with_link_with_project_lock_at( + let agent_id = normalize_game_creator_runtime_agent_id(agent_id)?; + validate_project_root(root)?; + let result = with_agent_conversation_session_lane_at( root, - agent_id, - session_id, - task, - run_id, - source, - run_profile, - task_link, - None, - ) + &agent_id, + "Agent Session Runtime 入队", + || { + start_game_creator_agent_background_task_with_link_in_session_lane_at( + root, + &agent_id, + session_id, + task, + run_id, + source, + run_profile, + task_link, + ) + }, + )?; + notify_external_agent_runner_after_background_task_enqueue( + root, + &agent_id, + &result.0.state.session_id, + &result.1, + )?; + Ok(result) } pub(in crate::agent) fn start_game_creator_agent_background_task_with_link_locked_at( @@ -196,7 +211,7 @@ pub(in crate::agent) fn start_game_creator_agent_background_task_with_link_locke if !project_write_lock.guards_project_root(root)? { return Err("Agent 后台任务入队缺少当前项目写锁".to_string()); } - start_game_creator_agent_background_task_with_link_with_project_lock_at( + start_game_creator_agent_background_task_with_link_at( root, agent_id, session_id, @@ -205,51 +220,9 @@ pub(in crate::agent) fn start_game_creator_agent_background_task_with_link_locke source, run_profile, task_link, - Some(project_write_lock), ) } -#[allow(clippy::too_many_arguments)] -fn start_game_creator_agent_background_task_with_link_with_project_lock_at( - root: &Path, - agent_id: &str, - session_id: Option<&str>, - task: &str, - run_id: &str, - source: &str, - run_profile: Option<&str>, - task_link: Option<&AgentRuntimeTaskLink>, - project_write_lock: Option<&ProjectWriteLock>, -) -> Result<(AgentRuntimeResult, String), String> { - let agent_id = normalize_game_creator_runtime_agent_id(agent_id)?; - validate_project_root(root)?; - let result = with_agent_conversation_session_lane_at( - root, - &agent_id, - "Agent Session Runtime 入队", - || { - start_game_creator_agent_background_task_with_link_in_session_lane_with_project_lock_at( - root, - &agent_id, - session_id, - task, - run_id, - source, - run_profile, - task_link, - project_write_lock, - ) - }, - )?; - notify_external_agent_runner_after_background_task_enqueue( - root, - &agent_id, - &result.0.state.session_id, - &result.1, - )?; - Ok(result) -} - pub(crate) fn notify_external_agent_runner_after_background_task_enqueue( root: &Path, agent_id: &str, @@ -292,6 +265,7 @@ pub(crate) fn notify_external_agent_runner_after_background_task_enqueue( Ok(()) } +#[allow(clippy::too_many_arguments)] pub(in crate::agent) fn start_game_creator_agent_background_task_with_link_in_session_lane_at( root: &Path, agent_id: &str, @@ -301,31 +275,6 @@ pub(in crate::agent) fn start_game_creator_agent_background_task_with_link_in_se source: &str, run_profile: Option<&str>, task_link: Option<&AgentRuntimeTaskLink>, -) -> Result<(AgentRuntimeResult, String), String> { - start_game_creator_agent_background_task_with_link_in_session_lane_with_project_lock_at( - root, - agent_id, - session_id, - task, - run_id, - source, - run_profile, - task_link, - None, - ) -} - -#[allow(clippy::too_many_arguments)] -fn start_game_creator_agent_background_task_with_link_in_session_lane_with_project_lock_at( - root: &Path, - agent_id: &str, - session_id: Option<&str>, - task: &str, - run_id: &str, - source: &str, - run_profile: Option<&str>, - task_link: Option<&AgentRuntimeTaskLink>, - project_write_lock: Option<&ProjectWriteLock>, ) -> Result<(AgentRuntimeResult, String), String> { let isolated_instance = agent_id .starts_with("child-") diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent_native_tools.rs b/apps/ai-game-creator-shell/src-tauri/src/agent_native_tools.rs index 421d5af05..799c26b83 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent_native_tools.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent_native_tools.rs @@ -267,21 +267,8 @@ fn agent_runtime_native_capability_registry() -> Result<&'static CapabilityRegis .map_err(Clone::clone) } -/// 不带身份的全量目录,**只允许测试使用**。 -/// -/// `"__all_agents__"` 是个不对应任何真实 Agent 的哨兵:走这条路径拿到的是 -/// 未按身份收窄的完整函数目录。生产代码必须调用 `_for_agent` 版本并传入真实 -/// `agentId`,否则按身份收窄的工具面会被静默绕开。这里用 `#[cfg(test)]` 把「忘记改用 `_for_agent`」 -/// 从运行时静默扩权变成编译期错误。 -#[cfg(test)] +/// 从当前 capability registry 构建原生函数目录。 pub(crate) fn build_agent_runtime_native_function_tools() -> Result, String> { - build_agent_runtime_native_function_tools_for_agent("__all_agents__") -} - -/// Build the function catalog for a specific Agent identity. -pub(crate) fn build_agent_runtime_native_function_tools_for_agent( - agent_id: &str, -) -> Result, String> { let mut functions = vec![plan_update_function_tool(), response_function_tool()]; let mut names = BTreeSet::from([ AGENT_RUNTIME_UPDATE_PLAN_FUNCTION_NAME.to_string(), @@ -320,9 +307,8 @@ pub(crate) fn build_agent_runtime_native_function_tools_for_agent( pub(crate) fn build_agent_runtime_native_function_tools_for_project( root: &std::path::Path, - agent_id: &str, ) -> Result, String> { - let mut tools = build_agent_runtime_native_function_tools_for_agent(agent_id)?; + let mut tools = build_agent_runtime_native_function_tools()?; if !crate::builtin_plugins::godot_editor_agent_tool_available_for_project(root) { let name = native_runtime_function_name_for_tool("godot.editor.execute"); tools.retain(|tool| tool.name != name); @@ -1915,22 +1901,18 @@ mod tests { ); let name = native_runtime_function_name_for_tool("godot.editor.execute"); assert_eq!( - build_agent_runtime_native_function_tools_for_project( - project.path(), - "__all_agents__" - ) - .unwrap() - .iter() - .any(|tool| tool.name == name), + build_agent_runtime_native_function_tools_for_project(project.path()) + .unwrap() + .iter() + .any(|tool| tool.name == name), expected ); - assert!(!build_agent_runtime_native_function_tools_for_project( - other_project.path(), - "__all_agents__" - ) - .unwrap() - .iter() - .any(|tool| tool.name == name)); + assert!( + !build_agent_runtime_native_function_tools_for_project(other_project.path()) + .unwrap() + .iter() + .any(|tool| tool.name == name) + ); } } diff --git a/docs/project-memory/plans/【实施计划】退役策划Agent V1V2解耦清理-2026-09-15.md b/docs/project-memory/plans/【实施计划】退役策划Agent V1V2解耦清理-2026-09-15.md deleted file mode 100644 index 6b6b92655..000000000 --- a/docs/project-memory/plans/【实施计划】退役策划Agent V1V2解耦清理-2026-09-15.md +++ /dev/null @@ -1,92 +0,0 @@ -# 【实施计划】退役策划 Agent V1/V2 解耦清理 - -| 字段 | 值 | -| --- | --- | -| Milestone | `docs/project-memory/plans/【里程碑】退役策划Agent V1V2解耦清理-2026-09-15.md` | -| Status | ready | -| Owner | Codex | - -## 一句话交付结果 - -删除退役策划 V1/V2 及其耦合的 Supervisor 产品残留,让当前 Design Agent 独立运行、做游戏走 DirectCodex 并恢复仓库编译;保留通用 Supervisor 和做游戏 16 Agent DAG。 - -## 验收判据 - -当前分支能够通过 AGC 前端 typecheck 和受影响定向测试;Design Agent 的新建、恢复、澄清、阶段审批和 reasoning 展示仍由当前 Design Agent 链路完成;旧 V2 IPC、旧 GDD 类型和旧前端测试契约不再存在。 - -## 修改边界 - -允许修改: - -- `apps/ai-game-creator-shell/src/App.tsx` 中旧 V2 状态、helper、IPC 分支和旧 UI props。 -- `apps/ai-game-creator-shell/src/app/types.ts` 中旧 GDD 类型。 -- `apps/ai-game-creator-shell/src/features/project-workspace/planningSessionV2.ts` 及其直接调用方。 -- `apps/ai-game-creator-shell/tests/appSurface/harness.ts`、`home.suite.ts`、旧策划事件测试。 -- `apps/ai-game-creator-shell/src/styles.css` 中只属于旧 Plan GDD / planning lane 的样式。 -- 没有现役调用方的旧策划身份 fixture、注释和文档索引。 -- 为通过编译所需的最小共享残留删除或改名。 - -明确不修改: - -- `directCodex` 主链路和当前 Design Agent。 -- 16 Agent DAG、`supervisor-swarm` 测试和通用 Runtime 编排;只处理删除策划耦合后直接造成的编译错误。 -- 当前 Design Agent Rust runtime、Design Agent 资源包和 Design Agent IPC 协议。 -- 公开 API、SpacetimeDB schema、迁移和历史持久化数据格式。 - -## 实现顺序与提交拆分 - -### 提交一:解耦 Design Agent 状态命名 - -- 将新版 Design Agent 实际使用的 `planningV2*` transient reply、reasoning、active ref 和相关 lane 控制改成 Design Agent 专属状态。 -- 保持行为不变,不删除旧 V2 会话代码。 -- 验证:AGC typecheck、`git diff --check`。 - -### 提交二:删除 App 旧 V2 会话控制流 - -- 删除仅服务旧策划的 Supervisor 产品入口、恢复、轮询和聊天提交分支。 -- 删除旧 V2 session/GDD 状态和 helper。 -- 删除项目打开、消息发送、问询回答、审批和旧流式事件分支。 -- 将“做方案”只连接到当前 Design Agent hydrate/continue/decide 路径,将“做游戏/做素材”只连接到 DirectCodex。 -- 保留 `planningStartMode` 作为入口路由字段,避免无关扩大重命名。 -- 验证:AGC typecheck;必要时运行 App 启动相关定向 suite。 - -### 提交三:删除旧 TypeScript 适配层和类型 - -- 删除 `planningSessionV2.ts`。 -- 删除 `PlanGddDecisionAction`、`PlanGddStateViewV1` 及所有直接导入。 -- 重新执行旧符号检索,确认没有残留调用方。 -- 验证:AGC typecheck、`npm run check:encoding`、`git diff --check`。 - -### 提交四:清理测试、事件契约和 CSS - -- 精确删除 harness 中旧 V2/GDD 工厂、mock、调用记录和导出。 -- 精确删除首页 suite 中旧 V2 IPC 断言。 -- 删除旧 `planning-session-v2-stream` 事件测试。 -- 删除 Plan GDD、GDD 审批卡和 planning lane 专属 CSS 及过时说明。 -- 验证:appSurface 定向测试、事件订阅定向测试、AGC typecheck、编码和 diff 检查。 - -### 提交五:收口确定失效的身份残留和文档入口 - -- 只处理因 V1/V2 退役而确定失效的旧身份展示、测试 fixture、注释和文档索引。 -- 不扫描或重构做游戏 DAG;共享代码只在其旧策划用途已确定死且删除能直接解决编译/测试问题时处理。 -- 验证:旧策划符号定向检索、相关测试、编码和 diff 检查。 - -## 验证命令 - -1. `npm --prefix apps/ai-game-creator-shell run typecheck` -2. `npm run check:encoding` -3. `git diff --check` -4. `npm --prefix apps/ai-game-creator-shell exec vitest run tests/appSurface.test.ts` -5. 受影响 Rust 文件变化后运行 `cargo check --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml` -6. 完成全部提交后再次执行旧策划符号检索,并核对 `git status` 与提交边界 - -## 风险与回滚点 - -- 最大风险是新版 Design Agent 复用了旧变量名;必须先完成提交一,再删除旧 helper。 -- `ProjectSupervisorView` 已经移除旧 GDD props,App 传参残留会在提交二中一并删除。 -- 测试 harness 同时服务通用总控和 Design Agent,必须局部删除旧 mock,不能整段重写。 -- 若某次提交导致 Design Agent 测试失败,只回滚该独立提交,不恢复旧 V2 兼容层。 - -## 完成后的临时文档处理 - -全部里程碑验收通过后,删除本里程碑和实施计划两份临时文档;把仍然有效的长期边界同步回现行 Design Agent 技术方案和项目记忆,不保留阶段性提交步骤。 diff --git a/docs/project-memory/plans/【实施计划】退役策划V2 Rust Runtime清理-2026-09-14.md b/docs/project-memory/plans/【实施计划】退役策划V2 Rust Runtime清理-2026-09-14.md deleted file mode 100644 index ebe9f1d74..000000000 --- a/docs/project-memory/plans/【实施计划】退役策划V2 Rust Runtime清理-2026-09-14.md +++ /dev/null @@ -1,21 +0,0 @@ -# 关联里程碑 - -`【里程碑】退役策划V2 Rust Runtime清理-2026-09-14.md` - -# 修改顺序 - -1. 从 `runtime_protocol.rs` 移除 V2 模块声明与导出。 -2. 从 `main.rs` / `commands.rs` 移除 V2 command 注册和仅供 V2 的导入。 -3. 删除 V2 Rust 模块及其专属单元测试;保留共享 GDD 模型或新版设计会话仍使用的类型。 -4. 用 `rg` 检查 V2 Rust 符号残留,修复编译引用。 - -# 验证命令 - -- `cargo check --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml` -- `npm run check:encoding` -- `git diff --check` - -# 风险与回滚 - -- 风险:V2 类型可能被共享测试或前端桥接代码引用。处理方式是按编译错误逐项判断,保留真正共享类型。 -- 回滚:按提交粒度回退本里程碑提交,不触碰前序 V1 清理提交。 diff --git a/docs/project-memory/plans/【里程碑】退役策划Agent V1V2解耦清理-2026-09-15.md b/docs/project-memory/plans/【里程碑】退役策划Agent V1V2解耦清理-2026-09-15.md deleted file mode 100644 index ccc9a2dd9..000000000 --- a/docs/project-memory/plans/【里程碑】退役策划Agent V1V2解耦清理-2026-09-15.md +++ /dev/null @@ -1,49 +0,0 @@ -# 【里程碑】退役策划 Agent V1/V2 解耦清理 - -| 字段 | 值 | -| --- | --- | -| Version | 1.0 | -| Status | proposed | -| Date | 2026-09-15 | -| Parent Spec | `docs/technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md` | - -## 目标 - -移除旧版策划 Agent V1、V2 的前端会话、审批、数据适配、测试契约和确定失效的展示残留;仅在删除策划链路时遇到已退役 Supervisor 功能耦合时一并删除该耦合,使“做方案”只使用当前 Design Agent、做游戏只使用 DirectCodex。 - -## 范围 - -- 解除当前 Design Agent 与旧 `planningV2` / `PlanGdd` 状态命名和控制流的耦合。 -- 删除仅服务旧策划的 Supervisor 产品入口、会话恢复、Runtime 轮询和聊天提交分支;保留通用 Supervisor 与做游戏 DAG。 -- 删除旧 V2 会话 hydrate、start、continue、审批和用户问询分支。 -- 删除旧 V2 TypeScript 会话适配层、旧 GDD 前端类型、测试 mock、旧事件契约和专属样式。 -- 清理确定没有现役调用方的旧策划身份说明、测试 fixture 和文档当前入口。 -- 保留当前 Design Agent 的会话、澄清、阶段审批、工作区浏览和 reasoning 展示行为。 - -## 不在范围内 - -- 不主动扫描、重构或整体删除做游戏 Agent 的 16 Agent DAG;只有策划删除直接造成编译或测试失败时才做最小修复。 -- 不删除 DirectCodex 或当前 Design Agent;必要时保留被两者复用的中性聊天表现组件。 -- 不为旧项目新增兼容层、迁移器、墓碑注释或退役行为测试。 -- 不修改 SpacetimeDB schema、公开 API、持久化迁移和现役 Design Agent 协议。 - -## 依赖与前置条件 - -- PR #159 的合并提交 `3d8e0211` 代表旧 Fast GDD / 策划 V1 的引入。 -- PR #305 的合并提交 `04128eb6` 同时包含 V1 大范围退役、策划 V2 会话链路和后续 Design Agent 迁移。 -- 当前分支已经删除 Rust V1/V2 Runtime 模块和旧审批组件,但前端仍残留旧 V2 调用方;实现前须保持工作树干净。 - -## 验收标准 - -- [ ] “做方案”入口和已有 Design Agent 项目只调用当前 Design Agent IPC,不再调用旧 `planning_*_v2` IPC。 -- [ ] 当前 Design Agent 的消息、reasoning、澄清、阶段审批和重试行为不依赖旧 V2 状态变量。 -- [ ] 源码中不再存在旧 V2 TypeScript 会话适配层、旧 `PlanGdd` 类型和旧前端审批契约。 -- [ ] 旧前端测试、事件测试和样式残留被删除或改为当前 Design Agent 契约。 -- [ ] 不主动修改做游戏 Supervisor + 16 Agent DAG;因共享退役代码删除产生的编译错误得到最小修复。 -- [ ] 前端 typecheck、相关定向测试、编码检查和 diff 检查通过;触及 Rust 时对应 cargo check 通过。 - -## 证据要求 - -- 自动化:`npm --prefix apps/ai-game-creator-shell run typecheck`、相关 appSurface 定向测试、`npm run check:encoding`、`git diff --check`。 -- 运行时:至少验证“做方案”新项目进入 Design Agent、已有 Design Agent 会话恢复、澄清/审批回合可继续。 -- 边界:确认 DirectCodex 和做游戏既有入口未被旧策划清理改动;确认旧 V2 IPC 字符串和旧事件契约不再进入现役前端。 diff --git a/docs/project-memory/plans/【里程碑】退役策划V2 Rust Runtime清理-2026-09-14.md b/docs/project-memory/plans/【里程碑】退役策划V2 Rust Runtime清理-2026-09-14.md deleted file mode 100644 index 8fcab81ad..000000000 --- a/docs/project-memory/plans/【里程碑】退役策划V2 Rust Runtime清理-2026-09-14.md +++ /dev/null @@ -1,38 +0,0 @@ -# Version - -V2-RUST-RETIRE-1 - -# Status - -in-progress - -# Date - -2026-09-14 - -# Parent Spec - -`docs/technical/【技术方案】策划会话RuntimeV2接入与旧链路退役-2026-09-03.md` - -# 目标 - -删除已经被独立 Design Agent 取代的旧策划 V2 Rust Runtime、Tauri 命令注册和仅服务 V2 的模块导出,使桌面壳继续编译并保留做游戏 Agent 与新版 Design Agent。 - -# 边界 - -- 删除 `planning_policy_v2`、`planning_session_v2` 及仅供这两者使用的 V2 注册和调用。 -- 删除 V2 专属的 Tauri command 注册、模块导出和测试入口。 -- 保留 `design_runtime`、`design_tools`、`design_session`、通用 runtime、DirectProject 和做游戏 Agent。 -- 本里程碑不处理前端 V2 数据层、UI、文档索引和共享运行时中的可选清理。 - -# 验收标准 - -1. Rust 源码不再编译 `planning_policy_v2.rs` 或 `planning_session_v2.rs`。 -2. `main.rs`、`commands.rs` 和 runtime protocol 不再注册或导出 V2 命令。 -3. 新版 Design Agent 与做游戏 Agent 的 Rust 编译路径保持可用。 -4. 相关定向 Rust 测试和 `cargo check` 通过。 - -# 依赖 - -- 当前分支已包含 PR159 的 V1 清理。 -- 前端 V2 调用暂时保留,待后续里程碑同步删除。 diff --git a/docs/project-memory/shared-memory/decision-log.md b/docs/project-memory/shared-memory/decision-log.md index f9d61a507..e504f0aaa 100644 --- a/docs/project-memory/shared-memory/decision-log.md +++ b/docs/project-memory/shared-memory/decision-log.md @@ -1,5 +1,12 @@ # 决策记录 +## 策划 V1/V2 退役的现行边界 + +- 旧策划 V1 和 Runtime V2 均已删除,当前策划入口统一使用独立 Design Agent。V1 被 V2 接替只描述历史过程,不表示 V2 仍在使用。 +- 下文旧策划版本的阶段审批、`plan.submit_gdd`、planning session binding、exact planning lifecycle v3、专属身份白名单、IPC 和测试约束均为历史记录,不能作为恢复代码或保留孤立实现的理由。不新增旧版本兼容别名、双跑或回退链路。 +- 通用项目锁、权限、持久化和当前 Design Agent 能力按实际调用保留;清理未用参数不扩大为删除调用方的持锁范围或锁归属校验。 +- 当前事实源:[策划 Agent 生产迁移与工作区浏览](../../technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md)。 + ## 2026-09-23 运行视窗:右下角全屏预览 + 没有内容就自动收起的信息栏 - 背景:运行页右下角缺一个把游戏画面放大到整屏的入口;运行视窗下方常驻「信息展示 / 数值微调」两张卡片,没有选中资源时就是两块空白,验收现场提出「没有功能就暂时隐藏」。 diff --git a/docs/project-memory/shared-memory/document-map.md b/docs/project-memory/shared-memory/document-map.md index fe12603b2..7f4a1a4d5 100644 --- a/docs/project-memory/shared-memory/document-map.md +++ b/docs/project-memory/shared-memory/document-map.md @@ -1,6 +1,6 @@ # 文档地图与阅读索引 -更新时间:`2026-08-31` +更新时间:`2026-09-23` ## 阅读顺序 @@ -24,14 +24,14 @@ AI 游戏创作 / DirectProject / UI workflow: 1. `docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md` -2. `docs/technical/【技术方案】策划会话RuntimeV2接入与旧链路退役-2026-09-03.md`(历史方案,仅供追溯) +2. `docs/technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md`(当前 Design Agent;旧策划 V1/V2 均已退役) 3. `docs/technical/【技术方案】DirectProject客户端Skill与MCP扩展导入方案-2026-08-31.md` 4. `docs/prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md` 5. `docs/technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md`(历史 V1 方案,仅供追溯) 6. `docs/technical/【技术方案】DirectProject Codex原始历史与异常恢复-2026-09-04.md` 7. `docs/technical/【技术方案】DirectProject客户端Skill与MCP扩展导入方案-2026-08-31.md` 8. `docs/prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md` -9. `docs/technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md` +9. `docs/technical/【技术方案】策划会话RuntimeV2接入与旧链路退役-2026-09-03.md`(历史 V2 方案,仅供追溯,不是当前实现依据) 10. DirectProject 附件按 AGC 主实施计划的 canonical `userItem` 合同;`docs/technical/【技术方案】DirectProject本轮附件路径映射-2026-08-31.md` 为旧 sidecar 历史方案,不作为实现入口。 11. Direct 历史、审计与耗时按 AGC 实施计划及原始历史专题;`docs/technical/【技术方案】Direct回合行为审计账本-2026-08-31.md` 已归历史,不作为实现入口。 12. `docs/technical/【技术方案】GameAgent资源自由画板与快速编辑-2026-08-20.md` diff --git a/docs/project-memory/shared-memory/pitfalls.md b/docs/project-memory/shared-memory/pitfalls.md index 2efa4c511..2b7159171 100644 --- a/docs/project-memory/shared-memory/pitfalls.md +++ b/docs/project-memory/shared-memory/pitfalls.md @@ -1,5 +1,7 @@ # 踩坑与排障记录 +> 策划历史条目边界:旧策划 V1/V2 已全部退役,当前入口仅使用 Design Agent。下文带日期的旧 Planning V2、Fast GDD、`plan.submit_gdd`、旧 IPC/模块记录仅用于追溯,不能作为恢复旧代码、身份门禁或专属测试的依据;共享问题需在现役调用上核查。现行合同见[策划 Agent 生产迁移与工作区浏览](../../technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md)。 + ## 策划回复的重复终态不能重新启动伪流式 策划 Runtime 会通过状态事件与命令返回交付同一份最终视图。若前端清空临时正文后再拿“最后一条非用户历史消息”回填动画,就会出现正式回复旁又播放一遍、播放后消失的假重试。正文应按 `messageId` 保存显示进度,与正式消息共用一个气泡;请求完成不清动画,不延迟正式业务状态。Provider 自动重试复用消息 ID 并发送空文本,只允许重置未持久化的该条回复。正文、工具状态和 reasoning 分开;事件与异步命令收尾均检查项目及活动回合,旧请求不能覆盖新回合。详见 [AGC 实施计划](../../technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md)。 diff --git a/docs/project-memory/todos/【待解决】主要构建入口编译警告清单-2026-09-23.md b/docs/project-memory/todos/【待解决】主要构建入口编译警告清单-2026-09-23.md index 1fa1c5d9e..c0cbc28a7 100644 --- a/docs/project-memory/todos/【待解决】主要构建入口编译警告清单-2026-09-23.md +++ b/docs/project-memory/todos/【待解决】主要构建入口编译警告清单-2026-09-23.md @@ -7,7 +7,7 @@ ## 1. 基线与范围 -首次诊断的基线提交为 `016356e509f11a1a638ce45ed51b9e40ef3e36a2`,诊断时工作树干净。环境为 Windows x64、Rust `1.98.1`、Node `v24.15.0`、npm `12.0.2`。第 2~6 节和附录保留首次诊断快照;后续处理状态及契约核查见第 7~16 节,不能将附录的全部条目视为仍未解决。 +首次诊断的基线提交为 `016356e509f11a1a638ce45ed51b9e40ef3e36a2`,诊断时工作树干净。环境为 Windows x64、Rust `1.98.1`、Node `v24.15.0`、npm `12.0.2`。第 2~6 节和附录保留首次诊断快照;后续处理状态及契约核查见第 7~18 节,不能将附录的全部条目视为仍未解决。 AGC Rust 使用默认 features、dev profile;237 是本轮编译器诊断数,不代表 237 个独立根因,也不是所有平台、features 和 test targets 的总数。另有 5 条不带常规源码 span 的 ts-rs 宏提示,不计入 237。 @@ -247,9 +247,11 @@ three、FBX/GLTF loader、OrbitControls 已动态 import。不能把“改为动 ### 三条待核定项 +以下为初审快照;策划 V1/V2 均已退役,W063 的当前结论已纠正为可清理,详见第 17 节。Fast GDD 历史条款不能作为恢复旧策划实现的依据。 + | 编号 | 已确认事实 | 下一步判据 | | --- | --- | --- | -| W063 | `runtime_driver.rs:391` 的 plan lifecycle v3 常量无引用;`runtime_protocol/provider_control.rs:355` 的现有 writer 使用通用 v2 常量;Fast GDD 文档第 1270 行仍要求 exact plan 的 v3 语义 | 跟踪 exact plan 请求实际 writer / reader,核定 v3 是否在别处实现、文档已过期或实现缺失;不凭一个常量删改持久化版本 | +| W063 | plan lifecycle v3 常量无引用;它服务的旧策划 V1 已整体退役,曾接替 V1 的 V2 也已删除。Fast GDD 的 v3 条款仅属历史合同 | 可删除孤立常量;保留现役通用 lifecycle v2 writer/reader,不补回旧 v3 链路 | | W069 | `finalization.rs:6–10` 的 Deferred 注释描述 project→execution 重取失败,当前无构造;`recovery_scan.rs:1092,1105,1114` 仍匹配,pending recovery 未发现注释所述释放 / 重取;Fast GDD 第 2144 行只承诺新增 planning 澄清路径锁序 | 明确旧注释 / 分支是否已经退役,再删除对应分支或另立行为修复;本轮不改变锁序 | | W071 | `task_start.rs:745–753` 的孤立 helper 读取 Goal sidecar;相邻现役 `autonomous_root_goal_contract_persisted_at` 在验证身份后返回 `Ok(true)`,与第 755~758 行“缺 sidecar no-op、损坏报错”的注释不符 | 核定当前 scheduler 的 Goal 前置合同,再决定删除旧 helper / 更新注释还是修复检查;不把恒真入口视为已验证的 Goal 门禁 | @@ -359,7 +361,7 @@ three、FBX/GLTF loader、OrbitControls 已动态 import。不能把“改为动 | 编号 | 当前证据入口 | 处理边界 | | --- | --- | --- | -| W063 | `src/agent/runtime_driver.rs:391` | 常量 v3 当前仅声明,provider_control.rs:355 使用 v2;Fast GDD 文档明确 exact plan lifecycle v3,需先核实计划请求实际 writer/reader 是否别处落地,再定常量去留。 | +| W063 | `src/agent/runtime_driver.rs:391` | 旧策划 V1/V2 已明确删除,孤立 v3 常量可清理;现役通用 lifecycle v2 保留,不为历史 Fast GDD 条款恢复实现。 | | W069 | `src/agent/runtime_driver/finalization.rs:10` | Deferred 在此 enum 无构造,但 recovery_scan 有三处 continue 及同步路径 Err;注释描述通用 project→execution 重取失败,pending_recovery 没有相应释放/重取,Fast GDD 文档锁序承诺只覆盖 planning 澄清。先确认旧注释/分支是否退役。 | | W071 | `src/agent/runtime_driver/task_start.rs:745` | 死 helper 会读取 Goal sidecar;现役 autonomous_root_goal_contract_persisted_at 返回 Ok(true),ready-task parent validator 只查身份,和相邻注释承诺的 sidecar 未落盘 no-op/坏数据报错冲突。先裁定当前合同再动 helper。 | @@ -586,6 +588,33 @@ W076 只将 Pending(String) 收窄为 Pending;三处生产返回前继续记 最近一次实测仍为第 14 节的 **50 条**。第 15~16 节共处理其中 20 条,预期剩余 **30 条**,尚未重新编译确认;不能将预期数作为实测结果。 +## 17. 策划 V1/V2 退役口径纠正(2026-09-23) + +用户确认旧策划 V1、V2 均已明确删除。当前策划入口仅为 Design Agent,合同以[生产迁移与工作区浏览](../../technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md)为准;Fast GDD 和策划会话 Runtime V2 文档仅供历史追溯。不得因旧文档出现“必须”、源码残留常量或测试引用而要求恢复旧版本功能。 + +这修正了原审计对相关警告的保留判断: + +- W063:旧 exact planning lifecycle v3 常量可删;通用 Provider lifecycle v2 的当前写入与校验不是该旧功能的实现缺口。 +- W213/W215:旧策划阶段读取和会话投影已删除,内部锁参数透传可清理;外层持锁范围与正式 locked 入口的项目锁归属校验继续保留。 +- W214/W219:旧策划专属工具身份白名单已删除,未用 `agent_id`、`__all_agents__` 包装及过时注释可按实际调用清理。现有通用工具注册表、run/profile 与控制权检查不等于按 Agent 身份的白名单,不另行恢复旧门禁。 +- W069 的旧策划锁序注释不再构成保留无构造 `Deferred` 的依据;删除死分支不等于调整通用 Runtime 锁序。 + +本节先更新契约及审计结论,后续代码清理见第 18 节。已同步修正历史方案入口、当前实施计划和共享记忆,并删除已被现役迁移结果取代的四份退役临时计划/里程碑。本次文档纠正本身不计作 warning 减少。 + +## 18. 旧策划链路相关警告清理(2026-09-23) + +本批落实第 17 节对应的 6 条诊断:W063、W069、W213、W214、W215、W219。范围仅为旧策划 V1/V2 退役残留,不包含其余视觉素材、Goal helper、用户修订包装和 Direct 回合初始化候选。 + +- W063:删除无人引用的 plan Provider lifecycle v3 常量,通用 v2 记录与校验不变。 +- W069:删除没有构造点的 `AgentRuntimePendingActionResume::Deferred` 及恢复扫描、精确继续和测试结果适配中的专属分支;不修改取锁或恢复执行逻辑。 +- W213:把请求构建本体合入原 locked 入口,删除内部 `Option<&ProjectWriteLock>` 参数和转发包装。locked 签名仍要求借用项目锁;调用方在请求构建前后读取 manifest 的同一 guard 作用域保持原样。该借用约束本身不新增项目归属校验。 +- W215:合并任务入队的无用锁透传包装;保留 locked 入口的 `guards_project_root` 校验、调用方 guard、session lane 和入队后通知顺序。 +- W214/W219:合并通用工具计划解析和原生工具目录的无身份实现,删除未使用的 `agent_id` 参数、`__all_agents__` 哨兵包装及过期说明;同步生产调用与原测试调用,断言不变。工具协议、全局注册表、项目插件可用性和请求侧权限过滤保持原逻辑,不恢复旧策划身份白名单。 + +验证:静态核对所有改名/删参调用、旧符号残留和锁作用域;修改文件 rustfmt、编码、文档索引及 `git diff --check` 通过。按用户要求未执行 Cargo check/build/test,也未运行旧二进制冒充修改后验证;未新增测试。 + +最近一次实测仍为第 14 节的 50 条;第 15~16 节预期减少 20 条,本批再处理 6 条,预期剩余 **24 条**,尚未重新编译确认。 + ## 附录:237 条编译器诊断位置 以下是诊断的人工可读整理,不保存原始构建日志、本机路径或 target 缓存路径。位置相对 `apps/ai-game-creator-shell/src-tauri/`;行号只对应本节基线,修改后以符号搜索及重新编译为准。每条保留一个主要 span,编号用于本清单内跟踪,不表示独立业务缺陷。生成产物项须回到 `build_support/runtime_prompt_bundle.rs` 处理。 diff --git a/docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md b/docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md index 625d38d09..cdba75b97 100644 --- a/docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md +++ b/docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md @@ -1,5 +1,9 @@ # AI 游戏创作智能体 App 实施计划 +## 当前策划入口与退役边界 + +策划 V1、策划会话 Runtime V2 均已删除,当前“做方案”只使用独立 Design Agent,现行合同见[策划 Agent 生产迁移与工作区浏览](./【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md)。旧 V1/V2 Runtime、命令、会话、审批卡、身份白名单和专属测试不作为兼容或恢复目标;历史方案中的 lifecycle v3、planning binding 等要求不能作为孤立代码的保留依据。共享能力按现役调用判断,不因名称相似删除当前 Design Agent 或通用 Runtime。 + ## 2026-09-23 Direct 宿主继续请求输入修复 - 首次模型请求使用原始结构化用户输入,保留 Skill 提及及其它引用;未提供结构化输入时沿用请求正文与图片转换。 @@ -356,7 +360,7 @@ DirectProject 的生图、素材处理、构建和试玩可能跨越短生命周 DirectProject 工作区只恢复自身对话,不按专业 Agent 默认任务占位行批量读取旧会话或生成专业 Agent 文本回执。专业 Agent 结果加载 effect 必须以当前 Runtime 模式为边界,并在模式切换时清空旧结果。仍供开发入口使用的 `read_local_conversation` 在 blocking worker 内完整执行权限校验、会话目录解析和历史读取,避免文件访问或锁等待阻塞 Tauri 窗口线程。 -项目打开链路的目录检查、manifest 读取、项目 revision 读取和 Planning V2 hydrate 也必须通过 blocking worker 执行;它们可能碰到项目写锁,不能在 Tauri 窗口线程同步等待。 +项目打开链路的目录检查、manifest 读取和项目 revision 读取也必须通过 blocking worker 执行;它们可能碰到项目写锁,不能在 Tauri 窗口线程同步等待。Planning V2 hydrate 已随旧策划 Runtime 删除,不再属于现役打开链路。 DirectProject 自身的 `read_direct_project_conversation` 也必须在 blocking worker 中执行权限校验、JSONL 历史解析和消息投影,不能因为它只读取一份项目历史就保留同步 Tauri command。 @@ -1529,7 +1533,7 @@ DirectProject 使用 `approvalPolicy=never`,避免每次原生调用再经过 - `agc_write_file` 是用户直接触发、失败即整轮无法落盘的项目写入通道,原先却用零等待 `acquire_project_write_lock`:任何重叠都在 24-42ms 内被判成“项目正在被其他写操作占用”,而 `file.write / file.patch / file.delete` 等入口用的是约 10 秒有界等待。现统一为 `acquire_game_creator_agent_runtime_project_write_lock_with_wait`:短暂重叠排队等成功,只有预算耗尽才报出带持锁方身份的错误;同一轮并行写多个文件按同一把锁串行。这是 2026-07-22 同一形状修复在 Direct 通道上的补齐,与 2026-08-13 一节“这些结果统一投影为争用并进入既有有界等待”的口径一致。**失败耗时是判据**:几十毫秒说明该入口没等,不是锁没释放。 - 这条等待是**同步轮询**(2_000 × 5ms,最多约 10 秒),而 `handle_direct_tool_bridge` 是 async handler:直接在 handler 里跑完整条写路径会占住一个 tokio worker,争用窗口内同一轮并行写多个文件时会有多个 worker 被占,而这条 bridge 与只读端点、UI 命令共享同一个 runtime——Issue #318 现场“只读工具全部正常”这条诊断特征会在争用窗口内失效。因此写路径经 `bridge_write_file_in_blocking_pool` 走 `tokio::task::spawn_blocking`(仓库既有模式,如 `codex_app_server.rs` 的 DirectProject 历史落盘),等待语义与错误文案不变;定向用例用默认 `current_thread` runtime 加心跳任务锁住“等待期间 runtime 仍在推进”。 -- 争用错误必须带持锁方身份才可行动:`项目正在被其他写操作占用:<锁路径>(持锁方 commandId=<命令> pid=<进程> createdAt=<创建时间> ownerIsSelf=<是否本进程>)`。锁文件处于 delete-pending 或尚未写完时读不到身份,也必须显式表达成“不可读”,不得默认成“没有持锁方”。前缀逐字不变:`project_gates.rs`、`provider_recovery.rs`、`planning_session_v2.rs`、`direct_runtime.rs` 和前端 `App.tsx` 都按它把争用识别成可等待的瞬时状态;这句话已是 `crate::project::PROJECT_WRITE_LOCK_CONTENTION_PREFIX` 单一真源,四个站点不再各自手写中文。 +- 争用错误必须带持锁方身份才可行动:`项目正在被其他写操作占用:<锁路径>(持锁方 commandId=<命令> pid=<进程> createdAt=<创建时间> ownerIsSelf=<是否本进程>)`。锁文件处于 delete-pending 或尚未写完时读不到身份,也必须显式表达成“不可读”,不得默认成“没有持锁方”。现役调用方通过 `crate::project::PROJECT_WRITE_LOCK_CONTENTION_PREFIX` 单一真源识别争用,不各自手写中文;已删除的 `planning_session_v2.rs` 不再列为现役调用点。 - `create_new` 的失败必须分三类处置,不能再共用一句文案:可重试(目标已存在、Windows `sharing violation(32)` / `lock violation(33)` / `ACCESS_DENIED(5)`)进入有界等待;明确判定不是争用的权限 / ACL 拒绝(Unix `EACCES`)失败关闭且文案不含争用前缀;其它 I/O 错误原样上报。**重试性只能由错误码决定,不能用 `path.exists()` 这类一次 metadata 观察决定**:目标被删除时目录项先消失、删除挂起随后才结束,`create_new` 会在这个拆链窗口里返回 `ACCESS_DENIED(5)`,而 `exists()` 往往已经报 false(本机实测 6 万次建锁 / 删锁竞争里 396-538 例命中该组合)。按“目标不存在”当场判成权限拒绝,等待层就会立刻失败关闭——正是本次要消灭的“毫秒级直接失败”,只是换成更误导的 ACL 文案。平台判据以 `project_write_lock_open_failure_for(platform, error)` 保留、平台由参数传入而不是 `#[cfg]`:CI 只有 Linux runner,Windows 分支必须在 Linux 上也能断言。 - Windows 上真实 ACL 拒绝与删除拆链窗口在错误码上不可区分,所以终态改判放到**等待预算耗尽之后**:`ProjectWriteLockFailure::exhausted_projection(waited)` 只在“真的等过预算 + 目标此刻仍不存在 + 错误码是 `ACCESS_DENIED(5)`”三个条件同时成立时才投影成权限拒绝;单次试探(`max_attempts == 1`,例如 hydrate 的 `try_acquire_...`)没有等待证据,保持争用语义。代价是 Windows 上真实 ACL 拒绝会先等满等待窗口(约 10 秒)才报权限错误;Unix 的 `EACCES` 立即判定、不等待。 - 重试与否改由**类型**决定,不再解析错误文案:`acquire_project_write_lock_failure` 返回 `ProjectWriteLockFailure::{Retryable, Terminal}`,有界等待按 `is_retryable()` 分流,`acquire_project_write_lock` 只是它的文案包装。零等待入口前缀不变,只在“错误码不可区分且目标此刻不存在”时补一句“可能是删除挂起、删除拆链窗口或权限 / ACL 拒绝”,把两种处置都交给调用方,而不是替它猜一个。 diff --git a/docs/technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md b/docs/technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md index 5f231d263..353592059 100644 --- a/docs/technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md +++ b/docs/technical/【技术方案】立项策划Agent(Fast GDD)-2026-08-10.md @@ -1,10 +1,10 @@ # 立项策划 Agent(Fast GDD)技术方案 - 日期:2026-08-10 -- 状态:**已退役**。本文描述的 V1 策划链路(`project-supervisor-plan` 根 Run、`project-planning` 子 Agent、`plan.submit_gdd` 工具、Fast GDD 审批门禁与恢复机制)已由策划会话 Runtime V2 取代,源码已于 2026-09 按四不写原则整体删除;现行方案见 `【技术方案】策划会话RuntimeV2接入与旧链路退役-2026-09-03.md`。本文仅作为历史推导记录保留。 +- 状态:**历史方案,已退役**。策划 V1 和曾接替它的 Runtime V2 均已删除,V2 不是现行方案。当前策划入口统一使用独立 Design Agent,见[策划 Agent 生产迁移与工作区浏览](./【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md)。本文仅供历史追溯,不要求恢复旧 Runtime、审批、工具、身份门禁、持久化协议或专属测试。 - 适用范围:AI 游戏创作独立 App、Project Supervisor、Agent Runtime、本地项目策划 sidecar 与后续完整构建准入 -> 当前口径(2026-08-30):以本文件中标注的 D11 / 最新修订和当前 `apps/ai-game-creator-shell` 实现为准。D6~D9 等被明确标注为作废或被取代的段落仅保留推导背景,不得作为现行拓扑、入口或 Runtime 真相;产品入口与 DirectProject 总体口径见 `docs/README.md` 和 App 实施计划。 +> 历史内容边界(2026-09-23):下文的 D11、版本修订、“当前”“必须”和验收要求均描述退役前的 V1,不能覆盖现役 Design Agent 合同。包括 exact planning lifecycle v3、`planningSessionBinding` 和 `plan.submit_gdd` 在内的旧要求,不构成恢复实现或保留孤立代码的依据。 ## 1. 背景与目标 diff --git a/docs/technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md b/docs/technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md index ecbb3008a..ed7e775da 100644 --- a/docs/technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md +++ b/docs/technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md @@ -1,10 +1,12 @@ # 策划 Agent 生产迁移与工作区浏览方案 -更新时间:2026-09-21 +更新时间:2026-09-23 状态:已完成(2026-09-18) > 现状说明(2026-09-18):本文记录的迁移已完成,当前策划入口统一使用 Design Agent。旧 Planning V1/V2 会话、专用命令、审批卡和展示适配已删除;文中提到的 V2 文件仅代表迁移时的参考来源,不得作为现行实现、回退路径或测试迁移目标。 +策划 V1 和 V2 的退役均已确定,不再作为待实施迁移。旧 `plan.submit_gdd`、planning session binding、exact planning lifecycle v3、V1 专属工具身份白名单与 V2 IPC/Runtime 均不属于当前合同。清理孤立常量、未用参数、包装和旧说明时,不为满足这些历史要求恢复代码或迁移专属测试。共享锁、通用持久化、资源权限和当前 Design Agent 的会话、澄清、阶段审批按实际现役调用保留;用户已有文件不因源码清理而删除。 + ## 1. 目标 将 `local-scripts/design_agent_refactored` 中已经验证的自由协作型策划 Agent 迁移到生产 App。生产代码只提供可靠的运行基础设施,Agent 的工作方式以原型为准。 diff --git a/docs/technical/【技术方案】策划会话RuntimeV2接入与旧链路退役-2026-09-03.md b/docs/technical/【技术方案】策划会话RuntimeV2接入与旧链路退役-2026-09-03.md index 9012f52a4..dd3987183 100644 --- a/docs/technical/【技术方案】策划会话RuntimeV2接入与旧链路退役-2026-09-03.md +++ b/docs/technical/【技术方案】策划会话RuntimeV2接入与旧链路退役-2026-09-03.md @@ -4,7 +4,7 @@ - 状态:**历史方案,已完成并退役**。Runtime V2 及其专用入口、命令、展示和测试已在 2026-09 按四不写原则删除;当前“做方案”统一使用独立 Design Agent。 - 适用范围:历史 AGC“做方案”入口、策划会话、GDD 产物与审批设计 -> 本文只用于追溯 Runtime V2 的设计和退役过程,不是现行实现依据。不要恢复 `planning_session_v2`、`planning_policy_v2`、`hydrate_planning_session_v2` 或 V2 专用 UI;当前行为以 Design Agent 生产迁移方案和代码为准。 +> 本文只用于追溯 Runtime V2 的设计和退役过程,不是现行实现依据。策划 V1、V2 均已删除,不保留兼容别名、双跑或回退路径;不要恢复 `planning_session_v2`、`planning_policy_v2`、`hydrate_planning_session_v2`、专属审批/UI 或旧测试。当前行为以[Design Agent 生产迁移方案](./【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md)和代码为准,下文的版本要求与验收清单仅描述历史实现。 ## 1. 决策摘要