Add rollout migration tooling and background migration (#37348)

## What changed

- Add `codex migrate-rollouts` with dry-run inspection by default, explicit `--apply`, thread filtering, optional I/O throttling, progress output, and JSON or verbose reports.
- Add the disabled-by-default `background_paginated_rollout_migration` feature to migrate legacy local sessions at startup before rollout compression begins.
- Persist a migration cursor and skipped-file fingerprints so later startups avoid full rescans while retrying changed files and recovering pending migrations.
- Coordinate migration with live writers and emit metrics for manual and startup runs.

## Testing

- Cover startup cursor advancement and lookback, pending migration recovery, live-writer coordination, changed empty rollouts, and progress reporting.

GitOrigin-RevId: 276ac506c50ebec5140fd319faca1bb998172061
This commit is contained in:
Owen Lin
2026-08-07 01:26:42 +00:00
committed by copyberry
parent 69b6152c17
commit 4bb7ee3472
21 changed files with 1569 additions and 24 deletions
+13
View File
@@ -51,6 +51,7 @@ mod doctor;
mod exec_server_telemetry;
mod marketplace_cmd;
mod mcp_cmd;
mod migrate_rollouts;
mod plugin_cmd;
mod remote_control_cmd;
#[cfg(target_os = "windows")]
@@ -190,6 +191,9 @@ enum Subcommand {
/// Permanently delete a saved session by id or session name.
Delete(DeleteCommand),
/// Inspect or migrate legacy local sessions to paginated thread history.
MigrateRollouts(migrate_rollouts::MigrateRolloutsCommand),
/// Unarchive a saved session by id or session name.
Unarchive(SessionArchiveCommand),
@@ -1339,6 +1343,14 @@ async fn cli_main(
.await?;
println!("{output}");
}
Some(Subcommand::MigrateRollouts(command)) => {
reject_remote_mode_for_subcommand(
root_remote.as_deref(),
root_remote_auth_token_env.as_deref(),
"migrate-rollouts",
)?;
migrate_rollouts::run(command, root_config_overrides).await?;
}
Some(Subcommand::Unarchive(cmd)) => {
let output = run_session_archive_cli_command(
codex_tui::SessionArchiveAction::Unarchive,
@@ -2245,6 +2257,7 @@ fn unsupported_subcommand_name_for_strict_config(
Some(Subcommand::RemoteControl(remote_control)) => Some(remote_control.subcommand_name()),
Some(Subcommand::Mcp(_)) => Some("mcp"),
Some(Subcommand::Plugin(_)) => Some("plugin"),
Some(Subcommand::MigrateRollouts(_)) => Some("migrate-rollouts"),
#[cfg(any(target_os = "macos", target_os = "windows"))]
Some(Subcommand::App(_)) => Some("app"),
Some(Subcommand::Login(_)) => Some("login"),