Skip to main content

TransparencyLog

Struct TransparencyLog 

Source
pub struct TransparencyLog { /* private fields */ }
Expand description

Transparency statistics for the current session.

Implementations§

Source§

impl TransparencyLog

Source

pub fn new() -> Self

Create a new transparency log.

Examples found in repository?
examples/capture_demo.rs (line 60)
26fn main() {
27    println!("Synheart Sensor Agent - Capture Demo");
28    println!("=====================================");
29    println!();
30
31    // Display privacy declaration
32    println!("{PRIVACY_DECLARATION}");
33    println!();
34
35    // Check for permission
36    print!("Checking Input Monitoring permission... ");
37    if check_permission() {
38        println!("OK ✓");
39    } else {
40        println!("FAILED ✗");
41        println!();
42        println!("Please grant Input Monitoring permission:");
43        println!("1. Open System Preferences");
44        println!("2. Go to Security & Privacy > Privacy > Input Monitoring");
45        println!("3. Add this application");
46        println!("4. Restart this demo");
47        return;
48    }
49    println!();
50
51    // Create components
52    let config = CollectorConfig {
53        capture_keyboard: true,
54        capture_mouse: true,
55    };
56
57    let mut collector = Collector::new(config);
58    let mut window_manager = WindowManager::new(10, 300); // 10s windows, 5min session gap
59    let hsi_builder = HsiBuilder::new();
60    let transparency_log = TransparencyLog::new();
61
62    println!("Instance ID: {}", hsi_builder.instance_id());
63    println!();
64    println!("Starting capture for 30 seconds...");
65    println!("Try typing and moving your mouse!");
66    println!();
67
68    // Start collection
69    if let Err(e) = collector.start() {
70        eprintln!("Error starting collector: {e}");
71        return;
72    }
73
74    // Set up stop flag
75    let running = Arc::new(AtomicBool::new(true));
76    let r = running.clone();
77
78    // Set up Ctrl+C handler
79    ctrlc::set_handler(move || {
80        r.store(false, Ordering::SeqCst);
81    })
82    .expect("Error setting Ctrl+C handler");
83
84    // Run for 30 seconds
85    let start = std::time::Instant::now();
86    let receiver = collector.receiver().clone();
87    let mut event_count = 0;
88
89    while running.load(Ordering::SeqCst) && start.elapsed() < Duration::from_secs(30) {
90        // Receive events with timeout
91        match receiver.recv_timeout(Duration::from_millis(100)) {
92            Ok(event) => {
93                event_count += 1;
94
95                // Log event type
96                match &event {
97                    SensorEvent::Keyboard(e) => {
98                        transparency_log.record_keyboard_event();
99                        if event_count <= 10 || event_count % 50 == 0 {
100                            println!(
101                                "  Keyboard event: {} at {}",
102                                if e.is_key_down { "down" } else { "up" },
103                                e.timestamp.format("%H:%M:%S%.3f")
104                            );
105                        }
106                    }
107                    SensorEvent::Mouse(e) => {
108                        transparency_log.record_mouse_event();
109                        if event_count <= 10 || event_count % 100 == 0 {
110                            println!(
111                                "  Mouse event: {:?} at {}",
112                                e.event_type,
113                                e.timestamp.format("%H:%M:%S%.3f")
114                            );
115                        }
116                    }
117                    SensorEvent::Shortcut(e) => {
118                        transparency_log.record_shortcut_event();
119                        if event_count <= 10 || event_count % 50 == 0 {
120                            println!(
121                                "  Shortcut event: {:?} at {}",
122                                e.shortcut_type,
123                                e.timestamp.format("%H:%M:%S%.3f")
124                            );
125                        }
126                    }
127                }
128
129                // Process in window manager
130                window_manager.process_event(event);
131            }
132            Err(crossbeam_channel::RecvTimeoutError::Timeout) => {
133                // Check for window expiry
134                window_manager.check_window_expiry();
135            }
136            Err(crossbeam_channel::RecvTimeoutError::Disconnected) => {
137                break;
138            }
139        }
140
141        // Process completed windows
142        for window in window_manager.take_completed_windows() {
143            transparency_log.record_window_completed();
144
145            let features = compute_features(&window);
146            let snapshot = hsi_builder.build(&window, &features);
147
148            println!();
149            println!("=== Window Completed ===");
150            println!("  Duration: {:.1}s", window.duration_secs());
151            println!("  Keyboard events: {}", window.keyboard_events.len());
152            println!("  Mouse events: {}", window.mouse_events.len());
153            println!();
154            println!("  Keyboard Features:");
155            println!(
156                "    Typing rate: {:.2} keys/sec",
157                features.keyboard.typing_rate
158            );
159            println!("    Pause count: {}", features.keyboard.pause_count);
160            println!("    Burst index: {:.3}", features.keyboard.burst_index);
161            println!();
162            println!("  Mouse Features:");
163            println!(
164                "    Activity rate: {:.2} moves/sec",
165                features.mouse.mouse_activity_rate
166            );
167            println!("    Mean velocity: {:.2}", features.mouse.mean_velocity);
168            println!(
169                "    Click rate: {:.2} clicks/sec",
170                features.mouse.click_rate
171            );
172            println!();
173            println!("  Behavioral Signals:");
174            println!(
175                "    Interaction rhythm: {:.3}",
176                features.behavioral.interaction_rhythm
177            );
178            println!("    Friction: {:.3}", features.behavioral.friction);
179            println!(
180                "    Motor stability: {:.3}",
181                features.behavioral.motor_stability
182            );
183            println!(
184                "    Focus continuity: {:.3}",
185                features.behavioral.focus_continuity_proxy
186            );
187            println!();
188
189            // Show snippet of HSI JSON
190            let json = serde_json::to_string_pretty(&snapshot).unwrap();
191            println!("  HSI Snapshot (truncated):");
192            for line in json.lines().take(20) {
193                println!("    {line}");
194            }
195            println!("    ...");
196            println!();
197        }
198
199        // Show progress
200        if event_count > 0 && event_count % 200 == 0 {
201            let elapsed = start.elapsed().as_secs();
202            println!("  [{elapsed}/30s] Processed {event_count} events...");
203        }
204    }
205
206    // Stop collection
207    println!();
208    println!("Stopping capture...");
209    collector.stop();
210
211    // Flush remaining window
212    window_manager.flush();
213    for window in window_manager.take_completed_windows() {
214        println!("Final window: {} events", window.event_count());
215        transparency_log.record_window_completed();
216    }
217
218    // Final statistics
219    println!();
220    println!("{}", transparency_log.summary());
221    println!();
222    println!("Demo complete!");
223}
Source

