agent_trace/commands/
violations.rs1use crate::observability::CliOutput;
2use crate::store::Store;
3use crate::types::Action;
4use anyhow::Result;
5use std::path::Path;
6
7pub fn run(store_root: &Path, limit: Option<usize>, output: &dyn CliOutput) -> Result<()> {
8 let store = Store::open(store_root)?;
9 let all = store.git.log(usize::MAX)?;
11 let violations: Vec<_> = all
12 .into_iter()
13 .filter(|e| matches!(e.action, Action::Violation))
14 .take(limit.unwrap_or(50))
15 .collect();
16
17 if violations.is_empty() {
18 output.line("No violations recorded.")?;
19 return Ok(());
20 }
21
22 output.line(&format!("{} violation(s):", violations.len()))?;
23 for v in &violations {
24 let time = v.timestamp.format("%Y-%m-%d %H:%M:%S");
25 let files_str = v
26 .files
27 .iter()
28 .map(|(p, _, _)| p.display().to_string())
29 .collect::<Vec<_>>()
30 .join(", ");
31 output.line(&format!(
32 " {} {} {} — {}",
33 time, v.actor, files_str, v.summary
34 ))?;
35 }
36 Ok(())
37}