Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 54 additions & 1 deletion codex-rs/core/src/rollout/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::config::Config;
use crate::rollout;
use crate::rollout::list::parse_timestamp_uuid_from_filename;
use crate::rollout::recorder::RolloutRecorder;
use crate::state_db::normalize_cwd_for_state_db;
use chrono::DateTime;
use chrono::NaiveDateTime;
use chrono::Timelike;
Expand Down Expand Up @@ -279,6 +280,7 @@ pub(crate) async fn backfill_sessions(
);
}
let mut metadata = outcome.metadata;
metadata.cwd = normalize_cwd_for_state_db(&metadata.cwd);
let memory_mode = outcome.memory_mode.unwrap_or_else(|| "enabled".to_string());
if rollout.archived && metadata.archived_at.is_none() {
let fallback_archived_at = metadata.updated_at;
Expand Down Expand Up @@ -728,11 +730,62 @@ mod tests {
assert!(state.last_success_at.is_some());
}

#[tokio::test]
async fn backfill_sessions_normalizes_cwd_before_upsert() {
let dir = tempdir().expect("tempdir");
let codex_home = dir.path().to_path_buf();
let thread_uuid = Uuid::new_v4();
let session_cwd = codex_home.join(".");
let rollout_path = write_rollout_in_sessions_with_cwd(
codex_home.as_path(),
"2026-01-27T12-34-56",
"2026-01-27T12:34:56Z",
thread_uuid,
session_cwd.clone(),
);

let runtime =
codex_state::StateRuntime::init(codex_home.clone(), "test-provider".to_string(), None)
.await
.expect("initialize runtime");

let mut config = crate::config::test_config();
config.codex_home = codex_home.clone();
config.model_provider_id = "test-provider".to_string();
backfill_sessions(runtime.as_ref(), &config, None).await;

let thread_id = ThreadId::from_string(&thread_uuid.to_string()).expect("thread id");
let stored = runtime
.get_thread(thread_id)
.await
.expect("get thread")
.expect("thread should be backfilled");

assert_eq!(stored.rollout_path, rollout_path);
assert_eq!(stored.cwd, normalize_cwd_for_state_db(&session_cwd));
}

fn write_rollout_in_sessions(
codex_home: &Path,
filename_ts: &str,
event_ts: &str,
thread_uuid: Uuid,
) -> PathBuf {
write_rollout_in_sessions_with_cwd(
codex_home,
filename_ts,
event_ts,
thread_uuid,
codex_home.to_path_buf(),
)
}

fn write_rollout_in_sessions_with_cwd(
codex_home: &Path,
filename_ts: &str,
event_ts: &str,
thread_uuid: Uuid,
cwd: PathBuf,
) -> PathBuf {
let id = ThreadId::from_string(&thread_uuid.to_string()).expect("thread id");
let sessions_dir = codex_home.join("sessions");
Expand All @@ -742,7 +795,7 @@ mod tests {
id,
forked_from_id: None,
timestamp: event_ts.to_string(),
cwd: codex_home.to_path_buf(),
cwd,
originator: "cli".to_string(),
cli_version: "0.0.0".to_string(),
source: SessionSource::default(),
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/core/src/state_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ fn cursor_to_anchor(cursor: Option<&Cursor>) -> Option<codex_state::Anchor> {
Some(codex_state::Anchor { ts, id })
}

fn normalize_cwd_for_state_db(cwd: &Path) -> PathBuf {
pub(crate) fn normalize_cwd_for_state_db(cwd: &Path) -> PathBuf {
normalize_for_path_comparison(cwd).unwrap_or_else(|_| cwd.to_path_buf())
}

Expand Down
Loading