From d326b7ad7d24546b11a49c95d1e66400714b16b0 Mon Sep 17 00:00:00 2001 From: Brent Traut Date: Wed, 8 Jul 2026 01:59:38 -0700 Subject: [PATCH] fix(thread-store): suppress pre-materialization catalog updates --- codex-rs/thread-store/src/local/mod.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/codex-rs/thread-store/src/local/mod.rs b/codex-rs/thread-store/src/local/mod.rs index 387fea0385..135f0d6de7 100644 --- a/codex-rs/thread-store/src/local/mod.rs +++ b/codex-rs/thread-store/src/local/mod.rs @@ -350,7 +350,12 @@ impl ThreadStore for LocalThreadStore { let changed = !params.patch.is_empty(); Box::pin(async move { let thread = update_thread_metadata::update_thread_metadata(self, params).await?; - if changed { + if changed + && let Some(rollout_path) = thread.rollout_path.as_ref() + && codex_rollout::existing_rollout_path(rollout_path) + .await + .is_some() + { self.publish_catalog_change(ThreadCatalogChange::Upsert { thread_id }); } Ok(thread) @@ -408,6 +413,7 @@ mod tests { use super::*; use crate::LiveThread; + use crate::ThreadMetadataPatch; use crate::ThreadPersistenceMetadata; use crate::local::test_support::test_config; use crate::local::test_support::write_archived_session_file; @@ -683,11 +689,24 @@ mod tests { .await .expect("state db should initialize"); let store = Arc::new(LocalThreadStore::new(config, Some(runtime.clone()))); + let mut catalog_changes = store.subscribe_catalog_changes(); let thread_id = ThreadId::default(); let live_thread = LiveThread::create(store.clone(), create_thread_params(thread_id)) .await .expect("create live thread"); + live_thread + .update_metadata( + ThreadMetadataPatch::default(), + /*include_archived*/ false, + ) + .await + .expect("flush pending metadata"); + assert!(matches!( + catalog_changes.try_recv(), + Err(broadcast::error::TryRecvError::Empty) + )); + live_thread .update_memory_mode(ThreadMemoryMode::Disabled, /*include_archived*/ false) .await