codex: auto-unarchive archived sessions safely on resume

Preserve the auto-unarchive-on-resume behavior while keeping archived-session lookup safe. This carries the rollout lookup hardening, the resume path updates, and the cross-platform guardian/TUI test fixes needed for current CI.
This commit is contained in:
Friel
2026-03-13 20:34:24 -07:00
parent 65f631c3d6
commit 328706da37
8 changed files with 242 additions and 9 deletions

View File

@@ -9,6 +9,7 @@ use codex_core::RolloutRecorder;
use codex_core::RolloutRecorderParams;
use codex_core::config::ConfigBuilder;
use codex_core::find_archived_thread_path_by_id_str;
use codex_core::find_or_unarchive_thread_path_by_id_str;
use codex_core::find_thread_path_by_id_str;
use codex_core::find_thread_path_by_name_str;
use codex_protocol::ThreadId;
@@ -219,3 +220,74 @@ async fn find_archived_locates_rollout_file_by_id() {
assert_eq!(found, Some(expected));
}
#[tokio::test]
async fn find_thread_path_by_id_str_does_not_unarchive_archived_rollout() {
let home = TempDir::new().unwrap();
let id = Uuid::new_v4();
let archived = write_minimal_rollout_with_id_in_subdir(home.path(), "archived_sessions", id);
let found = find_thread_path_by_id_str(home.path(), &id.to_string())
.await
.unwrap();
assert_eq!(found, None);
assert!(archived.exists());
}
#[tokio::test]
async fn find_or_unarchive_restores_archived_rollout_file_by_id() {
let home = TempDir::new().unwrap();
let id = Uuid::new_v4();
let archived = write_minimal_rollout_with_id_in_subdir(home.path(), "archived_sessions", id);
let file_name = archived.file_name().unwrap().to_owned();
let expected_restored = home.path().join("sessions/2024/01/01").join(file_name);
let found = find_or_unarchive_thread_path_by_id_str(home.path(), &id.to_string())
.await
.unwrap();
assert_eq!(found, Some(expected_restored.clone()));
assert!(expected_restored.exists());
assert!(!archived.exists());
let archived_found = find_archived_thread_path_by_id_str(home.path(), &id.to_string())
.await
.unwrap();
assert_eq!(archived_found, None);
}
#[tokio::test]
async fn find_does_not_move_unrelated_file_for_stale_archived_db_path() {
let home = TempDir::new().unwrap();
let requested_id = Uuid::new_v4();
let requested_thread_id = ThreadId::from_string(&requested_id.to_string()).unwrap();
let unrelated_id = Uuid::new_v4();
let unrelated_active_path = write_minimal_rollout_with_id(home.path(), unrelated_id);
upsert_thread_metadata(
home.path(),
requested_thread_id,
unrelated_active_path.clone(),
)
.await;
let runtime = StateRuntime::init(home.path().to_path_buf(), "test-provider".to_string())
.await
.unwrap();
runtime.mark_backfill_complete(None).await.unwrap();
runtime
.mark_archived(
requested_thread_id,
unrelated_active_path.as_path(),
Utc::now(),
)
.await
.unwrap();
let found = find_or_unarchive_thread_path_by_id_str(home.path(), &requested_id.to_string())
.await
.unwrap();
assert_eq!(found, None);
assert!(unrelated_active_path.exists());
}