Files
codex/codex-rs/state/src/audit.rs
T
chess 32ce703a80 Bound SQLite integrity checks for diagnostic attachments (#40688)
## Why

Diagnostic uploads skip the doctor attachment if report generation exceeds its
overall timeout. SQLite integrity scans can be delayed by large databases or
lock contention.

## What changed

- Give each database integrity scan a one-second deadline when collecting a
  diagnostic attachment.
- Interrupt scans and lock waits at the deadline, preserve any corruption rows
  already returned, and report an incomplete clean scan as a warning.
- Keep direct `codex doctor` integrity checks unbounded.

## Testing

- Cover interrupted scans, lock waits, retries without a deadline, and
  corruption results returned before interruption.

GitOrigin-RevId: 4817fb459ac53953669a9ba5f03397a6fc82c72e
2026-08-25 20:09:55 +00:00

49 lines
1.4 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(), /*busy_timeout*/ None)
.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()
}