diff --git a/codex-rs/codex-infty/src/orchestrator.rs b/codex-rs/codex-infty/src/orchestrator.rs index a1079464b7..9551347e6e 100644 --- a/codex-rs/codex-infty/src/orchestrator.rs +++ b/codex-rs/codex-infty/src/orchestrator.rs @@ -513,7 +513,7 @@ impl InftyOrchestrator { claim_path: &str, options: &RunExecutionOptions, ) -> Result { - let pool = VerifierPool::from_sessions( + let mut pool = VerifierPool::from_sessions( Arc::clone(&self.hub), sessions, options.verifier_timeout, @@ -521,6 +521,8 @@ impl InftyOrchestrator { ); let req = VerificationRequestPayload::new(claim_path, None, None); let round = pool.collect_round(&req).await?; + pool.rotate_passing(sessions, &self.conversation_manager, &round.passing_roles) + .await?; Ok(round.summary) } } diff --git a/codex-rs/codex-infty/src/roles/verifier_pool.rs b/codex-rs/codex-infty/src/roles/verifier_pool.rs index 9a63584d84..1ace688e0d 100644 --- a/codex-rs/codex-infty/src/roles/verifier_pool.rs +++ b/codex-rs/codex-infty/src/roles/verifier_pool.rs @@ -4,8 +4,6 @@ use std::time::Duration; use anyhow::Context as _; use anyhow::Result; use codex_core::ConversationManager; -use codex_core::config::Config; -use codex_core::config::ConfigOverrides; use codex_core::cross_session::CrossSessionHub; use codex_core::protocol::Op; @@ -130,10 +128,9 @@ impl VerifierPool { let _ = old.conversation.submit(Op::Shutdown).await; let _ = manager.remove_conversation(&old.conversation_id).await; - // load fresh config and spawn a new session - let config = Config::load_with_cli_overrides(Vec::new(), ConfigOverrides::default()) - .await - .context("failed to load Codex config for verifier respawn")?; + // Reuse the existing verifier's config so overrides (e.g., base_url in tests) + // are preserved when respawning a passing verifier. + let config = old.config.clone(); let role_config = RoleConfig::new(role.to_string(), config); let run_path = sessions.store.path(); let session = session::spawn_role( diff --git a/codex-rs/codex-infty/src/utils.rs b/codex-rs/codex-infty/src/utils.rs index 44e24ad631..fd5219802a 100644 --- a/codex-rs/codex-infty/src/utils.rs +++ b/codex-rs/codex-infty/src/utils.rs @@ -71,14 +71,20 @@ mod tests { std::fs::create_dir_all(base.join("deliverable")).unwrap(); std::fs::write(base.join("deliverable").join("a.txt"), "ok").unwrap(); let resolved = resolve_deliverable_path(base, "deliverable/a.txt").unwrap(); - assert!(resolved.starts_with(base)); + let base_abs = base.canonicalize().unwrap(); + assert!(resolved.starts_with(&base_abs)); } #[test] fn resolve_deliverable_rejects_escape() { let tmp = TempDir::new().unwrap(); let base = tmp.path(); - let err = resolve_deliverable_path(base, "../outside.txt").unwrap_err(); + // Create a real file outside of base so canonicalization succeeds + let outside = TempDir::new().unwrap(); + let outside_file = outside.path().join("outside.txt"); + std::fs::write(&outside_file, "nope").unwrap(); + + let err = resolve_deliverable_path(base, outside_file.to_str().unwrap()).unwrap_err(); let msg = format!("{err}"); assert!(msg.contains("escapes run store")); } diff --git a/codex-rs/codex-infty/tests/orchestrator.rs b/codex-rs/codex-infty/tests/orchestrator.rs index 39b3a6a631..8e7812a51d 100644 --- a/codex-rs/codex-infty/tests/orchestrator.rs +++ b/codex-rs/codex-infty/tests/orchestrator.rs @@ -171,6 +171,15 @@ async fn execute_new_run_drives_to_completion() -> anyhow::Result<()> { ), responses::ev_completed("solver-resp-4"), ]), + // Final verification of the deliverable + responses::sse(vec![ + responses::ev_response_created("verifier-resp-3"), + responses::ev_assistant_message( + "verifier-msg-3", + r#"{"verdict":"pass","reasons":[],"suggestions":[]}"#, + ), + responses::ev_completed("verifier-resp-3"), + ]), ]; for body in bodies { responses::mount_sse_once(&server, body).await;