Private
Public Access
Adds a tier-2 pre-commit hook that auto-unstages sandbox-only files from any tier-2 commit, preventing the leak that hit master in00e5a3f2(the offender commit that was just selectively reverted infab2e55b). The hook is paired with a config file that lists the forbidden paths as substring patterns. Design: - Hook reads conductor/tier2/githooks/forbidden-files.txt (one substring pattern per line; # comments and blanks ignored) - For each staged file, checks if any pattern is a substring of the path. If a match is found, the file is auto-unstaged via `git rm --cached --force` (force is required when the index has content that differs from BOTH HEAD and the working tree) - Hook always exits 0 — it removes the leak rather than blocking the commit. A hard reject would leave tier-2 stuck mid-flow (tier-2 cannot run `git restore --staged`, which is banned by the sandbox permission rules) - The hook's config file lives at the project root so it ships with the clone. setup_tier2_clone.ps1 will install the hook in a follow-up commit; existing clones need to re-run setup to get the hook Forbidden patterns (substring matches): - .opencode/agents/tier2-autonomous (sandbox agent prompt) - .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 cases): - Empty staged set: git's standard "nothing to commit" error - Allowed files: commit succeeds normally - Each forbidden file (agent, command, opencode.json, mcp_paths.toml) staged: auto-unstaged, commit proceeds - Mixed staged set: only forbidden are unstaged - Hook silent when no leaks detected - Hook warns (stderr) when unstaging - Config-driven: replacing forbidden-files.txt changes the denylist without modifying the hook - Paths with spaces: handled correctly via git diff -z Defense-in-depth context: - Layer 1: OpenCode permission system (denies direct edits to these files from the tier2-autonomous agent) - Layer 2 (this commit): pre-commit hook (removes the leak at the commit boundary) - Layer 3 (follow-up commit): scripts/audit_tier2_leaks.py (scans working tree, CI gate)
38 lines
1.6 KiB
Plaintext
38 lines
1.6 KiB
Plaintext
# Tier 2 autonomous mode: file denylist for pre-commit hook.
|
|
#
|
|
# One pattern per line. Each pattern is matched as a substring against
|
|
# the staged file's relative path. Lines starting with `#` and blank
|
|
# lines are ignored.
|
|
#
|
|
# These files are tier-2 sandbox-specific:
|
|
# - setup_tier2_clone.ps1 modifies opencode.json and mcp_paths.toml
|
|
# IN the clone (points MCP server at the clone, clears extra_dirs)
|
|
# - The .opencode/agents/tier2-autonomous.md and
|
|
# .opencode/commands/tier-2-auto-execute.md files are copied from
|
|
# conductor/tier2/agents/ and conductor/tier2/commands/ into the
|
|
# clone by setup_tier2_clone.ps1
|
|
#
|
|
# If any of these end up in a tier-2 commit (via accidental `git add .`),
|
|
# the main repo would absorb the sandbox's local config drift.
|
|
#
|
|
# PATTERN SCOPE: the patterns below are SPECIFIC (not prefix-based) so
|
|
# they do not match the interactive Tier 2 agent prompt at
|
|
# .opencode/agents/tier2-tech-lead.md (which legitimately lives in the
|
|
# main repo). Edit this file when adding new tier-2 sandbox-specific
|
|
# paths.
|
|
|
|
# Tier-2 autonomous agent prompt (only in clone, canonical source:
|
|
# conductor/tier2/agents/tier2-autonomous.md)
|
|
.opencode/agents/tier2-autonomous
|
|
|
|
# Tier-2 autonomous slash command (only in clone, canonical source:
|
|
# conductor/tier2/commands/tier-2-auto-execute.md)
|
|
.opencode/commands/tier-2-auto-execute
|
|
|
|
# OpenCode config: setup_tier2_clone.ps1 overrides MCP server path +
|
|
# default_agent + model in the clone's copy of this file
|
|
opencode.json
|
|
|
|
# MCP allowed paths: setup_tier2_clone.ps1 clears extra_dirs in the
|
|
# clone's copy of this file
|
|
mcp_paths.toml |