Skip to main content

synheart_sensor_agent/
lib.rs

1//! # Synheart Sensor Agent
2//!
3//! **Privacy-first PC background sensor for behavioral research.**
4//!
5//! This library captures keyboard and mouse interaction timing for behavioral
6//! research with strong privacy guarantees. Raw events are never stored — only
7//! derived statistical features are produced as HSI 1.0 JSON snapshots.
8//!
9//! # Privacy Guarantees
10//!
11//! - **No key content** — only timing and category (typing vs. navigation)
12//! - **No coordinates** — only mouse movement magnitude/speed
13//! - **No raw storage** — events are discarded after feature extraction (every 10 s)
14//! - **Transparency** — all collection is logged and auditable via [`TransparencyLog`]
15//!
16//! # Architecture
17//!
18//! ```text
19//! ┌─────────────────────────────────────────────────────────────┐
20//! │                    Synheart Sensor Agent                    │
21//! ├─────────────────────────────────────────────────────────────┤
22//! │  ┌─────────────┐   ┌─────────────┐   ┌─────────────┐        │
23//! │  │  Collector  │──▶│  Windowing  │──▶│  Features   │        │
24//! │  │ (platform)  │   │  (10s bins) │   │ (compute)   │        │
25//! │  └─────────────┘   └─────────────┘   └─────────────┘        │
26//! │         │                                    │              │
27//! │         ▼                                    ▼              │
28//! │  ┌─────────────┐                     ┌─────────────┐        │
29//! │  │Transparency │                     │    HSI      │        │
30//! │  │    Log      │                     │  Snapshot   │        │
31//! │  └─────────────┘                     └─────────────┘        │
32//! └─────────────────────────────────────────────────────────────┘
33//! ```
34//!
35//! # Quick Start
36//!
37//! ```no_run
38//! use synheart_sensor_agent::{collector, core, transparency};
39//!
40//! // Create a collector (requires Input Monitoring permission on macOS)
41//! let config = collector::CollectorConfig::default();
42//! let mut collector = collector::Collector::new(config);
43//!
44//! // Start collection
45//! collector.start().expect("Failed to start collector");
46//!
47//! // Events can be received from collector.receiver()
48//! ```
49//!
50//! # Modules
51//!
52//! | Module | Purpose |
53//! |--------|---------|
54//! | [`collector`] | Platform-specific event capture ([`SensorEvent`], [`Collector`]) |
55//! | [`config`] | Agent configuration and persistence ([`Config`], [`SourceConfig`]) |
56//! | [`core`] | Windowing, feature extraction, and HSI encoding ([`WindowManager`], [`compute_features`], [`HsiBuilder`]) |
57//! | [`transparency`] | Auditable collection logging ([`TransparencyLog`], [`TransparencyStats`]) |
58//! | [`flux`] | Synheart Flux integration for baseline tracking *(requires `flux` feature)* |
59//! | [`gateway`] | Gateway client for real-time HSI sync *(requires `gateway` feature)* |
60//! | [`server`] | HTTP server for Chrome extension ingest *(requires `server` feature)* |
61//!
62//! # Feature Flags
63//!
64//! | Feature | Description |
65//! |---------|-------------|
66//! | `flux` | Enables [`SensorFluxProcessor`] for rolling baseline tracking via synheart-flux |
67//! | `gateway` | Enables [`GatewayClient`] / [`BlockingGatewayClient`] for syncing HSI to the local gateway |
68//! | `server` | Enables the HTTP ingest server for Chrome extension data (implies `flux` + `gateway`) |
69//!
70//! # Platform Support
71//!
72//! The [`collector`] module adapts to the build target:
73//!
74//! - **macOS** — CoreGraphics event tap + NSWorkspace for foreground app detection
75//! - **Windows** — Windows Hooks API for keyboard/mouse + foreground window detection
76//! - **Other** — No-op collector (compiles but does not capture events)
77
78#![cfg_attr(docsrs, feature(doc_cfg))]
79#![warn(missing_docs)]
80
81/// Platform-specific event collection (keyboard, mouse, shortcuts).
82///
83/// See [`SensorEvent`](collector::types::SensorEvent) for the event types and
84/// [`Collector`](collector::Collector) for the platform-agnostic entry point.
85pub mod collector;
86
87/// Agent configuration and persistence.
88pub mod config;
89
90/// Core functionality — windowing, feature extraction, and HSI snapshot building.
91pub mod core;
92
93/// Transparency logging for auditable data collection.
94pub mod transparency;
95
96/// Synheart Flux integration for baseline tracking and HSI enrichment.
97///
98/// See [`SensorFluxProcessor`](flux::SensorFluxProcessor) for the main entry point.
99#[cfg(feature = "flux")]
100pub mod flux;
101
102/// Gateway client for syncing HSI snapshots to the local synheart-core-gateway.
103///
104/// See [`GatewayClient`](gateway::GatewayClient) for async usage and
105/// [`BlockingGatewayClient`](gateway::BlockingGatewayClient) for synchronous usage.
106#[cfg(feature = "gateway")]
107pub mod gateway;
108
109/// HTTP server for receiving behavioral data from the Chrome extension.
110///
111/// See `server::run` to start the server and `server::ServerConfig`
112/// for configuration.
113#[cfg(feature = "server")]
114pub mod server;
115
116// Re-export key types at crate root for convenience
117pub use collector::{Collector, CollectorConfig, CollectorError, SensorEvent};
118pub use config::{Config, SourceConfig};
119pub use core::{compute_features, HsiBuilder, HsiSnapshot, WindowFeatures, WindowManager};
120pub use transparency::{SharedTransparencyLog, TransparencyLog, TransparencyStats};
121
122// Flux re-exports (when enabled)
123#[cfg(feature = "flux")]
124pub use flux::{EnrichedSnapshot, SensorFluxProcessor};
125
126// Gateway re-exports (when enabled)
127#[cfg(feature = "gateway")]
128pub use gateway::{
129    BlockingGatewayClient, GatewayClient, GatewayConfig, GatewayError, GatewayResponse,
130};
131
132// Server re-exports (when enabled)
133#[cfg(feature = "server")]
134pub use server::{run as run_server, ServerConfig};
135
136/// Library version string sourced from `Cargo.toml`.
137pub const VERSION: &str = env!("CARGO_PKG_VERSION");
138
139/// Privacy declaration that can be displayed to users.
140pub const PRIVACY_DECLARATION: &str = r#"
141╔══════════════════════════════════════════════════════════════════╗
142║           SYNHEART SENSOR AGENT - PRIVACY DECLARATION            ║
143╠══════════════════════════════════════════════════════════════════╣
144║                                                                  ║
145║  This agent captures behavioral timing data for research.        ║
146║                                                                  ║
147║  ✓ WHAT WE CAPTURE:                                              ║
148║    • When keys are pressed (timing only)                         ║
149║    • Key categories (backspace, enter, etc. - NOT which letter)  ║
150║    • Common shortcut patterns (copy, paste, etc. - timing only)  ║
151║    • How fast the mouse moves (speed only)                       ║
152║    • When clicks and scrolls occur (timing only)                 ║
153║    • Which app is in the foreground (identifier only, no titles) ║
154║                                                                  ║
155║  ✗ WHAT WE NEVER CAPTURE:                                        ║
156║    • Which keys you press (no passwords, messages, etc.)         ║
157║    • Where your cursor is (no screen position tracking)          ║
158║    • Window titles, file names, or document content              ║
159║    • Any screen content                                          ║
160║                                                                  ║
161║  All data is processed locally. Raw events are discarded         ║
162║  after feature extraction (every 10 seconds).                    ║
163║                                                                  ║
164║  You can view collection statistics anytime with:                ║
165║    synheart-sensor status                                        ║
166║                                                                  ║
167╚══════════════════════════════════════════════════════════════════╝
168"#;
169
170#[cfg(test)]
171mod tests {
172    use super::*;
173
174    #[test]
175    fn test_privacy_declaration_contents() {
176        assert!(PRIVACY_DECLARATION.contains("PRIVACY"));
177        assert!(PRIVACY_DECLARATION.contains("NEVER CAPTURE"));
178        assert!(PRIVACY_DECLARATION.contains("keys you press"));
179    }
180}