Before you open a PR
- Run the tests.
swift testfromprivacycommand/, and confirm they pass. - For UI changes, attach a before/after screenshot.
- For a new analysis signal, add its Knowledge Base entry. See below.
The Knowledge Base contract
This is the one convention that isn’t negotiable. privacycommand explains what every finding means in plain English. A raw entitlement key or a matched string is not a finding — it becomes one when a reader who isn’t a macOS internals specialist can tell what it implies. So a new detector is not complete without a Knowledge Base entry alongside it. The entry should say what the signal is, why an app might legitimately have it, and what would make it concerning. That last part matters. Most signals are dual-use: anti-analysis checks are common in DRM, a launch daemon is reasonable for a VPN client. An entry that only says “this is bad” makes the report worse, not better.Writing a detector
Detectors live inSources/privacycommandCore/Analysis/. Keep them there, and
keep them free of AppKit — nothing under Analysis/ imports it today — so they
stay testable from swift test and usable from auditctl.
Useful habits:
- Prefer evidence over inference. Report what was found and where. Let the behaviour pass combine signals into findings.
- Make it traceable. Every detection should be able to show what matched. The telemetry callout shows the matched strings behind every SDK, and new detectors should meet the same bar.
- Test against a real bundle.
auditctlagainst a system app is the fastest check that a detector behaves on real input.