How On-Device AI Analyzes Your Emails: A Technical Overview
When you share a suspicious email with Veilsort, a fixed multi-stage pipeline runs entirely on your iPhone — PII masking, optional chunking, Apple Foundation Models inference, and a four-card structured result. Here is how each stage actually works, and what it does and does not do.
| Risk domain | Low | Medium | High |
|---|---|---|---|
| Legal | Generic disclaimer language | Threat of legal action mentioned | Specific lawsuit / court deadline claimed |
| Financial | Generic payment request | Urgent payment / account suspension | Demands for credentials, card numbers, or wire transfers |
| Employment | Generic HR-themed email | Job offer requiring upfront payment | Resume / payroll redirect impersonation |
| Privacy | Newsletter sign-up | Request to "verify your identity" | Demands for SSN, date of birth, or account credentials |
| Reputation | Generic brand mention | Impersonation of a known brand | Targeted impersonation of a specific person you know |
| Safety | Generic security notice | Threat of account closure | Threat of physical harm or extortion |
Veilsort's analysis pipeline is designed around a single hard constraint: zero network traffic from the app. Every stage — preprocessing, inference, and result assembly — runs on-device. That constraint is not a limitation; it is the core privacy guarantee. Here is a stage-by-stage walkthrough of what actually happens when you share an email from Mail.app (or paste one in).
Stage 1: Intake
The email text arrives either through the Share Extension (shared from Mail.app, handed off via a shared App Group container) or through manual paste in the app. No OAuth, no inbox access, no account. The text is a single email body at a time; v1.0 does not do batch or multi-email analysis.
Key technology: Share Extension + App Group container + CapturePayload/CaptureStore
Stage 2: PII Masking
Before the email reaches the model, PIIMasker scans for personal identifiers — names, phone numbers, addresses, URLs, email addresses, dates, and similar categories — using NSDataDetector, NLTagger (Natural Language framework), and a set of regex layers. Matches are replaced with typed token placeholders before the text is sent to the model prompt. The original text is retained in local history for you to read, but the model itself never sees raw PII. Masking is defense-in-depth: it reduces what the model is exposed to, and it is not a guarantee of perfect PII removal for every possible pattern.
Key technology: NSDataDetector + NLTagger + regex layers, all on-device
Stage 3: Optional Chunking
Long emails are split into chunks of roughly 2,800 characters by TextChunker for a map-reduce pass. Each chunk is analyzed independently and the results are merged into a single structured EmailAnalysis. Short emails skip this step entirely.
Key technology: TextChunker with map-reduce merge
Stage 4: Apple Foundation Models Inference
The masked, optionally-chunked text is passed to Apple Foundation Models running on-device, invoked through the FoundationModels framework directly (no MLX, no Core ML, no custom-trained model). The model returns a structured EmailAnalysis containing a one-paragraph summary, a list of risk flags, a list of deadlines, and a cautious suggested reply. If Apple Intelligence is not available on the device — older hardware, iOS < 26, or the model not ready — Veilsort shows a graceful locked-state screen. It does not fall back to a network call. There is no network to fall back to.
Key technology: Apple FoundationModels framework, triple-guarded with #if canImport + #available(iOS 26.0, *) + isAIAvailable
Stage 5: Four-Card Structured Result
The result is rendered as four cards on screen: Summary (one paragraph describing what the sender wants), Key Points (risk flags), Deadlines (explicit and inferred, with verbatim source quotes), and Suggested Replies (a cautious, non-committal draft you can copy). Risk flags are classified by domain — legal, financial, employment, privacy, reputation, safety — and by severity: low, medium, or high. There is no "Critical" severity tier in v1.0. Each risk and deadline includes a verbatim supporting quote from the email so you can verify the model's reasoning against the source. The suggested reply can be regenerated in a Cautious or Cooperative tone.
Key technology: SwiftUI AnalysisResultView + EmailAnalysis Codable model
Stage 6: Local History
The analysis is stored in HistoryStore as a HistoryEntry (raw text + structured analysis + timestamp + prompt kind) in a file-backed JSON store in the shared App Group container. Retention is user-configurable: a number of days, or Forever. The default for new installs is 30 days. There is no fixed "7-day only" option; the user picks the window. The store is local; nothing is synced, because there is nothing to sync to.
Key technology: HistoryStore + RetentionStore, file-backed JSON via Codable + FileManager in App Group container
What This Pipeline Does Not Do
A few things are worth stating plainly, because they are commonly assumed but not part of v1.0:
- No telemetry. The app makes zero network requests. The only data that ever leaves the device is Apple's own system-level MetricKit diagnostics, which is not initiated by Veilsort and contains no email content. There is no Crashlytics, Sentry, Firebase, Amplitude, or any third-party analytics SDK.
- No "confidence scores." The model returns structured risks with a severity of low, medium, or high, plus a rationale and a verbatim quote. It does not surface a numeric confidence percentage to the user.
- No header, SPF/DKIM, URL-destination, or attachment analysis. v1.0 is text-only. Anything requiring access to raw headers, follow-through on link redirects, or inspection of attachments is out of scope.
- No personalized inbox-pattern learning. Each analysis is independent. Veilsort does not learn what "normal" looks like for your inbox, because that would require persistent access to your inbox.
- No "anonymized telemetry that the user controls in Settings." There is no telemetry toggle in Settings, because there is no telemetry to toggle.
Why On-Device Matters for Each Stage
None of these stages require a server. PII masking is deterministic on-device text processing. Chunking is local. Model inference runs on Apple Foundation Models. Result rendering is SwiftUI. History is a local file. By keeping the entire pipeline on-device, Veilsort guarantees that no intermediate state — not the raw email, not the masked version, not the model output — ever leaves your iPhone. This is privacy by construction, not by policy.