pub fn with_persistence(path: PathBuf) -> Self

Create a transparency log with persistence.

Source

pub fn record_keyboard_event(&self)

Record a keyboard event.

Examples found in repository?
examples/capture_demo.rs (line 98)
26fn main() {
27    println!("Synheart Sensor Agent - Capture Demo");
28    println!("=====================================");
29    println!();
30
31    // Display privacy declaration
32    println!("{PRIVACY_DECLARATION}");
33    println!();
34
35    // Check for permission
36    print!("Checking Input Monitoring permission... ");
37    if check_permission() {
38        println!("OK ✓");
39    } else {
40        println!("FAILED ✗");
41        println!();
42        println!("Please grant Input Monitoring permission:");
43        println!("1. Open System Preferences");
44        println!("2. Go to Security & Privacy > Privacy > Input Monitoring");
45        println!("3. Add this application");
46        println!("4. Restart this demo");
47        return;
48    }
49    println!();
50
51    // Create components
52    let config = CollectorConfig {
53        capture_keyboard: true,
54        capture_mouse: true,
55    };
56
57    let mut collector = Collector::new(config);
58    let mut window_manager = WindowManager::new(10, 300); // 10s windows, 5min session gap
59    let hsi_builder = HsiBuilder::new();
60    let transparency_log = TransparencyLog::new();
61
62    println!("Instance ID: {}", hsi_builder.instance_id());
63    println!();
64    println!("Starting capture for 30 seconds...");
65    println!("Try typing and moving your mouse!");
66    println!();
67
68    // Start collection
69    if let Err(e) = collector.start() {
70        eprintln!("Error starting collector: {e}");
71        return;
72    }
73
74    // Set up stop flag
75    let running = Arc::new(AtomicBool::new(true));
76    let r = running.clone();
77
78    // Set up Ctrl+C handler
79    ctrlc::set_handler(move || {
80        r.store(false, Ordering::SeqCst);
81    })
82    .expect("Error setting Ctrl+C handler");
83
84    // Run for 30 seconds
85    let start = std::time::Instant::now();
86    let receiver = collector.receiver().clone();
87    let mut event_count = 0;
88
89    while running.load(Ordering::SeqCst) && start.elapsed() < Duration::from_secs(30) {
90        // Receive events with timeout
91        match receiver.recv_timeout(Duration::from_millis(100)) {
92            Ok(event) => {
93                event_count += 1;
94
95                // Log event type
96                match &event {
97                    SensorEvent::Keyboard(e) => {
98                        transparency_log.record_keyboard_event();
99                        if event_count <= 10 || event_count % 50 == 0 {
100                            println!(
101                                "  Keyboard event: {} at {}",
102                                if e.is_key_down { "down" } else { "up" },
103                                e.timestamp.format("%H:%M:%S%.3f")
104                            );
105                        }
106                    }
107                    SensorEvent::Mouse(e) => {
108                        transparency_log.record_mouse_event();
109                        if event_count <= 10 || event_count % 100 == 0 {
110                            println!(
111                                "  Mouse event: {:?} at {}",
112                                e.event_type,
113                                e.timestamp.format("%H:%M:%S%.3f")
114                            );
115                        }
116                    }
117                    SensorEvent::Shortcut(e) => {
118                        transparency_log.record_shortcut_event();
119                        if event_count <= 10 || event_count % 50 == 0 {
120                            println!(
121                                "  Shortcut event: {:?} at {}",
122                                e.shortcut_type,
123                                e.timestamp.format("%H:%M:%S%.3f")
124                            );
125                        }
126                    }
127                }
128
129                // Process in window manager
130                window_manager.process_event(event);
131            }
132            Err(crossbeam_channel::RecvTimeoutError::Timeout) => {
133                // Check for window expiry
134                window_manager.check_window_expiry();
135            }
136            Err(crossbeam_channel::RecvTimeoutError::Disconnected) => {
137                break;
138            }
139        }
140
141        // Process completed windows
142        for window in window_manager.take_completed_windows() {
143            transparency_log.record_window_completed();
144
145            let features = compute_features(&window);
146            let snapshot = hsi_builder.build(&window, &features);
147
148            println!();
149            println!("=== Window Completed ===");
150            println!("  Duration: {:.1}s", window.duration_secs());
151            println!("  Keyboard events: {}", window.keyboard_events.len());
152            println!("  Mouse events: {}", window.mouse_events.len());
153            println!();
154            println!("  Keyboard Features:");
155            println!(
156                "    Typing rate: {:.2} keys/sec",
157                features.keyboard.typing_rate
158            );
159            println!("    Pause count: {}", features.keyboard.pause_count);
160            println!("    Burst index: {:.3}", features.keyboard.burst_index);
161            println!();
162            println!("  Mouse Features:");
163            println!(
164                "    Activity rate: {:.2} moves/sec",
165                features.mouse.mouse_activity_rate
166            );
167            println!("    Mean velocity: {:.2}", features.mouse.mean_velocity);
168            println!(
169                "    Click rate: {:.2} clicks/sec",
170                features.mouse.click_rate
171            );
172            println!();
173            println!("  Behavioral Signals:");
174            println!(
175                "    Interaction rhythm: {:.3}",
176                features.behavioral.interaction_rhythm
177            );
178            println!("    Friction: {:.3}", features.behavioral.friction);
179            println!(
180                "    Motor stability: {:.3}",
181                features.behavioral.motor_stability
182            );
183            println!(
184                "    Focus continuity: {:.3}",
185                features.behavioral.focus_continuity_proxy
186            );
187            println!();
188
189            // Show snippet of HSI JSON
190            let json = serde_json::to_string_pretty(&snapshot).unwrap();
191            println!("  HSI Snapshot (truncated):");
192            for line in json.lines().take(20) {
193                println!("    {line}");
194            }
195            println!("    ...");
196            println!();
197        }
198
199        // Show progress
200        if event_count > 0 && event_count % 200 == 0 {
201            let elapsed = start.elapsed().as_secs();
202            println!("  [{elapsed}/30s] Processed {event_count} events...");
203        }
204    }
205
206    // Stop collection
207    println!();
208    println!("Stopping capture...");
209    collector.stop();
210
211    // Flush remaining window
212    window_manager.flush();
213    for window in window_manager.take_completed_windows() {
214        println!("Final window: {} events", window.event_count());
215        transparency_log.record_window_completed();
216    }
217
218    // Final statistics
219    println!();
220    println!("{}", transparency_log.summary());
221    println!();
222    println!("Demo complete!");
223}
Source

