pub mod candidates;
pub mod log_index;
pub mod render;
pub mod signals;
use anyhow::{Context, Result};
use log_index::InjectionIndex;
const DEFAULT_LIMIT: usize = 25;
#[derive(Debug, Clone, Default)]
pub struct ReportOptions {
pub palace: Option<String>,
pub limit: Option<usize>,
pub min_injections: u64,
pub json: bool,
pub logs_dir: Option<std::path::PathBuf>,
}
pub async fn handle_backfill_report(opts: ReportOptions) -> Result<()> {
let data_dir = trusty_common::resolve_data_dir("trusty-memory")
.context("resolve trusty-memory data dir")?;
let logs_dir = opts
.logs_dir
.clone()
.unwrap_or_else(|| data_dir.join("logs"));
let registry_dir = crate::resolve_palace_registry_dir(data_dir);
let index = InjectionIndex::scan_dir(&logs_dir)
.with_context(|| format!("scan prompt logs in {}", logs_dir.display()))?;
if index.saw_no_logs() {
eprintln!(
"warning: no enriched-prompts.*.jsonl found in {} — injection counts \
will all be 0. This is missing data, not an absence of stale drawers.",
logs_dir.display()
);
}
let census = candidates::build_census(
®istry_dir,
&index,
opts.palace.as_deref(),
opts.min_injections,
)?;
let limit = opts.limit.unwrap_or(DEFAULT_LIMIT);
let stdout = std::io::stdout();
let mut out = stdout.lock();
if opts.json {
render::render_json(&mut out, &census, &index.stats, limit)
} else {
render::render_text(&mut out, &census, &index.stats, limit)
}
}
#[cfg(test)]
#[path = "tests.rs"]
mod tests;