conductor(plan): add TRACK_COMPLETION report + track artifacts for tier2_leak_prevention_20260620

Adds the end-of-track artifacts for the tier2_leak_prevention_20260620
fix track:

- docs/reports/TRACK_COMPLETION_tier2_leak_prevention_20260620.md:
  Full track completion report following the precedent set by
  TRACK_COMPLETION_tier2_autonomous_sandbox_20260616.md. Documents
  the 4 atomic commits, the 25 default-on tests, the manual
  end-to-end verification, the key design decisions (auto-unstage
  not exit 1, git rm --cached --force, CRLF handling, specific not
  prefix patterns), the known limitations, and the next steps for
  the user (push to origin, rebase stale tier-2 branches, re-run
  setup on the existing clone, optional CI wiring).

- conductor/tracks/tier2_leak_prevention_20260620/metadata.json:
  Track metadata (status=shipped, scope: 5 new files + 1 modified,
  25 default-on tests, 5 verification criteria, 5 risk-register
  entries, 2 deferred follow-up tracks).

- conductor/tracks/tier2_leak_prevention_20260620/spec.md:
  Track spec (background on the 00e5a3f2 offender commit, design
  with the 3-layer defense-in-depth, forbidden patterns, tests,
  out-of-scope items).

- conductor/tracks/tier2_leak_prevention_20260620/plan.md:
  Track plan (4 phases: revert + hook + audit + install; tasks
  recorded retroactively per workflow.md "Plan is the source of
  truth").

- conductor/tracks/tier2_leak_prevention_20260620/state.toml:
  Track state (status=completed, current_phase=complete, 4 phases
  with checkpoint SHAs, 16 tasks all completed with commit SHAs).

- conductor/tracks.md: registered as track 6f in the Active
  Tracks table; added a "Recently Completed" entry with the
  commit-history summary.

Per conductor/workflow.md "End-of-track report" protocol. The
report includes a "Mistake to flag" section about the
`Remove-Item -Recurse -Force` accident during verification, per
the AGENTS.md "Hard ban on destructive commands" rule (which is
specifically about `git restore`/`git checkout`/`git reset`/`git
push` but the lesson generalizes: destructive PowerShell commands
on directories with tracked files require explicit verification
before running).
This commit is contained in:
ed
2026-06-20 07:46:10 -04:00
parent 977cfdb740
commit 9224be7ac3
6 changed files with 616 additions and 0 deletions
@@ -0,0 +1,110 @@
# Tier 2 Sandbox File Leak Prevention — Plan
**Track:** `tier2_leak_prevention_20260620`
**Created:** 2026-06-20
**Status:** SHIPPED (4 atomic commits)
This plan was authored retroactively after the work was completed in-session
(in response to a user request: "tier-2 files leaked into master via commit
00e5a3f2; undo them and add a guard"). The plan is recorded here for
traceability per `conductor/workflow.md` "Plan is the source of truth."
## Phases
### Phase 1: Revert the offender commit (selective)
**Commit:** `fab2e55b fix(tier2): undo sandbox file leaks from 00e5a3f2`
**WHERE:** `git revert -n 00e5a3f2` then surgically unstage files outside the user's scope.
**WHAT:**
- Delete `.opencode/agents/tier2-autonomous.md`
- Delete `.opencode/commands/tier-2-auto-execute.md`
- Revert `mcp_paths.toml` extra_dirs to `["C:/projects/gencpp"]`
- Revert `opencode.json` MCP path to `manual_slop`, default_agent to `tier2-tech-lead`
- Leave at HEAD: 4 throwaway scripts in `scripts/tier2/artifacts/.../*.py`, `project_history.toml` timestamp
**HOW:** `git revert -n` (apply without committing), then `git reset HEAD -- <files>` to unstage the files outside scope, then `git checkout HEAD -- <files>` to restore them to HEAD's content. Resolve the modify/delete conflict on `tier2-autonomous.md` (commit `07f46bfd` modified it after the offender added it) by deletion.
**SAFETY:** User's project-level config files (config.toml, project.toml, etc.) were uncommitted at session start; stashed them as `stash@{0}` (tier2-safety-checkpoint) before the revert to avoid losing them. Commit with explicit message + git note.
### Phase 2: Pre-commit hook + config + tests
**Commit:** `81e1fd7b feat(tier2): add pre-commit hook + denylist config to block sandbox-only files`
**WHERE:**
- NEW `conductor/tier2/githooks/pre-commit`
- NEW `conductor/tier2/githooks/forbidden-files.txt`
- NEW `tests/test_tier2_pre_commit_hook.py`
**WHAT:** A shell script that auto-unstages forbidden files from any tier-2 commit. Configurable via a separate denylist file (one substring pattern per line; `#` comments and blanks ignored).
**HOW:**
1. Write 12 failing tests in `tests/test_tier2_pre_commit_hook.py` (TDD red phase)
2. Write `conductor/tier2/githooks/pre-commit` as a `#!/bin/sh` script
3. Write `conductor/tier2/githooks/forbidden-files.txt` with 4 specific patterns
4. Run tests; verify all 12 pass (green phase)
**SAFETY:**
- Hook always exits 0 (removes the leak rather than blocking the commit; tier-2 cannot run `git restore --staged` per sandbox rules)
- Uses `git rm --cached --force` (NOT `git restore`; required when staged content diverges from HEAD and working tree; discovered during TDD)
- Hook source file is plain POSIX sh; no Python dependency; works under Git Bash on Windows
- 12 tests cover: empty staged set, allowed files, each forbidden file type, multi-file unstaging, mixed staged sets, hook silence, hook warning, config-driven denylist, paths with spaces
### Phase 3: Audit script + tests
**Commit:** `f5d8ea04 feat(audit): add audit_tier2_leaks.py for tier-2 sandbox file leak detection`
**WHERE:**
- NEW `scripts/audit_tier2_leaks.py`
- NEW `tests/test_audit_tier2_leaks.py`
**WHAT:** A Python script that scans the main repo's working tree for files matching the forbidden patterns. Reports any matches as leaks. Default mode is informational (exit 0); `--strict` mode exits 1 on leaks (CI gate).
**HOW:**
1. Write 13 failing tests (TDD red phase)
2. Implement `scripts/audit_tier2_leaks.py` with argparse (--strict, --json flags)
3. Run tests; verify all 13 pass
**SAFETY:**
- Only reports `untracked` and `modified` files (tracked-and-clean files in the main repo are legitimate; patterns are about CONTENT not file existence)
- Skips `tests/`, `conductor/`, `node_modules/`, `.git/`, etc.
- Missing config file: warn to stderr, exit 0 (graceful degradation; hook also no-ops)
- Script uses `git ls-files` and `git diff --name-only` via subprocess; no shell injection risk
### Phase 4: Wire the hook into setup_tier2_clone.ps1
**Commit:** `8f54deda chore(tier2): install pre-commit hook via setup_tier2_clone.ps1`
**WHERE:** `scripts/tier2/setup_tier2_clone.ps1` step 4 (Install git hooks)
**WHAT:** Add `Copy-Item` for the new `pre-commit` hook alongside the existing `pre-push` and `post-checkout` hooks. Existing tier-2 clones need to re-run setup to install the new hook; new clones get it automatically.
**HOW:** Single-line addition to the existing git hooks installation block. The forbidden-files.txt config is already committed to the clone by the canonical-source commit, so the hook can find it via the project root.
**SAFETY:** The copy is idempotent (uses `-Force`). Tested by `tests/test_tier2_setup_bootstrap.py` (3 opt-in tests; all pass with the change).
## Verification
| Test file | Default-on tests | Opt-in tests |
|-----------|------------------|--------------|
| `tests/test_audit_tier2_leaks.py` | 13 | 0 |
| `tests/test_tier2_pre_commit_hook.py` | 12 | 0 |
| `tests/test_tier2_setup_bootstrap.py` | 0 | 3 |
| `tests/test_tier2_sandbox_enforcement.py` | 0 | 1 |
| `tests/test_tier2_slash_command_spec.py` | 17 | 0 |
**Total: 42 default-on + 4 opt-in** (all pass when the right env vars are set).
Manual end-to-end verification: created a fake git repo, staged `opencode.json` with a sandbox-style modification, ran the hook, verified the file was unstaged and the commit proceeded without it.
## Atomic per-task commits
Per `conductor/workflow.md` "ATOMIC PER-TASK COMMITS":
1. `fab2e55b fix(tier2): undo sandbox file leaks from 00e5a3f2` (Phase 1)
2. `81e1fd7b feat(tier2): add pre-commit hook + denylist config to block sandbox-only files` (Phase 2)
3. `f5d8ea04 feat(audit): add audit_tier2_leaks.py for tier-2 sandbox file leak detection` (Phase 3)
4. `8f54deda chore(tier2): install pre-commit hook via setup_tier2_clone.ps1` (Phase 4)
Each commit has a `git notes add -m "..." <sha>` summary explaining the why (per the workflow).