pub fn record_keyboard_events(&self, count: u64)

Record multiple keyboard events.

Source

pub fn record_mouse_event(&self)

Record a mouse event.

Examples found in repository?
examples/capture_demo.rs (line 108)
26fn main() {
27    println!("Synheart Sensor Agent - Capture Demo");
28    println!("=====================================");
29    println!();
30
31    // Display privacy declaration
32    println!("{PRIVACY_DECLARATION}");
33    println!();
34
35    // Check for permission
36    print!("Checking Input Monitoring permission... ");
37    if check_permission() {
38        println!("OK ✓");
39    } else {
40        println!("FAILED ✗");
41        println!();
42        println!("Please grant Input Monitoring permission:");
43        println!("1. Open System Preferences");
44        println!("2. Go to Security & Privacy > Privacy > Input Monitoring");
45        println!("3. Add this application");
46        println!("4. Restart this demo");
47        return;
48    }
49    println!();
50
51    // Create components
52    let config = CollectorConfig {
53        capture_keyboard: true,
54        capture_mouse: true,
55    };
56
57    let mut collector = Collector::new(config);
58    let mut window_manager = WindowManager::new(10, 300); // 10s windows, 5min session gap
59    let hsi_builder = HsiBuilder::new();
60    let transparency_log = TransparencyLog::new();
61
62    println!("Instance ID: {}", hsi_builder.instance_id());
63    println!();
64    println!("Starting capture for 30 seconds...");
65    println!("Try typing and moving your mouse!");
66    println!();
67
68    // Start collection
69    if let Err(e) = collector.start() {
70        eprintln!("Error starting collector: {e}");
71        return;
72    }
73
74    // Set up stop flag
75    let running = Arc::new(AtomicBool::new(true));
76    let r = running.clone();
77
78    // Set up Ctrl+C handler
79    ctrlc::set_handler(move || {
80        r.store(false, Ordering::SeqCst);
81    })
82    .expect("Error setting Ctrl+C handler");
83
84    // Run for 30 seconds
85    let start = std::time::Instant::now();
86    let receiver = collector.receiver().clone();
87    let mut event_count = 0;
88
89    while running.load(Ordering::SeqCst) && start.elapsed() < Duration::from_secs(30) {
90        // Receive events with timeout
91        match receiver.recv_timeout(Duration::from_millis(100)) {
92            Ok(event) => {
93                event_count += 1;
94
95                // Log event type
96                match &event {
97                    SensorEvent::Keyboard(e) => {
98                        transparency_log.record_keyboard_event();
99                        if event_count <= 10 || event_count % 50 == 0 {
100                            println!(
101                                "  Keyboard event: {} at {}",
102                                if e.is_key_down { "down" } else { "up" },
103                                e.timestamp.format("%H:%M:%S%.3f")
104                            );
105                        }
106                    }
107                    SensorEvent::Mouse(e) => {
108                        transparency_log.record_mouse_event();
109                        if event_count <= 10 || event_count % 100 == 0 {
110                            println!(
111                                "  Mouse event: {:?} at {}",
112                                e.event_type,
113                                e.timestamp.format("%H:%M:%S%.3f")
114                            );
115                        }
116                    }
117                    SensorEvent::Shortcut(e) => {
118                        transparency_log.record_shortcut_event();
119                        if event_count <= 10 || event_count % 50 == 0 {
120                            println!(
121                                "  Shortcut event: {:?} at {}",
122                                e.shortcut_type,
123                                e.timestamp.format("%H:%M:%S%.3f")
124                            );
125                        }
126                    }
127                }
128
129                // Process in window manager
130                window_manager.process_event(event);
131            }
132            Err(crossbeam_channel::RecvTimeoutError::Timeout) => {
133                // Check for window expiry
134                window_manager.check_window_expiry();
135            }
136            Err(crossbeam_channel::RecvTimeoutError::Disconnected) => {
137                break;
138            }
139        }
140
141        // Process completed windows
142        for window in window_manager.take_completed_windows() {
143            transparency_log.record_window_completed();
144
145            let features = compute_features(&window);
146            let snapshot = hsi_builder.build(&window, &features);
147
148            println!();
149            println!("=== Window Completed ===");
150            println!("  Duration: {:.1}s", window.duration_secs());
151            println!("  Keyboard events: {}", window.keyboard_events.len());
152            println!("  Mouse events: {}", window.mouse_events.len());
153            println!();
154            println!("  Keyboard Features:");
155            println!(
156                "    Typing rate: {:.2} keys/sec",
157                features.keyboard.typing_rate
158            );
159            println!("    Pause count: {}", features.keyboard.pause_count);
160            println!("    Burst index: {:.3}", features.keyboard.burst_index);
161            println!();
162            println!("  Mouse Features:");
163            println!(
164                "    Activity rate: {:.2} moves/sec",
165                features.mouse.mouse_activity_rate
166            );
167            println!("    Mean velocity: {:.2}", features.mouse.mean_velocity);
168            println!(
169                "    Click rate: {:.2} clicks/sec",
170                features.mouse.click_rate
171            );
172            println!();
173            println!("  Behavioral Signals:");
174            println!(
175                "    Interaction rhythm: {:.3}",
176                features.behavioral.interaction_rhythm
177            );
178            println!("    Friction: {:.3}", features.behavioral.friction);
179            println!(
180                "    Motor stability: {:.3}",
181                features.behavioral.motor_stability
182            );
183            println!(
184                "    Focus continuity: {:.3}",
185                features.behavioral.focus_continuity_proxy
186            );
187            println!();
188
189            // Show snippet of HSI JSON
190            let json = serde_json::to_string_pretty(&snapshot).unwrap();
191            println!("  HSI Snapshot (truncated):");
192            for line in json.lines().take(20) {
193                println!("    {line}");
194            }
195            println!("    ...");
196            println!();
197        }
198
199        // Show progress
200        if event_count > 0 && event_count % 200 == 0 {
201            let elapsed = start.elapsed().as_secs();
202            println!("  [{elapsed}/30s] Processed {event_count} events...");
203        }
204    }
205
206    // Stop collection
207    println!();
208    println!("Stopping capture...");
209    collector.stop();
210
211    // Flush remaining window
212    window_manager.flush();
213    for window in window_manager.take_completed_windows() {
214        println!("Final window: {} events", window.event_count());
215        transparency_log.record_window_completed();
216    }
217
218    // Final statistics
219    println!();
220    println!("{}", transparency_log.summary());
221    println!();
222    println!("Demo complete!");
223}
Source

