Audit
The sync script's --check proves an app's copy is current. The audit shows whether anything uses it.
Running it
npm run audit ../app-one ../app-two # from here, across checkouts
node scripts/audit-ds.mjs # from inside one app
node scripts/audit-ds.mjs --detail # every finding, with file:line
node scripts/audit-ds.mjs --max 60 # exit 1 over budget, for CIWhat it counts
Adoption is which tokens and components an app uses, which registry items it has installed and how many of their ob-* classes it uses, and which theme it imports. It reads the theme and components from ds/, or from node_modules/obvious for an app that installs it from npm.
Bypass is everything that went around the system, with a line each for literal colours, durations, easing curves, font stacks, radii and px font sizes, monospace, eyebrows (capitals with letter-spacing), gradient text, and fonts loaded that the theme doesn't name. Bypass is the one to watch.
It won't reach zero. Icons need literal fills and Brookwood doesn't take the interaction layer. The aim is a small number that's going down, and --max is there so CI can hold it.
Exceptions
When something is meant to stay, say why in the app's .ds-audit.json. ignore excuses every category in those paths. An entry under exceptions excuses one category, and only counts if it has a note.
{
"ignore": ["tools/"],
"note": "tools/ is a standalone preview harness.",
"exceptions": {
"gradient-text": { "ignore": ["src/hero.css"], "note": "The gold headline. I chose it." }
}
}Exceptions only hide findings. Tokens used in an ignored file still count towards adoption.