pushkin 0.2.1

Schema-first enforcement harness that gates AI coding agents' file writes against project contracts
//! `pushkin stats`: the local observability floor (spec §14, addendum
//! §8) — blocks by rule, compression savings, nudge arms, fail-opens.
//! Local events only; nothing leaves this machine.

use anyhow::Result;
use pushkin_core::events::EventLog;

use super::events_db_path;

pub fn run() -> Result<i32> {
    let log = EventLog::open(events_db_path()?)?;
    let summary = log.stats()?;

    println!("pushkin stats (local events only)");
    println!("Blocks by rule:");
    if summary.blocks_by_rule.is_empty() {
        println!("  (none)");
    }
    for (rule, count) in &summary.blocks_by_rule {
        println!("  {rule}: {count}");
    }
    println!(
        "Compression: {} pointer emissions, {} chars saved",
        summary.compression_events, summary.compression_saved_chars
    );
    if summary.nudge_arms.is_empty() {
        println!("Nudges: (none)");
    } else {
        let arms: Vec<String> = summary
            .nudge_arms
            .iter()
            .map(|(arm, count)| format!("{arm} {count}"))
            .collect();
        println!("Nudges: {}", arms.join(" / "));
    }
    println!("Fail-opens: {}", summary.failopen_events);
    Ok(0)
}