pub fn record_mouse_events(&self, count: u64)

Record multiple mouse events.

Source

pub fn record_shortcut_event(&self)

Record a shortcut event.

Examples found in repository?
examples/capture_demo.rs (line 118)
26fn main() {
27    println!("Synheart Sensor Agent - Capture Demo");
28    println!("=====================================");
29    println!();
30
31    // Display privacy declaration
32    println!("{PRIVACY_DECLARATION}");
33    println!();
34
35    // Check for permission
36    print!("Checking Input Monitoring permission... ");
37    if check_permission() {
38        println!("OK ✓");
39    } else {
40        println!("FAILED ✗");
41        println!();
42        println!("Please grant Input Monitoring permission:");
43        println!("1. Open System Preferences");
44        println!("2. Go to Security & Privacy > Privacy > Input Monitoring");
45        println!("3. Add this application");
46        println!("4. Restart this demo");
47        return;
48    }
49    println!();
50
51    // Create components
52    let config = CollectorConfig {
53        capture_keyboard: true,
54        capture_mouse: true,
55    };
56
57    let mut collector = Collector::new(config);
58    let mut window_manager = WindowManager::new(10, 300); // 10s windows, 5min session gap
59    let hsi_builder = HsiBuilder::new();
60    let transparency_log = TransparencyLog::new();
61
62    println!("Instance ID: {}", hsi_builder.instance_id());
63    println!();
64    println!("Starting capture for 30 seconds...");
65    println!("Try typing and moving your mouse!");
66    println!();
67
68    // Start collection
69    if let Err(e) = collector.start() {
70        eprintln!("Error starting collector: {e}");
71        return;
72    }
73
74    // Set up stop flag
75    let running = Arc::new(AtomicBool::new(true));
76    let r = running.clone();
77
78    // Set up Ctrl+C handler
79    ctrlc::set_handler(move || {
80        r.store(false, Ordering::SeqCst);
81    })
82    .expect("Error setting Ctrl+C handler");
83
84    // Run for 30 seconds
85    let start = std::time::Instant::now();
86    let receiver = collector.receiver().clone();
87    let mut event_count = 0;
88
89    while running.load(Ordering::SeqCst) && start.elapsed() < Duration::from_secs(30) {
90        // Receive events with timeout
91        match receiver.recv_timeout(Duration::from_millis(100)) {
92            Ok(event) => {
93                event_count += 1;
94
95                // Log event type
96                match &event {
97                    SensorEvent::Keyboard(e) => {
98                        transparency_log.record_keyboard_event();
99                        if event_count <= 10 || event_count % 50 == 0 {
100                            println!(
101                                "  Keyboard event: {} at {}",
102                                if e.is_key_down { "down" } else { "up" },
103                                e.timestamp.format("%H:%M:%S%.3f")
104                            );
105                        }
106                    }
107                    SensorEvent::Mouse(e) => {
108                        transparency_log.record_mouse_event();
109                        if event_count <= 10 || event_count % 100 == 0 {
110                            println!(
111                                "  Mouse event: {:?} at {}",
112                                e.event_type,
113                                e.timestamp.format("%H:%M:%S%.3f")
114                            );
115                        }
116                    }
117                    SensorEvent::Shortcut(e) => {
118                        transparency_log.record_shortcut_event();
119                        if event_count <= 10 || event_count % 50 == 0 {
120                            println!(
121                                "  Shortcut event: {:?} at {}",
122                                e.shortcut_type,
123                                e.timestamp.format("%H:%M:%S%.3f")
124                            );
125                        }
126                    }
127                }
128
129                // Process in window manager
130                window_manager.process_event(event);
131            }
132            Err(crossbeam_channel::RecvTimeoutError::Timeout) => {
133                // Check for window expiry
134                window_manager.check_window_expiry();
135            }
136            Err(crossbeam_channel::RecvTimeoutError::Disconnected) => {
137                break;
138            }
139        }
140
141        // Process completed windows
142        for window in window_manager.take_completed_windows() {
143            transparency_log.record_window_completed();
144
145            let features = compute_features(&window);
146            let snapshot = hsi_builder.build(&window, &features);
147
148            println!();
149            println!("=== Window Completed ===");
150            println!("  Duration: {:.1}s", window.duration_secs());
151            println!("  Keyboard events: {}", window.keyboard_events.len());
152            println!("  Mouse events: {}", window.mouse_events.len());
153            println!();
154            println!("  Keyboard Features:");
155            println!(
156                "    Typing rate: {:.2} keys/sec",
157                features.keyboard.typing_rate
158            );
159            println!("    Pause count: {}", features.keyboard.pause_count);
160            println!("    Burst index: {:.3}", features.keyboard.burst_index);
161            println!();
162            println!("  Mouse Features:");
163            println!(
164                "    Activity rate: {:.2} moves/sec",
165                features.mouse.mouse_activity_rate
166            );
167            println!("    Mean velocity: {:.2}", features.mouse.mean_velocity);
168            println!(
169                "    Click rate: {:.2} clicks/sec",
170                features.mouse.click_rate
171            );
172            println!();
173            println!("  Behavioral Signals:");
174            println!(
175                "    Interaction rhythm: {:.3}",
176                features.behavioral.interaction_rhythm
177            );
178            println!("    Friction: {:.3}", features.behavioral.friction);
179            println!(
180                "    Motor stability: {:.3}",
181                features.behavioral.motor_stability
182            );
183            println!(
184                "    Focus continuity: {:.3}",
185                features.behavioral.focus_continuity_proxy
186            );
187            println!();
188
189            // Show snippet of HSI JSON
190            let json = serde_json::to_string_pretty(&snapshot).unwrap();
191            println!("  HSI Snapshot (truncated):");
192            for line in json.lines().take(20) {
193                println!("    {line}");
194            }
195            println!("    ...");
196            println!();
197        }
198
199        // Show progress
200        if event_count > 0 && event_count % 200 == 0 {
201            let elapsed = start.elapsed().as_secs();
202            println!("  [{elapsed}/30s] Processed {event_count} events...");
203        }
204    }
205
206    // Stop collection
207    println!();
208    println!("Stopping capture...");
209    collector.stop();
210
211    // Flush remaining window
212    window_manager.flush();
213    for window in window_manager.take_completed_windows() {
214        println!("Final window: {} events", window.event_count());
215        transparency_log.record_window_completed();
216    }
217
218    // Final statistics
219    println!();
220    println!("{}", transparency_log.summary());
221    println!();
222    println!("Demo complete!");
223}
Source

