What we inspect, and why
When a process misbehaves, Anomalous resolves what it actually is through a layered loop — your on-device corpus, an on-device identity model, then an anonymous research lookup — always failing safe to "unknown" rather than guessing.
Why identity is hard
When Anomalous flags a process for behaving strangely, the first question is always the same: what is this process? A good, safe action depends entirely on the answer. Telling you to quit com.google.Chrome.helper is very different from telling you to leave kernel_task alone. But your Mac runs dozens of background programs with terse, cryptic names, and a small on-device model asked "what is dasd?" will happily invent a confident, wrong answer.
So Anomalous does not let a model guess. It resolves the identity of an unknown process through a strict, escalating lookup loop that leans on hard facts first and only reaches for research when there is a genuine mystery to solve. Each step inspects only what it needs, and the whole loop is built to fail safe to "unknown" rather than fabricate an identity.
Step 1: your on-device corpus
Anomalous ships with a built-in knowledge map of well-known macOS processes, and merges a reviewed, community-correctable corpus feed on top of it. If the flagged process is already known, the diagnosis card is composed deterministically from that curated entry, on your machine, instantly, with no AI involved. That is corpus grounding: the app only speaks about a process when the corpus actually knows it.
For example, a card for dasd can state that it normally averages around 0.1% CPU, note it is currently pinned high, and reassure you that it is safe to quit because launchd will respawn it. Two special cases are also resolved here without any model: kernel_task is reframed as "your Mac is hot" thermal throttling, and a frozen, "Not Responding" app gets a deterministic force-quit-and-relaunch card.
Under the hood
The shipped KnowledgeMap is merged with an Ed25519-signed corpus feed pulled from /v1/feed; reviewed and newer entries win, and an unsigned or unverifiable feed is rejected fail-closed so a tampered feed can never ground a card (AppState.swift:422-431, 620-632). A pure routing function decides per anomaly between thermal, hung-app, deterministic-unknown, and model paths (JudgmentEngine.swift:68-77, 86-100, 286-317). The corpus itself is a public, PR-able repository at github.com/msitarzewski/anomalous-corpus (Apache-2.0; PRs welcome, and the repo may still be private today). See how discovery grows the corpus.
Step 2: the on-device identity model
If the corpus has no entry but the process carries an application bundle id, Anomalous consults Apple's on-device Foundation Models. The bundle id is the hard fact that anchors the model to a real app, so it describes a known app's subprocess factually instead of inventing an identity. A subprocess named com.google.Chrome.helper is understood as part of Chrome, not conjured from nothing. This judgment runs entirely on your Mac; process metrics are sent nowhere.
The gate here is deliberate: a process with no corpus entry and no bundle id — a genuine mystery daemon — never reaches the model at all. It gets a conservative "unknown, tier 3" card, because for identity, an honest shrug beats a confident invention.
Under the hood
The rung-1 session is tool-calling: the model can call four read-only tools over a frozen snapshot — processHistory (the recent metric curve), baseline (what is normal and how far off it is now), correlated (other flagged dimensions and linked processes), and corpusEntry (the curated identity) — each returning one short sentence the model must quote verbatim rather than re-detect (JudgmentTools.swift:143-228). The prompt is budgeted to the model's dynamically-read context window (measured around 4096 tokens), dropping tools first, then falling back to compact no-tools instructions (JudgmentEngine.swift:378-390, 407-443). If Foundation Models is rate-limited or unavailable (pre-macOS 26), it degrades honestly to the map-only card. A second, Private Cloud Compute upgrade pass is wired but not yet live — it requires an Apple entitlement the build does not yet carry, so it will light up later with no code change. Related: the AI tiers.
Step 3: anonymous discovery
Only the genuinely-unknown cases — no corpus identity, and nothing for the on-device model to anchor on — warrant a network lookup. This is discovery: the app posts an anonymous signature of the process to Anomalous's servers. It is opt-in, free, on by default, and you can also tap to look up a single process even with the global toggle off.
If the corpus already knows the identity, the server answers instantly. Otherwise it hands back a poll handle and researches the process off the request path while the app checks back for a couple of minutes. Server-side, an AI agent researches the process and drafts a cited profile, then a separate, cheaper, independent verifier adversarially checks that draft against the actual text of its own cited sources. Only a verified, high-confidence answer is auto-published into the shared corpus, so it grounds everyone's cards from then on. Anything short of that stays "unknown" rather than guess. When an answer returns, the card upgrades in place, shows its cited sources, and is captioned "Sourced by Anomalous."
Under the hood
The request is anonymous by construction: the on-the-wire type has fields only for name, bundle id, app/OS version, install source, and anomaly type — there is literally no field for a file path, arguments, username, or hostname (DiscoveryClient.swift:33-51). Every request is written byte-for-byte to a local SendLog before it is sent (DiscoveryClient.swift:195-212). A cache hit returns 200/complete; a miss returns 202 with a random poll handle (DiscoveryController.php:57-92), which the app polls at roughly 3s then 6s intervals up to about 180s, deduped by process lineage so each tick does not kick off a fresh lookup (AppState.swift:985-1092). The publish gate is verified === true AND confidence >= 0.7; below it, the entry waits for human review and the caller gets "unknown" (ProcessDiscoveryJob.php:39-140). Full detail on the research→verify→publish flywheel lives in how discovery works; on what does and does not leave your Mac, see privacy.
Failing safe to "unknown"
Every step of the loop is designed to degrade to honesty. If the on-device model is unavailable, you get the deterministic corpus card. If discovery has no answer, the card stays a conservative "unknown." If the server has no AI provider configured, research writes a low-confidence stub and discovery returns "unknown" rather than fabricating a verified answer. Unknown processes default to the most cautious safety tier — explain-only, no button — so Anomalous never offers a one-click action against something it cannot name.
This is the core principle of the lookup loop: a wrong identity is worse than no identity. An unverified description is never published to the shared corpus, and a "verified" label is never fabricated.
What is inspected at each step
To resolve the question "what is this process," each step inspects strictly what it needs and nothing more:
| Step | What it inspects | Where it runs | Why |
|---|---|---|---|
| 1. Corpus grounding | The process name (and bundle id) against your on-device knowledge map and signed feed | On your Mac | Instant, free, deterministic identity for known processes; no AI, no network |
| 2. Identity model | The bundle id as an anchor, plus a frozen snapshot of the process's own metrics and baseline | On your Mac | Describes a real app's subprocess factually; a no-bundle mystery never reaches the model |
| 3. Anonymous discovery | An anonymous signature: name, bundle id, app/OS version, install source, anomaly type | Anomalous servers | Researches and independently verifies a genuine unknown; carries nothing that identifies you |
The safety tier the loop lands on drives the action:
offers one safe button (Quit, Restart, or Update), warns first, and only explains. Even then, termination re-confirms the process's start-time before acting so a reused pid can never cause a confident wrong kill, and Anomalous will not kill a root-owned process for you — it surfaces a copy-pastesudo killall command instead.