diff --git a/codex-rs/core/src/session/handlers.rs b/codex-rs/core/src/session/handlers.rs index 16f4f9b6bf5c..e59435578d89 100644 --- a/codex-rs/core/src/session/handlers.rs +++ b/codex-rs/core/src/session/handlers.rs @@ -978,7 +978,10 @@ pub async fn shutdown(sess: &Arc, sub_id: String) -> bool { id: sub_id, msg: EventMsg::ShutdownComplete, }; - sess.send_event_raw(event).await; + sess.services + .rollout_thread_trace + .record_protocol_event(&event.msg); + sess.deliver_event_raw(event).await; sess.services .rollout_thread_trace .record_ended(codex_rollout_trace::RolloutStatus::Completed); diff --git a/codex-rs/core/src/session/tests.rs b/codex-rs/core/src/session/tests.rs index ec08f646dfa8..69ae6753a8f0 100644 --- a/codex-rs/core/src/session/tests.rs +++ b/codex-rs/core/src/session/tests.rs @@ -4336,6 +4336,41 @@ async fn spawn_task_turn_span_inherits_dispatch_trace_context() { ); } +#[cfg(debug_assertions)] +#[tokio::test] +async fn shutdown_complete_does_not_append_to_thread_store_after_shutdown() { + let (mut session, _turn_context) = make_session_and_context().await; + let store = Arc::new(codex_thread_store::InMemoryThreadStore::default()); + let thread_store: Arc = store.clone(); + let live_thread = LiveThread::create( + Arc::clone(&thread_store), + CreateThreadParams { + thread_id: session.conversation_id, + forked_from_id: None, + source: SessionSource::Exec, + base_instructions: BaseInstructions::default(), + dynamic_tools: Vec::new(), + event_persistence_mode: ThreadEventPersistenceMode::Limited, + }, + ) + .await + .expect("create thread persistence"); + session.services.thread_store = thread_store; + session.services.live_thread = Some(live_thread); + let session = Arc::new(session); + + assert!(handlers::shutdown(&session, "sub-1".to_string()).await); + + assert_eq!( + codex_thread_store::InMemoryThreadStoreCalls { + create_thread: 1, + shutdown_thread: 1, + ..Default::default() + }, + store.calls().await + ); +} + #[tokio::test] async fn shutdown_and_wait_allows_multiple_waiters() { let (session, _turn_context) = make_session_and_context().await;