lift_inspection_flow/
lift_inspection_flow.rs1use ed25519_dalek::SigningKey;
2use immutable_trace::{
3 build_signed_record, AuditRecord, InMemoryAuditLedger, InMemoryOperationLog,
4 InMemoryRawDataStore, IngestService, IngestState,
5};
6
7fn main() {
8 let device_id = "lift-01";
9 let signing_key = SigningKey::from_bytes(&[1u8; 32]);
10 let verifying_key = signing_key.verifying_key();
11
12 let mut service = IngestService::new(
13 IngestState::default(),
14 InMemoryRawDataStore::default(),
15 InMemoryAuditLedger::default(),
16 InMemoryOperationLog::default(),
17 );
18 service.register_device(device_id, verifying_key);
19
20 let payloads = [
21 b"check=door,status=ok" as &[u8],
22 b"check=vibration,status=ok",
23 b"check=emergency_brake,status=ok",
24 ];
25
26 let mut prev_hash = AuditRecord::zero_hash();
27 let mut records = Vec::new();
28
29 for (index, payload) in payloads.iter().enumerate() {
30 let sequence = (index as u64) + 1;
31 let record = build_signed_record(
32 device_id,
33 sequence,
34 1_700_000_000_000 + sequence,
35 payload,
36 prev_hash,
37 format!("s3://bucket/{device_id}/inspection-{sequence}.bin"),
38 &signing_key,
39 );
40 prev_hash = record.hash();
41 records.push(record);
42 }
43
44 for record in &records {
45 service
46 .ingest(record.clone(), payloads[record.sequence as usize - 1])
47 .expect("ingest should succeed");
48 }
49
50 println!("Stored {} audit records", service.audit_ledger().records().len());
51
52 let tampered_payload = b"tampered";
53 let tampered_record = build_signed_record(
54 device_id,
55 4,
56 1_700_000_000_004,
57 tampered_payload,
58 prev_hash,
59 "s3://bucket/lift-01/inspection-4.bin",
60 &signing_key,
61 );
62 let mut tampered = tampered_record;
63 tampered.payload_hash[0] ^= 0x01;
64
65 let result = service.ingest(tampered, tampered_payload);
66 assert!(result.is_err(), "tampered record should be rejected");
67 println!("Tampered record rejected: {:?}", result.unwrap_err());
68
69 println!("Operation log entries: {}", service.operation_log().entries().len());
70 for entry in service.operation_log().entries() {
71 println!(" {:?} device={} seq={} msg={}", entry.decision, entry.device_id, entry.sequence, entry.message);
72 }
73}