f5d8ea047a
Adds scripts/audit_tier2_leaks.py as defense-in-depth layer 3 (the pre-commit hook is layer 2; OpenCode permission rules are layer 1). The audit scans the main repo's working tree for files matching the forbidden patterns in conductor/tier2/githooks/forbidden-files.txt. Behavior: - Default mode (exit 0): informational report of any leaks found. Useful for manual inspection and pre-commit workflow. - --strict mode (exit 1 if leaks): CI gate. The hook at the commit boundary is the live guard; this is the safety net for any leak that somehow slips through (manual edits, ops mistakes). - --json mode: machine-readable output for CI integration. Detection rules: - "untracked" status: file exists in working tree but is not in HEAD and not in `git ls-files`. Indicates a leak as a new file. - "modified" status: file is in HEAD but the working tree differs. Indicates a leak in progress (tier-2 setup modified a file). - Files that are tracked and unmodified are NOT reported: the main repo legitimately tracks opencode.json, mcp_paths.toml, etc. — the patterns are about CONTENT (modifications by tier-2), not file existence. Skip rules: - .git/, node_modules/, __pycache__/, .venv/, venv/ (ignored dirs) - tests/ (test infrastructure, not user code) - conductor/ (canonical source for tier-2 files; if they're here in a leak, they were committed, not just sitting in working tree) - .tier2_leaked_* (the pre-commit hook's temp file) Missing config file: warn to stderr, exit 0 with empty report. The hook also no-ops in this case; both layers degrade safely. Tests (tests/test_audit_tier2_leaks.py, 13 cases): - Clean tree returns 0 - Each forbidden file type detected (agent, command, opencode.json, mcp_paths.toml) - Non-forbidden files ignored (including legitimate conductor/tier2/agents/tier2-tech-lead.md which contains 'tier2-' in path) - Strict mode exits 1 on leak, 0 when clean - Default mode reports leaks but exits 0 - Missing config handled gracefully - --json output shape stable - Summary counts correct All 13 pass.