Synheart Sensor Agent
A privacy-first PC background sensor that captures keyboard and mouse interaction timing (not content) for behavioral research.
Overview
Synheart Sensor Agent collects behavioral timing data from keyboard and mouse interactions while maintaining strict privacy guarantees. It extracts features like typing rhythm, mouse movement patterns, and interaction continuity - all without ever capturing what you type or where you click.
Key Features
- Privacy by Design: Never captures key content, passwords, or screen coordinates
- Behavioral Features: Extracts 16+ behavioral signals from interaction patterns
- HSI Format: Exports data in the Human State Interface (HSI) JSON format ( via Synheart Flux )
- Transparency: Full visibility into what data is collected via
statuscommand - App Context: Captures foreground application bundle ID per window for task-switch detection (no window titles or content)
- macOS Support: Native integration using Core Graphics event taps
- Windows Support: Native integration using Windows Hooks API
Core Gateway Integration
For real-time HSI processing via synheart-core-gateway, enable the gateway feature:
# Build with gateway support
# Start with gateway sync (auto-detects port/token from runtime dir)
# Or specify port and token manually
# Customize sync interval (default: 10 seconds)
The gateway client reads configuration from:
- Port:
~/Library/Application Support/SyniLife/runtime/gateway.port - Token:
~/Library/Application Support/SyniLife/runtime/gateway.token
When connected, you'll see HSI state updates:
[Gateway] Synced 3 snapshots | HSI: focus: high, load: moderate, recovery: good
Synheart Flux Integration (Optional)
For rolling baselines and enriched HSI metrics, enable the optional flux feature and runtime flag:
Full guide: SYNHEART_FLUX_INTEGRATION.md
Combined Features
Enable both gateway sync and local flux processing:
Privacy Guarantees
╔══════════════════════════════════════════════════════════════════╗
║ ✓ WHAT WE CAPTURE: ║
║ • When keys are pressed (timing only) ║
║ • How fast the mouse moves (speed only) ║
║ • When clicks and scrolls occur (timing only) ║
║ • Foreground app bundle ID (for task-switch detection) ║
║ ║
║ ✗ WHAT WE NEVER CAPTURE: ║
║ • Which keys you press (no passwords, messages, etc.) ║
║ • Where your cursor is (no screen position tracking) ║
║ • Window titles or application content ║
║ • Any screen content ║
╚══════════════════════════════════════════════════════════════════╝
Installation
From Source
# Clone the repository
# Build in release mode
# The binary will be at target/release/synheart-sensor
Requirements
- Rust: 1.70 or later
- macOS: 10.15 (Catalina) or later
- Windows: 10 or later
- Permissions: Input Monitoring (macOS) or Run as Administrator (Windows)
Usage
Grant Input Capture Permission
macOS
Before the agent can capture events, you need to grant Input Monitoring permission:
- Open System Preferences > Security & Privacy > Privacy
- Select Input Monitoring in the left sidebar
- Click the lock icon and authenticate
- Add the
synheart-sensorapplication - Restart the application
Windows
Run the sensor agent as Administrator to capture input events:
- Right-click the
synheart-sensor.exebinary - Select Run as administrator
- Or launch your terminal (Command Prompt / PowerShell) as Administrator before running the binary
Commands
# Start capturing behavioral data
# Start with specific sources
# Pause collection
# Resume collection
# Show current status and statistics
# Display privacy declaration
# Export collected data
# Show configuration
Example Output
When running, the agent displays window completions:
Synheart Sensor Agent v0.2.2
Starting collection...
Keyboard: enabled
Mouse: enabled
Window duration: 10s
Press Ctrl+C to stop
Instance ID: 550e8400-e29b-41d4-a716-446655440000
[14:32:10] Window completed: 45 keyboard, 234 mouse events
[14:32:20] Window completed: 52 keyboard, 198 mouse events
[14:32:30] Window completed: 38 keyboard, 256 mouse events
HSI Output Format
The agent exports data in HSI 1.0 (Human State Interface) JSON format:
Behavioral Features
Keyboard Features
| Feature | Description |
|---|---|
typing_rate |
Keys pressed per second |
pause_count |
Number of pauses (gaps > 500ms) |
mean_pause_ms |
Average pause duration |
latency_variability |
Std dev of inter-key intervals |
hold_time_mean |
Average key hold duration |
burst_index |
Burstiness of typing (0-1) |
session_continuity |
Active typing ratio |
Mouse Features
| Feature | Description |
|---|---|
mouse_activity_rate |
Movement events per second |
mean_velocity |
Average cursor speed |
velocity_variability |
Consistency of movement |
acceleration_spikes |
Sudden speed changes |
click_rate |
Clicks per second |
scroll_rate |
Scroll events per second |
idle_ratio |
Idle vs active time |
micro_adjustment_ratio |
Small movements ratio |
Derived Signals
| Signal | Description |
|---|---|
interaction_rhythm |
Overall input regularity |
friction |
Hesitation/correction indicator |
motor_stability |
Movement consistency |
focus_continuity_proxy |
Sustained attention indicator |
burstiness |
Whether interactions occur in clusters or evenly |
deep_focus_block |
True if window shows sustained, uninterrupted activity |
Additional Metrics
| Metric | Description |
|---|---|
typing_tap_count |
Total discrete typing key events |
typing_cadence_stability |
Rhythmic consistency of typing (0-1) |
typing_gap_ratio |
Proportion of inter-tap intervals as gaps |
typing_interaction_intensity |
Composite of speed, stability, gap behavior |
keyboard_scroll_rate |
Navigation keys (arrows, PgUp/Dn) per second |
navigation_key_count |
Total navigation key events |
idle_time_ms |
Total idle time in milliseconds |
Metric Provenance
This section clarifies where each behavioral metric is computed to prevent confusion when integrating with downstream systems.
Computed Locally (Sensor Agent)
These metrics are computed directly in the sensor agent from raw event timing:
| Category | Metrics |
|---|---|
| Keyboard (Typing) | typing_rate, pause_count, mean_pause_ms, latency_variability, hold_time_mean, burst_index, session_continuity, typing_tap_count, typing_cadence_stability, typing_gap_ratio, typing_interaction_intensity |
| Keyboard (Navigation) | keyboard_scroll_rate, navigation_key_count |
| Mouse | mouse_activity_rate, mean_velocity, velocity_variability, acceleration_spikes, click_rate, scroll_rate, idle_ratio, micro_adjustment_ratio, idle_time_ms |
| Behavioral (Derived) | interaction_rhythm, friction, motor_stability, focus_continuity_proxy, burstiness, deep_focus_block |
Enriched in Flux (Optional)
When the --flux flag is enabled, these additional metrics are computed using rolling baselines:
| Metric | Description |
|---|---|
distraction_score |
Aggregate estimate of distraction |
focus_hint |
Aggregate estimate of focus |
interaction_intensity |
Flux-computed interaction intensity |
See SYNHEART_FLUX_INTEGRATION.md for details.
App Context (Privacy-Scoped)
As of v0.2.0, the agent captures the foreground application bundle ID per event window to enable task-switch detection and per-app behavioral segmentation. This is limited to the bundle identifier only (e.g., com.apple.Safari) — no window titles, URLs, or content are ever captured.
| Metric | Description |
|---|---|
app_id |
Foreground app bundle ID (one per 10-second window) |
Configuration
Configuration is stored at:
- macOS:
~/Library/Application Support/synheart-sensor-agent/config.json - Windows:
%APPDATA%\synheart-sensor-agent\config.json
Default configuration:
Architecture
┌─────────────────────────────────────────────────────────────────────────┐
│ Synheart Sensor Agent │
├─────────────────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Collector │──▶│ Windowing │──▶│ Features │ │
│ │(macOS/Win) │ │ (10s bins) │ │ (compute) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │Transparency │ │ HSI │──▶│ Gateway │ │
│ │ Log │ │ Snapshot │ │ Client │ │
│ └─────────────┘ └─────────────┘ └──────┬──────┘ │
└───────────────────────────────────────────────────────────────┼─────────┘
│
▼
┌─────────────────────┐
│ Core Gateway │
│ /v1/ingest/behavioral
│ ───────────────── │
│ HSI Processing │
│ via synheart-flux │
└─────────────────────┘
Development
Building
# Debug build
# Release build
# Run tests
# Run with logging
RUST_LOG=debug
Running the Demo
Project Structure
synheart-sensor-agent/
├── Cargo.toml # Project manifest
├── src/
│ ├── main.rs # CLI entry point
│ ├── lib.rs # Library exports
│ ├── config.rs # Configuration management
│ ├── gateway.rs # Gateway client (optional, --features gateway)
│ ├── flux.rs # Flux integration (optional, --features flux)
│ ├── core/
│ │ ├── mod.rs # Core module
│ │ ├── windowing.rs # Window management
│ │ ├── features.rs # Feature computation
│ │ └── hsi.rs # HSI snapshot builder
│ ├── collector/
│ │ ├── mod.rs # Collector module
│ │ ├── types.rs # Event types
│ │ ├── macos.rs # macOS implementation (Core Graphics)
│ │ └── windows.rs # Windows implementation (Hooks API)
│ └── transparency/
│ ├── mod.rs # Transparency module
│ └── log.rs # Privacy log
└── examples/
└── capture_demo.rs # Demo application
Troubleshooting
macOS: "Input Monitoring permission not granted"
- Open System Preferences > Security & Privacy > Privacy
- Select Input Monitoring
- Ensure the application is in the list and checked
- If already checked, remove and re-add the application
- Restart the application
Windows: "Administrator privileges required"
- Right-click the terminal or binary and select "Run as administrator"
- If using PowerShell, launch it with elevated privileges
- Restart the application
No events being captured
- Ensure you're actively typing or moving the mouse
- Check that the correct sources are enabled (
--sources all) - Verify permission is granted with
synheart-sensor status - macOS: Confirm Input Monitoring permission in System Preferences
- Windows: Confirm the process is running as Administrator
High CPU usage
- This is normal during active input
- CPU usage should be minimal when idle
- Consider reducing window duration if needed
Contributing
See CONTRIBUTING.md for guidelines on how to contribute.
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Acknowledgments
- Built with Rust
- macOS event capture via core-graphics
- Windows event capture via windows
- CLI powered by clap