One line: a SwiftUI app drops a bundle onto a pure-Swift analyzer, optionally launches the inspected app under a privileged XPC helper for dynamic monitoring, and optionally ships a guest agent into a macOS VM to do the same work in isolation.

The picture

Why each target is separate

privacycommandCore carries no UI on purpose. It runs from the CLI, from tests, from the GUI, and from the helper. Keeping the views out means a detector change is testable in seconds with swift test, and that the same analysis code runs everywhere rather than being reimplemented per surface. The Analysis/ half imports nothing from AppKit; three files under Monitoring/ do, because launching a bundle, reading the pasteboard, and driving a VM front-end have no Foundation equivalent. The helper is tiny on purpose. It exposes only what genuinely needs root: version, start/stop file monitor, the BTM dump, install/remove kill switch, uninstall. No general run-as-root path. It validates callers by code signature — Apple anchor plus matching Team ID — so a binary signed by anyone else can’t talk to it. That check depends on the helper itself being team-signed; see How it protects itself for what a no-team build does instead. The guest protocol has zero dependencies on purpose. The agent has to build and run inside a VM without compiling Core, so the wire format lives in its own target that both sides import. auditctl exists partly as a test. It’s the smallest path that exercises the analyzer end to end, which makes it the fastest way to notice you broke something.

How an audit flows

1

Ingest

A .app — or a .dmg, mounted and unmounted around the analysis — becomes a bundle path.
2

Static pass

Roughly forty detectors under Analysis/ run over the bundle: signing, entitlements, Mach-O inspection, string scanning, SDK fingerprinting, Privacy Manifest reading, and the rest. Each emits signals.
3

Classification

A behaviour pass turns combinations of signals into findings with a risk tier. This is what drives the summary and the batch scan table.
4

Enrichment

Optional and network-bound: App Store privacy labels for Mac App Store bundles.
5

Dynamic pass (optional)

The app is launched under observation. Monitoring/ collects file events (via the helper), network destinations, processes, device access, USB, and resource usage — or receives the same from a VM guest.
6

Report

Persisted to History, and exportable as JSON, HTML or PDF.

Reading the source

  • Sources/privacycommandCore/Analysis/ — the detectors, roughly forty files
  • Sources/privacycommandCore/Monitoring/ — dynamic observation
  • Sources/privacycommandCore/Classification/ — signals to findings
  • Sources/privacycommandCore/KnowledgeBase/ — the plain-English explanations
  • Sources/privacycommandCore/IPC/ — the helper’s XPC protocol
  • Sources/privacycommandCore/Batch/ — fleet scanning
  • Sources/privacycommandCore/Reporting/ — exports
The repo’s own ARCHITECTURE.md carries the longer version.