把 Fast GDD 审批等待的可恢复判据钉成不变量
判据在 task record 的 status 而不是 phase:审批等待只改 phase、保留 status=running,恢复扫描仍会拉起;真正的澄清等待才会把 status 一并写成 waiting-for-user-input。一旦有人把审批等待也写成后者,审批命令的通用 wake 会静默变成 no-op,用户点完批准/修改/退回不会有任何东西继续跑,且无报错。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1770,3 +1770,76 @@ mod orphaned_external_generation_recovery_tests {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod plan_gdd_approval_wait_recovery_tests {
|
||||
use super::*;
|
||||
|
||||
/// Fast GDD 审批等待期,根 Supervisor 到底还能不能被恢复扫描拉起。
|
||||
///
|
||||
/// 判据不在 `phase` 上:`read_recoverable_game_creator_agent_runtime_task` 按
|
||||
/// task record 的 **status** 分类,而 record 的 status 由
|
||||
/// `game_creator_agent_runtime_task_status` 从 `state.status` 推导。审批等待
|
||||
/// (`main_loop` 的 `runtime.plan_gdd` 分支)只改 phase、保留 `status="running"`;
|
||||
/// 真正的澄清等待(`action_projection`)才会把 status 一并写成
|
||||
/// `waiting-for-user-input`,那才是恢复扫描要让路的外部输入等待。
|
||||
///
|
||||
/// 这个区别决定了审批决定之后还有没有生产路径驱动父 run:审批命令只调通用
|
||||
/// wake,一旦有人把审批等待也写成 `status="waiting-for-user-input"`,通用 wake
|
||||
/// 会静默变成 no-op,用户点了批准/修改/退回之后不会有任何东西继续跑。这条测试
|
||||
/// 把这个区别钉成不变量。
|
||||
#[test]
|
||||
fn plan_gdd_approval_wait_stays_recoverable_while_real_user_input_wait_does_not() {
|
||||
let temporary = crate::tests::canonical_test_tempdir("plan-gdd-approval-wait-recovery-");
|
||||
let root = temporary.path();
|
||||
init_local_game_project_at(root, "plan-gdd-approval-wait", "Fast GDD 审批等待恢复判定")
|
||||
.expect("init project");
|
||||
let mut runtime = start_game_creator_agent_runtime_task_at(
|
||||
root,
|
||||
GAME_CREATOR_PROJECT_SUPERVISOR_AGENT_ID,
|
||||
"推进立项策划",
|
||||
"plan-gdd-approval-wait-run",
|
||||
"agent-ready-task-scheduler",
|
||||
"准备推进立项策划",
|
||||
vec!["推进立项策划".to_string()],
|
||||
)
|
||||
.expect("start plan-root supervisor runtime");
|
||||
|
||||
// main_loop.rs 的 Fast GDD 审批等待形状。
|
||||
runtime.status = "running".to_string();
|
||||
runtime.phase = "waiting-for-user-input".to_string();
|
||||
runtime.current_action = "等待 Fast GDD 审批决定".to_string();
|
||||
runtime.waiting_on = "用户在审批卡选择批准、修改或退回".to_string();
|
||||
runtime.updated_at = unix_timestamp();
|
||||
append_game_creator_agent_runtime_task(root, &runtime).expect("append approval wait task");
|
||||
refresh_game_creator_agent_runtime_task_queue(root, &mut runtime)
|
||||
.expect("refresh approval wait task queue");
|
||||
write_game_creator_agent_runtime_state(root, &runtime).expect("write approval wait state");
|
||||
|
||||
let task =
|
||||
read_recoverable_runnable_game_creator_agent_runtime_task(root, &runtime.agent_id)
|
||||
.expect("read approval wait task")
|
||||
.expect("审批等待态必须仍可被恢复扫描拉起,否则审批决定后没有生产路径驱动父 run");
|
||||
assert_eq!(task.status, "running");
|
||||
assert_eq!(task.phase, "waiting-for-user-input");
|
||||
assert!(has_recoverable_game_creator_agent_background_tasks_at(root)
|
||||
.expect("public preflight must agree with the recoverable task read"));
|
||||
|
||||
// 对照组:真正的用户输入等待把 status 一并写成 waiting-for-user-input。
|
||||
runtime.status = "waiting-for-user-input".to_string();
|
||||
runtime.updated_at = unix_timestamp();
|
||||
append_game_creator_agent_runtime_task(root, &runtime)
|
||||
.expect("append user input wait task");
|
||||
refresh_game_creator_agent_runtime_task_queue(root, &mut runtime)
|
||||
.expect("refresh user input wait task queue");
|
||||
write_game_creator_agent_runtime_state(root, &runtime)
|
||||
.expect("write user input wait state");
|
||||
|
||||
assert!(
|
||||
read_recoverable_runnable_game_creator_agent_runtime_task(root, &runtime.agent_id)
|
||||
.expect("read user input wait task")
|
||||
.is_none(),
|
||||
"status 写成 waiting-for-user-input 才是恢复扫描让路的外部输入等待"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user