5.1 KiB
Tier 2 Sandbox File Leak Prevention — Spec
Track: tier2_leak_prevention_20260620
Created: 2026-06-20
Type: fix (recovery + defense-in-depth)
Scope: 5 new files, 1 modified file, 4 commits
Background
On 2026-06-19, commit 00e5a3f2 ("chore(env): pre-existing tier2 setup files") was pushed to origin/master. The commit contained 9 file changes:
| Status | File | Notes |
|---|---|---|
| ADDED | .opencode/agents/tier2-autonomous.md |
tier-2 SANDBOX agent (canonical source: conductor/tier2/agents/tier2-autonomous.md) |
| ADDED | .opencode/commands/tier-2-auto-execute.md |
tier-2 SANDBOX command (canonical source: conductor/tier2/commands/tier-2-auto-execute.md) |
| MODIFIED | opencode.json |
tier-2 sandbox overrode MCP path → manual_slop_tier2, default_agent → tier2-autonomous, model → minimax-coding-plan/MiniMax-M3 |
| MODIFIED | mcp_paths.toml |
tier-2 sandbox cleared extra_dirs to [] |
| MODIFIED | project_history.toml |
timestamp update only (out of scope) |
| ADDED | scripts/tier2/artifacts/.../*.py |
4 throwaway scripts (out of scope; legitimately tier-2 working artifacts) |
The commit message ("pre-existing tier2 setup files") was misleading. The actual root cause: setup_tier2_clone.ps1 legitimately modifies these files in the clone (C:\projects\manual_slop_tier2\), but the modifications leaked into the main repo via an accidental git add . in the tier-2 clone. The canonical sources live at conductor/tier2/* (per setup_tier2_clone.ps1:48-49); the main repo should NEVER see the sandbox's local config drift.
What the user asked for
- Selective revert of the offending files:
./opencode/*,mcp_paths.toml,opencode.json. Leave the 4 throwaway scripts andproject_history.tomltimestamp at HEAD per the user's explicit list. - A way to make sure tier-2 autonomous never commits those files — explicitly NOT via gitignore.
Design
Layer 1 (existing): OpenCode permission system
The tier-2-autonomous agent profile denies direct edits to the forbidden files. This was already in place but the deny rules didn't cover the auto-modifications done by setup_tier2_clone.ps1 (the script itself writes the files, not the agent directly).
Layer 2 (this track): pre-commit hook at the commit boundary
conductor/tier2/githooks/pre-commit:
- Reads
conductor/tier2/githooks/forbidden-files.txt(substring patterns, one per line) - For each staged file, checks if any pattern is a substring of the path
- Auto-unstages matching files via
git rm --cached --force - Always exits 0 (removes the leak rather than blocking the commit, since tier-2 cannot run
git restore --stagedper the sandbox permission rules) - Hook source lives at
conductor/tier2/githooks/pre-commit; config lives alongside asconductor/tier2/githooks/forbidden-files.txt
Layer 3 (this track): working-tree audit
scripts/audit_tier2_leaks.py:
- Default mode (informational, exit 0): scans working tree for forbidden files
--strictmode (CI gate, exit 1 if leaks): catches anything the hook missed (manual edits, ops mistakes)--jsonmode: machine-readable output for CI integration- Skips
tests/,conductor/,node_modules/,.git/, etc. - Reports only
untrackedandmodifiedfiles (tracked-and-clean files are legitimate)
Hook installation
scripts/tier2/setup_tier2_clone.ps1 step 4 (Install git hooks) is updated to copy the new pre-commit hook into the clone's .git/hooks/ directory alongside the existing pre-push and post-checkout hooks. The forbidden-files.txt config is already committed to the clone (as part of the canonical conductor/tier2/* source), so the hook can find it via the project root.
Forbidden patterns (substring matches)
.opencode/agents/tier2-autonomous # sandbox agent, NOT the interactive tier2-tech-lead
.opencode/commands/tier-2-auto-execute # sandbox slash command
opencode.json # MCP path / default_agent / model override
mcp_paths.toml # extra_dirs cleared in clone
Patterns are SPECIFIC (not prefix-based) so they do not match the legitimate interactive tier-2 tech-lead prompt at .opencode/agents/tier2-tech-lead.md.
Tests
tests/test_tier2_pre_commit_hook.py(12 tests): pre-commit hook behaviortests/test_audit_tier2_leaks.py(13 tests): audit script behavior
All 25 tests pass.
Files changed
| Status | File |
|---|---|
| NEW | conductor/tier2/githooks/pre-commit |
| NEW | conductor/tier2/githooks/forbidden-files.txt |
| NEW | scripts/audit_tier2_leaks.py |
| NEW | tests/test_tier2_pre_commit_hook.py |
| NEW | tests/test_audit_tier2_leaks.py |
| MODIFIED | scripts/tier2/setup_tier2_clone.ps1 |
Out of scope
- Wiring
audit_tier2_leaks.py --strictinto CI (deferred to a follow-up track) - Rebasing stale tier-2 branches on the new master tip (user action required; see
TRACK_COMPLETION_tier2_leak_prevention_20260620.md§Next Steps) - The 4 throwaway scripts in
scripts/tier2/artifacts/.../*.py(legitimate tier-2 working artifacts per the tier-2 convention) - The
project_history.tomltimestamp update (harmless side effect)