pub fn record_window_completed(&self)

Record a completed window.

Examples found in repository?
examples/capture_demo.rs (line 143)
26fn main() {
27    println!("Synheart Sensor Agent - Capture Demo");
28    println!("=====================================");
29    println!();
30
31    // Display privacy declaration
32    println!("{PRIVACY_DECLARATION}");
33    println!();
34
35    // Check for permission
36    print!("Checking Input Monitoring permission... ");
37    if check_permission() {
38        println!("OK ✓");
39    } else {
40        println!("FAILED ✗");
41        println!();
42        println!("Please grant Input Monitoring permission:");
43        println!("1. Open System Preferences");
44        println!("2. Go to Security & Privacy > Privacy > Input Monitoring");
45        println!("3. Add this application");
46        println!("4. Restart this demo");
47        return;
48    }
49    println!();
50
51    // Create components
52    let config = CollectorConfig {
53        capture_keyboard: true,
54        capture_mouse: true,
55    };
56
57    let mut collector = Collector::new(config);
58    let mut window_manager = WindowManager::new(10, 300); // 10s windows, 5min session gap
59    let hsi_builder = HsiBuilder::new();
60    let transparency_log = TransparencyLog::new();
61
62    println!("Instance ID: {}", hsi_builder.instance_id());
63    println!();
64    println!("Starting capture for 30 seconds...");
65    println!("Try typing and moving your mouse!");
66    println!();
67
68    // Start collection
69    if let Err(e) = collector.start() {
70        eprintln!("Error starting collector: {e}");
71        return;
72    }
73
74    // Set up stop flag
75    let running = Arc::new(AtomicBool::new(true));
76    let r = running.clone();
77
78    // Set up Ctrl+C handler
79    ctrlc::set_handler(move || {
80        r.store(false, Ordering::SeqCst);
81    })
82    .expect("Error setting Ctrl+C handler");
83
84    // Run for 30 seconds
85    let start = std::time::Instant::now();
86    let receiver = collector.receiver().clone();
87    let mut event_count = 0;
88
89    while running.load(Ordering::SeqCst) && start.elapsed() < Duration::from_secs(30) {
90        // Receive events with timeout
91        match receiver.recv_timeout(Duration::from_millis(100)) {
92            Ok(event) => {
93                event_count += 1;
94
95                // Log event type
96                match &event {
97                    SensorEvent::Keyboard(e) => {
98                        transparency_log.record_keyboard_event();
99                        if event_count <= 10 || event_count % 50 == 0 {
100                            println!(
101                                "  Keyboard event: {} at {}",
102                                if e.is_key_down { "down" } else { "up" },
103                                e.timestamp.format("%H:%M:%S%.3f")
104                            );
105                        }
106                    }
107                    SensorEvent::Mouse(e) => {
108                        transparency_log.record_mouse_event();
109                        if event_count <= 10 || event_count % 100 == 0 {
110                            println!(
111                                "  Mouse event: {:?} at {}",
112                                e.event_type,
113                                e.timestamp.format("%H:%M:%S%.3f")
114                            );
115                        }
116                    }
117                    SensorEvent::Shortcut(e) => {
118                        transparency_log.record_shortcut_event();
119                        if event_count <= 10 || event_count % 50 == 0 {
120                            println!(
121                                "  Shortcut event: {:?} at {}",
122                                e.shortcut_type,
123                                e.timestamp.format("%H:%M:%S%.3f")
124                            );
125                        }
126                    }
127                }
128
129                // Process in window manager
130                window_manager.process_event(event);
131            }
132            Err(crossbeam_channel::RecvTimeoutError::Timeout) => {
133                // Check for window expiry
134                window_manager.check_window_expiry();
135            }
136            Err(crossbeam_channel::RecvTimeoutError::Disconnected) => {
137                break;
138            }
139        }
140
141        // Process completed windows
142        for window in window_manager.take_completed_windows() {
143            transparency_log.record_window_completed();
144
145            let features = compute_features(&window);
146            let snapshot = hsi_builder.build(&window, &features);
147
148            println!();
149            println!("=== Window Completed ===");
150            println!("  Duration: {:.1}s", window.duration_secs());
151            println!("  Keyboard events: {}", window.keyboard_events.len());
152            println!("  Mouse events: {}", window.mouse_events.len());
153            println!();
154            println!("  Keyboard Features:");
155            println!(
156                "    Typing rate: {:.2} keys/sec",
157                features.keyboard.typing_rate
158            );
159            println!("    Pause count: {}", features.keyboard.pause_count);
160            println!("    Burst index: {:.3}", features.keyboard.burst_index);
161            println!();
162            println!("  Mouse Features:");
163            println!(
164                "    Activity rate: {:.2} moves/sec",
165                features.mouse.mouse_activity_rate
166            );
167            println!("    Mean velocity: {:.2}", features.mouse.mean_velocity);
168            println!(
169                "    Click rate: {:.2} clicks/sec",
170                features.mouse.click_rate
171            );
172            println!();
173            println!("  Behavioral Signals:");
174            println!(
175                "    Interaction rhythm: {:.3}",
176                features.behavioral.interaction_rhythm
177            );
178            println!("    Friction: {:.3}", features.behavioral.friction);
179            println!(
180                "    Motor stability: {:.3}",
181                features.behavioral.motor_stability
182            );
183            println!(
184                "    Focus continuity: {:.3}",
185                features.behavioral.focus_continuity_proxy
186            );
187            println!();
188
189            // Show snippet of HSI JSON
190            let json = serde_json::to_string_pretty(&snapshot).unwrap();
191            println!("  HSI Snapshot (truncated):");
192            for line in json.lines().take(20) {
193                println!("    {line}");
194            }
195            println!("    ...");
196            println!();
197        }
198
199        // Show progress
200        if event_count > 0 && event_count % 200 == 0 {
201            let elapsed = start.elapsed().as_secs();
202            println!("  [{elapsed}/30s] Processed {event_count} events...");
203        }
204    }
205
206    // Stop collection
207    println!();
208    println!("Stopping capture...");
209    collector.stop();
210
211    // Flush remaining window
212    window_manager.flush();
213    for window in window_manager.take_completed_windows() {
214        println!("Final window: {} events", window.event_count());
215        transparency_log.record_window_completed();
216    }
217
218    // Final statistics
219    println!();
220    println!("{}", transparency_log.summary());
221    println!();
222    println!("Demo complete!");
223}
Source

