[codex] Restore thread recency with compatible migration history (#28671)

## Summary

- Revert #28655, restoring the thread `recencyAt` behavior introduced by
#27910.
- Move `threads_recency_at` to migration 0039 so it no longer collides
with `external_agent_config_imports` at version 0038.
- Repair databases that already applied the recency migration as version
38 by moving the matching migration-history row to version 39 before
SQLx validation. The current version-38 migration can then apply
normally.

## Validation

- `just test -p codex-state
migrations::tests::repairs_recency_migration_that_was_applied_as_version_38`
- `just test -p codex-state -p codex-rollout -p codex-thread-store -p
codex-app-server-protocol -p codex-tui`: 3,439 passed; six TUI tests
could not open the machine's existing read-only incident database at
`~/.codex/sqlite/state_5.sqlite`.
- `just fix -p codex-state`
- `just fmt`
- Verified that state migration versions are unique.
This commit is contained in:
Jeremy Rose authored and GitHub committed 2026-06-17 18:52:18 +00:00
1 parent d9e0551564
commit 7dc7096ae1
67 files changed
+1274 -100

No files matched your search

+6 -1
View File
@@ -290,7 +290,10 @@ fn cursor_to_anchor(cursor: Option<&Cursor>) -> Option<codex_state::Anchor> {
let millis = cursor.timestamp().unix_timestamp_nanos() / 1_000_000;
let millis = i64::try_from(millis).ok()?;
let ts = chrono::DateTime::<Utc>::from_timestamp_millis(millis)?;
Some(codex_state::Anchor { ts })
Some(codex_state::Anchor {
ts,
id: cursor.thread_id(),
})
}
pub fn normalize_cwd_for_state_db(cwd: &Path) -> PathBuf {
@@ -336,6 +339,7 @@ pub async fn list_thread_ids_db(
match sort_key {
ThreadSortKey::CreatedAt => codex_state::SortKey::CreatedAt,
ThreadSortKey::UpdatedAt => codex_state::SortKey::UpdatedAt,
ThreadSortKey::RecencyAt => codex_state::SortKey::RecencyAt,
},
allowed_sources.as_slice(),
model_providers.as_deref(),
@@ -401,6 +405,7 @@ pub async fn list_threads_db(
sort_key: match sort_key {
ThreadSortKey::CreatedAt => codex_state::SortKey::CreatedAt,
ThreadSortKey::UpdatedAt => codex_state::SortKey::UpdatedAt,
ThreadSortKey::RecencyAt => codex_state::SortKey::RecencyAt,
},
sort_direction: match sort_direction {
SortDirection::Asc => codex_state::SortDirection::Asc,