audit_tier2_leaks bug: when test fixtures (tmp_path) are inside the
parent git repo, git's git diff and git ls-files look UP for a
parent .git/ directory and report the PARENT's modified files. This
made tests/test_audit_tier2_leaks.py fail because the audit reported
mcp_paths.toml + opencode.json as 'modified' even though those are in
the parent repo, not in the clean tmp_path fixture.
Fix: set GIT_DIR to a non-existent path (repo_root/.git) in the env
passed to git subprocesses. This forces git to fail, which the audit
treats as 'no modifications' / 'no tracked files'.
test_palette_starts_hidden hardening: live_gui is session-scoped so
other tests may leave the palette open. Pre-toggle the palette before
asserting it's hidden - converts a 'depends on test ordering' test
into a 'palette is closable' test.
Verification:
- tier-1-unit-core: ALL 5 batches PASS (was 5 failures)
- tier-3-live_gui: test_gui2_custom_callback_hook_works now PASSES
(was FAILED); other live_gui flakes surface non-deterministically
per batch run (pre-existing issue, not caused by this fix)
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.