pub fn record_snapshot_exported(&self)

Record an exported snapshot.

Source

pub fn stats(&self) -> TransparencyStats

Get the current statistics.

Source

pub fn summary(&self) -> String

Get a summary string for display.

Examples found in repository?
examples/capture_demo.rs (line 220)
26fn main() {
27    println!("Synheart Sensor Agent - Capture Demo");
28    println!("=====================================");
29    println!();
30
31    // Display privacy declaration
32    println!("{PRIVACY_DECLARATION}");
33    println!();
34
35    // Check for permission
36    print!("Checking Input Monitoring permission... ");
37    if check_permission() {
38        println!("OK ✓");
39    } else {
40        println!("FAILED ✗");
41        println!();
42        println!("Please grant Input Monitoring permission:");
43        println!("1. Open System Preferences");
44        println!("2. Go to Security & Privacy > Privacy > Input Monitoring");
45        println!("3. Add this application");
46        println!("4. Restart this demo");
47        return;
48    }
49    println!();
50
51    // Create components
52    let config = CollectorConfig {
53        capture_keyboard: true,
54        capture_mouse: true,
55    };
56
57    let mut collector = Collector::new(config);
58    let mut window_manager = WindowManager::new(10, 300); // 10s windows, 5min session gap
59    let hsi_builder = HsiBuilder::new();
60    let transparency_log = TransparencyLog::new();
61
62    println!("Instance ID: {}", hsi_builder.instance_id());
63    println!();
64    println!("Starting capture for 30 seconds...");
65    println!("Try typing and moving your mouse!");
66    println!();
67
68    // Start collection
69    if let Err(e) = collector.start() {
70        eprintln!("Error starting collector: {e}");
71        return;
72    }
73
74    // Set up stop flag
75    let running = Arc::new(AtomicBool::new(true));
76    let r = running.clone();
77
78    // Set up Ctrl+C handler
79    ctrlc::set_handler(move || {
80        r.store(false, Ordering::SeqCst);
81    })
82    .expect("Error setting Ctrl+C handler");
83
84    // Run for 30 seconds
85    let start = std::time::Instant::now();
86    let receiver = collector.receiver().clone();
87    let mut event_count = 0;
88
89    while running.load(Ordering::SeqCst) && start.elapsed() < Duration::from_secs(30) {
90        // Receive events with timeout
91        match receiver.recv_timeout(Duration::from_millis(100)) {
92            Ok(event) => {
93                event_count += 1;
94
95                // Log event type
96                match &event {
97                    SensorEvent::Keyboard(e) => {
98                        transparency_log.record_keyboard_event();
99                        if event_count <= 10 || event_count % 50 == 0 {
100                            println!(
101                                "  Keyboard event: {} at {}",
102                                if e.is_key_down { "down" } else { "up" },
103                                e.timestamp.format("%H:%M:%S%.3f")
104                            );
105                        }
106                    }
107                    SensorEvent::Mouse(e) => {
108                        transparency_log.record_mouse_event();
109                        if event_count <= 10 || event_count % 100 == 0 {
110                            println!(
111                                "  Mouse event: {:?} at {}",
112                                e.event_type,
113                                e.timestamp.format("%H:%M:%S%.3f")
114                            );
115                        }
116                    }
117                    SensorEvent::Shortcut(e) => {
118                        transparency_log.record_shortcut_event();
119                        if event_count <= 10 || event_count % 50 == 0 {
120                            println!(
121                                "  Shortcut event: {:?} at {}",
122                                e.shortcut_type,
123                                e.timestamp.format("%H:%M:%S%.3f")
124                            );
125                        }
126                    }
127                }
128
129                // Process in window manager
130                window_manager.process_event(event);
131            }
132            Err(crossbeam_channel::RecvTimeoutError::Timeout) => {
133                // Check for window expiry
134                window_manager.check_window_expiry();
135            }
136            Err(crossbeam_channel::RecvTimeoutError::Disconnected) => {
137                break;
138            }
139        }
140
141        // Process completed windows
142        for window in window_manager.take_completed_windows() {
143            transparency_log.record_window_completed();
144
145            let features = compute_features(&window);
146            let snapshot = hsi_builder.build(&window, &features);
147
148            println!();
149            println!("=== Window Completed ===");
150            println!("  Duration: {:.1}s", window.duration_secs());
151            println!("  Keyboard events: {}", window.keyboard_events.len());
152            println!("  Mouse events: {}", window.mouse_events.len());
153            println!();
154            println!("  Keyboard Features:");
155            println!(
156                "    Typing rate: {:.2} keys/sec",
157                features.keyboard.typing_rate
158            );
159            println!("    Pause count: {}", features.keyboard.pause_count);
160            println!("    Burst index: {:.3}", features.keyboard.burst_index);
161            println!();
162            println!("  Mouse Features:");
163            println!(
164                "    Activity rate: {:.2} moves/sec",
165                features.mouse.mouse_activity_rate
166            );
167            println!("    Mean velocity: {:.2}", features.mouse.mean_velocity);
168            println!(
169                "    Click rate: {:.2} clicks/sec",
170                features.mouse.click_rate
171            );
172            println!();
173            println!("  Behavioral Signals:");
174            println!(
175                "    Interaction rhythm: {:.3}",
176                features.behavioral.interaction_rhythm
177            );
178            println!("    Friction: {:.3}", features.behavioral.friction);
179            println!(
180                "    Motor stability: {:.3}",
181                features.behavioral.motor_stability
182            );
183            println!(
184                "    Focus continuity: {:.3}",
185                features.behavioral.focus_continuity_proxy
186            );
187            println!();
188
189            // Show snippet of HSI JSON
190            let json = serde_json::to_string_pretty(&snapshot).unwrap();
191            println!("  HSI Snapshot (truncated):");
192            for line in json.lines().take(20) {
193                println!("    {line}");
194            }
195            println!("    ...");
196            println!();
197        }
198
199        // Show progress
200        if event_count > 0 && event_count % 200 == 0 {
201            let elapsed = start.elapsed().as_secs();
202            println!("  [{elapsed}/30s] Processed {event_count} events...");
203        }
204    }
205
206    // Stop collection
207    println!();
208    println!("Stopping capture...");
209    collector.stop();
210
211    // Flush remaining window
212    window_manager.flush();
213    for window in window_manager.take_completed_windows() {
214        println!("Final window: {} events", window.event_count());
215        transparency_log.record_window_completed();
216    }
217
218    // Final statistics
219    println!();
220    println!("{}", transparency_log.summary());
221    println!();
222    println!("Demo complete!");
223}
Source

pub fn save(&self) -> Result<(), Error>

Save stats to disk.

Source

pub fn reset(&self)

Reset all counters.

Trait Implementations§

Source§

impl Debug for TransparencyLog

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for TransparencyLog

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.