mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +00:00
Distinguish rollout IDs from thread IDs (#38127)
## Why `thread/revert` preserves a thread ID while creating a new immutable rollout. Rollout persistence and filesystem fallback therefore need to distinguish the logical thread from each physical history file. ## What changed - Add a `RolloutId` alias and canonical filename parsing for both ordinary rollouts and reverted rollouts with a distinct rollout ID. - Allow the recorder to create a replacement rollout without changing the thread ID, and add lookup by either the stable thread ID or an exact rollout ID. - Index history references and compression safety checks by rollout ID so multiple rollouts for one thread remain distinct. - Preserve the rollout path selected in SQLite when filesystem repair encounters another rollout for the same thread. ## Testing Add coverage for filename round trips, replacement rollout metadata, thread and rollout lookup, reference indexing, compression, and database path preservation. GitOrigin-RevId: 14b1d0b4a9432b341a1307afc0abadd507e7ae7d
This commit is contained in:
1 parent
2230d64464
commit
4ef836f883
18 files changed
+513
-178
No files matched your search
@@ -554,6 +554,15 @@ pub async fn reconcile_rollout(
|
||||
let memory_mode = outcome.memory_mode.unwrap_or_else(|| "enabled".to_string());
|
||||
metadata.cwd = normalize_cwd_for_state_db(&metadata.cwd);
|
||||
let existing_metadata = ctx.get_thread(metadata.id).await.ok().flatten();
|
||||
// Filesystem repair may seed a missing row, but it must not change an existing row's
|
||||
// selected rollout path. After `thread/revert`, a scan can find multiple immutable
|
||||
// rollouts for one thread and cannot know which one SQLite selected.
|
||||
if existing_metadata
|
||||
.as_ref()
|
||||
.is_some_and(|existing| existing.rollout_path.as_path() != rollout_path)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Paginated metadata updates are SQLite-only. Use the rollout mode to seed a
|
||||
// missing row, then keep the value from SQLite.
|
||||
let restore_memory_mode_from_rollout =
|
||||
@@ -607,6 +616,12 @@ pub async fn read_repair_rollout_path(
|
||||
if let Some(thread_id) = thread_id
|
||||
&& let Ok(Some(metadata)) = ctx.get_thread(thread_id).await
|
||||
{
|
||||
// Filesystem repair may seed a missing row, but it must not change an existing row's
|
||||
// selected rollout path. After `thread/revert`, a scan can find multiple immutable
|
||||
// rollouts for one thread and cannot know which one SQLite selected.
|
||||
if metadata.rollout_path.as_path() != rollout_path {
|
||||
return;
|
||||
}
|
||||
saw_existing_metadata = true;
|
||||
let mut repaired = metadata.clone();
|
||||
repaired.rollout_path = rollout_path.to_path_buf();
|
||||
|
||||
Reference in new issue
Block a user