Gate paginated thread history on the state database (#35787)

## Why

Local thread stores without an initialized state database should not implicitly
create SQLite files or partially delete threads that have materialized history.

## What changed

- Report paginated history listing as unsupported when no state database is
  available, and skip history projection and materialization in that mode.
- Reject paginated forks without a state database.
- Validate access to materialized history before deleting rollout files, so a
  failed deletion preserves both the rollout and its history rows.

## Testing

Added coverage that a store without a state database creates no SQLite files
and preserves materialized history when deletion is unsupported. Existing
projection tests now initialize the state runtime explicitly.

GitOrigin-RevId: 2eaa0f5f0de8d5e4d84375ec50b310746a0ee68e
This commit is contained in:
Owen Lin authored and copyberry committed 2026-07-28 16:00:39 +00:00
1 parent cf7e9cfe6a
commit fa1d4c40d0
6 files changed
+168 -29

No files matched your search

+6 -1
View File
@@ -207,6 +207,11 @@ impl LocalThreadStore {
}
async fn thread_history_db(&self) -> ThreadStoreResult<&sqlx::SqlitePool> {
if self.state_db.is_none() {
return Err(ThreadStoreError::Unsupported {
operation: "paginated_history",
});
}
self.thread_history_db
.get_or_try_init(|| async {
codex_state::open_thread_history_db(&self.config.sqlite).await
@@ -452,7 +457,7 @@ impl ThreadStore for LocalThreadStore {
}
fn supports_paginated_history_lists(&self) -> bool {
true
self.state_db.is_some()
}
fn list_turns(&self, params: ListTurnsParams) -> ThreadStoreFuture<'_, TurnPage> {