gen_audit_cli/
gen_audit_cli.rs1use chrono::Utc;
5use std::fs::File;
6use std::io::Write;
7use uuid::Uuid;
8use vex_core::{AuditEvent, AuditEventType, Hash, MerkleTree};
9use vex_persist::audit_store::AuditExport;
10
11fn main() -> Result<(), Box<dyn std::error::Error>> {
12 let agent_id = Uuid::new_v4();
13
14 let e1 = AuditEvent::new(
16 AuditEventType::AgentCreated,
17 Some(agent_id),
18 serde_json::json!({"role": "Root Agent", "model": "deepseek-chat"}),
19 0,
20 );
21
22 let e2 = AuditEvent::chained(
24 AuditEventType::AgentExecuted,
25 Some(agent_id),
26 serde_json::json!({"prompt": "What is the meaning of life?", "confidence": 0.95}),
27 e1.hash.clone(),
28 1,
29 );
30
31 let e3 = AuditEvent::chained(
33 AuditEventType::AgentExecuted,
34 Some(agent_id),
35 serde_json::json!({"prompt": "Follow-up question", "confidence": 0.87}),
36 e2.hash.clone(),
37 2,
38 );
39
40 let events = vec![e1.clone(), e2.clone(), e3.clone()];
41
42 let leaves: Vec<(String, Hash)> = events
44 .iter()
45 .map(|e| (e.id.to_string(), e.hash.clone()))
46 .collect();
47 let tree = MerkleTree::from_leaves(leaves);
48
49 let export = AuditExport {
50 events: events.clone(),
51 merkle_root: tree.root_hash().map(|h| h.to_string()),
52 exported_at: Utc::now(),
53 verified: true,
54 };
55
56 let valid_json = serde_json::to_string_pretty(&export)?;
58 let mut file = File::create("audit_valid.json")?;
59 file.write_all(valid_json.as_bytes())?;
60 println!("✓ Generated audit_valid.json (3 events)");
61
62 let mut tampered_export = export.clone();
64 tampered_export.events[1].data = serde_json::json!({"prompt": "TAMPERED DATA"});
65 let tampered_json = serde_json::to_string_pretty(&tampered_export)?;
68 let mut file = File::create("audit_tampered.json")?;
69 file.write_all(tampered_json.as_bytes())?;
70 println!("✓ Generated audit_tampered.json (data tampered)");
71
72 let mut tampered_root_export = export.clone();
74 tampered_root_export.merkle_root = Some("fake_root_abc123".to_string());
75
76 let tampered_root_json = serde_json::to_string_pretty(&tampered_root_export)?;
77 let mut file = File::create("audit_tampered_root.json")?;
78 file.write_all(tampered_root_json.as_bytes())?;
79 println!("✓ Generated audit_tampered_root.json (root tampered)");
80
81 println!("\nTest with:");
82 println!(" vex verify -a audit_valid.json # Should pass");
83 println!(" vex verify -a audit_tampered.json # Should fail (hash mismatch)");
84 println!(" vex verify -a audit_tampered_root.json # Should fail (root mismatch)");
85
86 Ok(())
87}