| name | mac-audit |
| description | Comprehensive macOS development environment health check. Detects brew drift, orphaned packages, security issues, version mismatches, and deferred cleanup readiness. |
| argument-hint | [--section <name>] [--deferred-only] |
| allowed-tools | Bash, Read, Glob, Grep |
Purpose
Audit the macOS development environment for drift, security issues, and cleanup opportunities. Compares current state against the declared Brewfile and AUDIT.md project requirements. Produces a markdown report with pass/warn/fail indicators.
Run quarterly (or after major environment changes) to catch drift before it accumulates.
Arguments
- No arguments — run all 8 checks
--section <name> — run only one section (brew-drift, orphans, security, versions, services, disk, shell, deferred)
--deferred-only — only check deferred item readiness (quick check)
Configuration paths
BREWFILE=~/Developer/projects/macbook-clean/Brewfile
AUDIT_MD=~/Developer/projects/macbook-clean/AUDIT.md
Output format
Print a markdown report with a timestamp header and sections for each category. Use these indicators:
PASS — healthy, no action needed
WARN — not broken but worth investigating
FAIL — needs attention
Example:
## Mac Environment Audit — 2026-02-12
### 1. Brew Drift
- PASS: 0 formulae installed but not in Brewfile
- WARN: 2 formulae in Brewfile but not installed (postgresql@16, gitleaks)
Checks to perform
Run each check inline using Bash commands. Do NOT create or depend on external scripts — keep the skill self-contained.
1. Brew Drift
Goal: Detect packages that have been installed ad-hoc (not declared in Brewfile) or declared but missing.
Steps:
- Read the Brewfile at
~/Developer/projects/macbook-clean/Brewfile
- Extract all formula names (lines starting with
brew ") and cask names (lines starting with cask ")
- Run
brew leaves to get currently installed top-level formulae
- Run
brew list --cask to get installed casks
- Compare:
- Installed but not in Brewfile — potential orphans or undeclared additions
- In Brewfile but not installed — missing tools (maybe not yet installed, or removed accidentally)
- Run
brew bundle check --file=~/Developer/projects/macbook-clean/Brewfile for the official check
- Report results with PASS/WARN/FAIL
2. Orphan Detection
Goal: Find formulae that nothing depends on and no project needs.
Steps:
- For each formula found in check 1 as "installed but not in Brewfile":
- Run
brew uses --installed <formula> to see if any installed formula depends on it
- Cross-reference against known project requirements (Section 8 of AUDIT.md)
- Flag formulae with 0 dependents AND no project need as orphan candidates
- Report each orphan candidate with its status
3. Security Hygiene
Goal: Detect exposed secrets in environment and shell config.
Steps:
- Run
env | grep -iE 'token|secret|key|password' and review results
- Filter out known-safe entries (PATH, HOMEBREW keys, SSH_AUTH_SOCK, etc.)
- Flag anything that looks like an actual secret value
- Search
~/.zshrc for hardcoded credentials:
grep -inE '(token|secret|password|api_key)\s*=' ~/.zshrc
- Search
~/.zprofile for hardcoded credentials:
grep -inE '(token|secret|password|api_key)\s*=' ~/.zprofile
- Check for
.env files outside project directories:
find ~ -maxdepth 2 -name '.env' -not -path '*/Developer/projects/*' -not -path '*/.claude/*' 2>/dev/null
- Report PASS if clean, FAIL if secrets found
4. Version Health
Goal: Verify runtime versions match project requirements.
Steps:
- Check Node.js:
node --version — should be v22.x (project requirement)
which -a node — NVM path should come first, should show 1-2 entries (not more)
- Check Python:
python3 --version — should be 3.13.x
which -a python3 — should show 1-2 entries (not 4)
- Check for deprecated Homebrew formulae:
brew info --json=v2 --installed | jq '[.formulae[] | select(.deprecated == true) | .name]'
- Check for outdated critical tools:
brew outdated --json=v2 | jq '[.formulae[].name] | length' — report count
- Report PASS/WARN/FAIL per runtime
5. Service Health
Goal: Detect services that shouldn't be running, or zombie LaunchAgents.
Steps:
- Run
brew services list to get all Homebrew-managed services
- For each running service: check if it has a project need (mongodb-community for hello-mern, postgresql@16 for hello-nean)
- Flag running services with no project need as WARN
- Check for LaunchAgent plists that exist but whose service is not running:
ls ~/Library/LaunchAgents/ 2>/dev/null | grep homebrew
- Cross-reference against
brew services list — if a plist exists but service is stopped/error, flag as zombie
- Report results
6. Disk Usage
Goal: Flag large caches and scattered node_modules.
Steps:
- Check sizes of key directories (use
du -sh, suppress errors):
/opt/homebrew
~/.npm
~/Library/Caches/Homebrew
~/Library/Caches/pip
~/.nvm
~/.pnpm-store (if exists)
- Flag any cache over 1 GB as WARN
- Check for
node_modules directories outside ~/Developer/projects/:
find ~ -maxdepth 4 -name node_modules -type d -not -path '*/Developer/projects/*' -not -path '*/.nvm/*' 2>/dev/null
- Report findings with sizes
7. Shell Config Health
Goal: Detect PATH and config issues that cause confusion.
Steps:
- Check for duplicate PATH entries:
echo $PATH | tr ':' '\n' | sort | uniq -d
- Check for non-existent directories in PATH:
echo $PATH | tr ':' '\n' | while read -r d; do [ ! -d "$d" ] && echo "$d"; done
- Exclude known Apple system bootstrap paths (
/var/run/com.apple.security.cryptexd/)
- Check for duplicate aliases in
~/.zshrc:
grep '^alias ' ~/.zshrc | awk -F= '{print $1}' | sort | uniq -d
- Check if
~/.profile exists and is empty (pointless file)
- Check if
~/.bash_profile exists (leftover from bash)
- Report PASS/WARN per finding
8. Deferred Item Readiness
Goal: Check whether items deferred during remediation are now safe to remove.
For each deferred item, run the specified check and report status:
| Deferred Item | Condition to Become Safe | Check Command |
|---|
Homebrew node | No installed formulae depend on it | brew uses --installed node |
python@3.14 | semgrep no longer depends on it | brew uses --installed python@3.14 |
icu4c@76 | All dependents removed or upgraded | brew uses --installed icu4c@76 |
icu4c@77 | All dependents removed or upgraded | brew uses --installed icu4c@77 |
postgresql@14 | Data migrated to @16, @14 stopped | Check brew services list for @14 stopped AND @16 running |
Report for each item:
- SAFE TO REMOVE — condition met, dependents list is empty (or service conditions met)
- NOT YET — condition not met; list what still depends on it
- CHANGED — dependent count differs from expected baseline (worth investigating)
Expected baselines (from initial audit):
node: 4 dependents (eslint, mongodb-community, mongosh, prettier)
python@3.14: 1 dependent (semgrep)
icu4c@76: 6 dependents (eslint, maven, openjdk, openjdk@11, postgresql@14, prettier)
icu4c@77: 8 dependents (composer, libpq, mysql@8.0, openjdk@17, openjdk@21, opensearch, php, php@8.1)
postgresql@14: running via LaunchAgent
After the audit
- Present the full report to the user
- If any FAIL items exist, recommend immediate action
- If any deferred items show SAFE TO REMOVE, ask if the user wants to proceed with removal
- If orphan candidates are found, ask if they should be added to the Brewfile (intentional) or uninstalled (not needed)
- Suggest updating the Brewfile if drift is detected