Files
codex/codex-rs/state/src/audit.rs
T
Adam Perry @ OpenAI c769a05340 Honor the configured SQLite home across state consumers (#34994)
## Why

Codex and SQLite data can use separate home directories, but state consumers
could reconstruct database paths from the Codex home instead of consistently
using the resolved SQLite configuration.

## What changed

- Pass `SqliteConfig` through the core, rollout, state runtime, and thread store
  instead of passing a directory and rebuilding the configuration downstream.
- Use that shared configuration for state, logs, memories, goals, and paginated
  thread-history database access, including integrity checks and cleanup.
- Reject state database handles whose SQLite configuration does not match the
  requesting store.

## Testing

Add coverage with separate Codex and SQLite homes that verifies startup
backfill, thread listing, and paginated history all use the configured SQLite
directory.

GitOrigin-RevId: 1de1cdd1d6ff1d70bbb6c360c8352e6543fb8ebf
2026-07-23 19:19:35 +00:00

47 lines
1.3 KiB
Rust

//! Read-only state database queries for diagnostics.
use anyhow::Result;
use sqlx::Row;
use std::path::PathBuf;
use crate::SqliteConfig;
/// Minimal thread metadata used by read-only state database audits.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ThreadStateAuditRow {
pub id: String,
pub rollout_path: PathBuf,
pub archived: bool,
pub source: String,
pub model_provider: String,
}
/// Read persisted thread rows from a state DB without creating, migrating, or repairing it.
pub async fn read_thread_state_audit_rows(
sqlite: &SqliteConfig,
) -> Result<Vec<ThreadStateAuditRow>> {
let pool = sqlite.open_read_only_pool(&sqlite.state_db_path()).await?;
let rows = sqlx::query(
r#"
SELECT id, rollout_path, archived, source, model_provider
FROM threads
"#,
)
.fetch_all(&pool)
.await?;
pool.close().await;
rows.into_iter()
.map(|row| {
let archived: i64 = row.try_get("archived")?;
Ok(ThreadStateAuditRow {
id: row.try_get("id")?,
rollout_path: PathBuf::from(row.try_get::<String, _>("rollout_path")?),
archived: archived != 0,
source: row.try_get("source")?,
model_provider: row.try_get("model_provider")?,
})
})
.collect()
}