ZeroTrace AirLeak
Alert Rules
Every privacy and tracking alert the firmware fires
The alert engine turns "AirLeak captures everything" into "AirLeak flags what matters." Each observation is evaluated against the rules below (src/pipeline/alert_engine.cpp). A match records an alert in the on-device ring and drives the threat-indicator LED (when enabled).
The firmware no longer pushes an alert.raised event to the app, the mobile app has no alerts-feed consumer yet, so pushing each alert was pure dead weight on the BLE link and could tip a dense capture into a re-snapshot loop. Alerts still fire locally: they fill the alert ring and drive the threat-indicator LED. The wired-up app alerts feed is a future addition.
Severity levels
The firmware uses a compact 0–2 severity band, distinct from a device's 0–100 leakage score:
| Level | Meaning |
|---|---|
| 0, Info | Informational. Not necessarily a problem. |
| 1, Low | Minor or expected behaviour worth noting. |
| 2, High | Real exposure or a strong tracking signal. |
Rate limiting
Each rule is rate-limited per device. The default cooldown is 30 seconds per (device, rule) pair, so a persistent condition doesn't flood the ring. Some rules use a longer window (5 or 10 minutes) where re-firing sooner adds no value.
Rule reference
These are the rules the engine actually evaluates (AlertRule in src/pipeline/alert_engine.h).
airdrop_discoverable, severity 2
Trigger: an AirDrop advertisement indicating "Everyone" / discoverable mode.
What it means: a nearby device is broadcasting Apple ID / phone-number hash prefixes. Anyone nearby can also send it unsolicited AirDrop prompts.
findmy_separated, severity 1
Trigger: a Find My / AirTag advertisement whose state flag indicates separated-from-owner.
What it means: an AirTag or compatible accessory is in "owner not nearby" mode. Normal in short bursts; persistent observation over hours can indicate an unwanted tracker.
nearby_phone_unlocked, severity 0
Trigger: an Apple Continuity Nearby Info advertisement showing an active-audio/call action while the device reports unlocked. Rate-limited to once per 5 minutes per device.
What it means: a nearby Apple device appears unlocked during active audio or a call. Informational.
high_leakage_score, severity 2
Trigger: a device's combined leakage score reaches 60/100 or higher.
What it means: the device is exposing enough across multiple signals (AirDrop, Find My, identifiable fields) to score as a significant leak.
multi_hour_follower, severity 2
Trigger: a non-random MAC observed across 3 or more distinct hour windows since first sighting. Rate-limited to once per 5 minutes.
What it means: the same device has been near you across many hours, the classic "is something following me" signal.
smarttag_separated, severity 2
Trigger: a Samsung SmartTag advertisement in separated state. Rate-limited to once per 10 minutes.
What it means: a SmartTag is broadcasting away-from-owner.
unknown_tracker_near, severity 1
Trigger: a tracker-class beacon (Tile / Find My / FMDN) in separated state observed repeatedly (≥8 observations), or a tracker broadcasting an unwanted-tracking-protection (UTP) signal observed ≥5 times. Rate-limited to once per 10 minutes.
What it means: an unfamiliar separated tracker is persistently near you, or a tracker is actively signalling Apple/Google unwanted-tracker detection.
Earlier AirLeak fired WiFi-based alerts (corporate / PII / airport / hotel / café SSID-in-probe, open / WEP / WPA-personal networks, WPS, MFP, deauth bursts). Those were removed with the WiFi capture path, the BLE-only firmware doesn't see WiFi, so it can't evaluate them. Their enum slots are intentionally left as gaps so the remaining rule numbers stay stable.
Alert ring buffer
The firmware keeps the most recent 128 alerts in an in-RAM ring (PSRAM-backed). When full, the oldest are evicted. The ring is operational state only, it's cleared on reboot. The on-flash diagnostic log (diag.read) is the persistent record for post-mortem review.
Threat indicator
When led_threat_indicate is on, fired alerts drive the on-device LED through the threat indicator. Its window and yellow/red thresholds (including which rules or severities force red immediately) are tuned via the threat_* config keys, see Settings.