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 - macOS Support: Native integration using Core Graphics event taps
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) ║
║ ║
║ ✗ WHAT WE NEVER CAPTURE: ║
║ • Which keys you press (no passwords, messages, etc.) ║
║ • Where your cursor is (no screen position tracking) ║
║ • What applications you use ║
║ • 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
- Permissions: Input Monitoring permission required
Usage
Grant Input Monitoring Permission
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
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.1.0
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.
Not Captured (Privacy Policy)
The following metrics mentioned in behavioral research are intentionally not captured because they require application context, which violates our privacy policy:
| Metric | Reason Not Captured |
|---|---|
task_switch_rate |
Requires app/window tracking |
task_switch_cost |
Requires app/window tracking |
app_context |
Violates privacy guarantees |
Configuration
Configuration is stored at:
- macOS:
~/Library/Application Support/synheart-sensor-agent/config.json
Default configuration:
Architecture
┌─────────────────────────────────────────────────────────────────────────┐
│ Synheart Sensor Agent │
├─────────────────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Collector │──▶│ Windowing │──▶│ Features │ │
│ │ (macOS) │ │ (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
│ └── transparency/
│ ├── mod.rs # Transparency module
│ └── log.rs # Privacy log
└── examples/
└── capture_demo.rs # Demo application
Troubleshooting
"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
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
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
- CLI powered by clap