lean_ctx/core/
verification_observability.rs1use serde::Serialize;
2use std::sync::atomic::{AtomicU64, Ordering};
3
4static SLO_EVALS: AtomicU64 = AtomicU64::new(0);
5
6#[derive(Debug, Clone, Serialize)]
7pub struct VerificationObservabilityV1 {
8 pub schema_version: u32,
9 pub created_at: String,
10 pub role: String,
11 pub profile: String,
12 pub budgets: crate::core::budget_tracker::BudgetSnapshot,
13 pub slo: crate::core::slo::SloSnapshot,
14 pub verification: crate::core::output_verification::VerificationSnapshot,
15 pub proof: crate::core::context_proof::ProofStatsSnapshot,
16 pub pipeline: crate::core::pipeline::PipelineStats,
17 pub counters: CountersSnapshot,
18}
19
20#[derive(Debug, Clone, Serialize)]
21pub struct CountersSnapshot {
22 pub slo_evals: u64,
23}
24
25pub fn record_slo_eval() {
26 SLO_EVALS.fetch_add(1, Ordering::Relaxed);
27}
28
29pub fn snapshot_v1() -> VerificationObservabilityV1 {
30 let created_at = chrono::Utc::now().to_rfc3339();
31 let role = crate::core::roles::active_role_name();
32 let profile = crate::core::profiles::active_profile_name();
33
34 let budgets = crate::core::budget_tracker::BudgetTracker::global().check();
35 let slo = crate::core::slo::evaluate_quiet();
36 let verification = crate::core::output_verification::stats_snapshot();
37 let proof = crate::core::context_proof::proof_stats_snapshot();
38 let pipeline = crate::core::pipeline::PipelineStats::load();
39
40 VerificationObservabilityV1 {
41 schema_version: crate::core::contracts::VERIFICATION_OBSERVABILITY_V1_SCHEMA_VERSION,
42 created_at,
43 role,
44 profile,
45 budgets,
46 slo,
47 verification,
48 proof,
49 pipeline,
50 counters: CountersSnapshot {
51 slo_evals: SLO_EVALS.load(Ordering::Relaxed),
52 },
53 }
54}
55
56pub fn format_compact(v: &VerificationObservabilityV1) -> String {
57 let proof_last = v
58 .proof
59 .last_written_at
60 .clone()
61 .unwrap_or_else(|| "-".to_string());
62 format!(
63 "{}\n{}\n{}\nProof: written={} last={proof_last}",
64 v.verification.format_compact(),
65 v.slo.format_compact(),
66 v.budgets.format_compact(),
67 v.proof.written
68 )
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn snapshot_has_schema_version() {
77 let s = snapshot_v1();
78 assert_eq!(s.schema_version, 1);
79 assert!(s.created_at.contains('T'));
80 let compact = format_compact(&s);
81 assert!(compact.contains("Verification:"));
82 assert!(compact.contains("Proof: written="));
83 }
84}