The per-file list was truncated to top 15 by default. Files below
the top-15 violation ranking (e.g., the 4 UNCLEAR sites in
outline_tool.py, summarize.py, conductor_tech_lead.py,
openai_compatible.py) were hidden from the per-file output.
The fix changes the default --top from 15 to 200, which exceeds
the current project file count (65 src/ files) and leaves room
for future growth. Users can still pass --top 15 if they want a
truncated view.
The render_json filter excluded INTERNAL_COMPLIANT findings from the
per-file list in non-verbose mode:
if f.category in VIOLATION_CATEGORIES or f.category in ("UNCLEAR", "INTERNAL_RETHROW")
This meant the 25 newly-classified compliant sites from the review
pass were not visible in the per-file output. Totals were correct
but the per-file list was incomplete.
The fix removes the filter so all findings appear in the per-file
list. The totals already match (they are computed from r.findings
before the per-file filter).
The audit script's visit_Try had a bug where the
\or child in handler.body\ loop was OUTSIDE the
\or handler in node.handlers\ loop. So \handler\ was bound
to the LAST handler, and only the last handler's body was walked.
Raises in non-last except handlers were missed (e.g.,
src/rag_engine.py:31 was not in the audit findings).
The fix moves the inner loop inside the outer loop so each
handler's body is walked. Both the FIRST and LAST handler raises
are now detected.
Adds tests/test_audit_exception_handling_bug_fixes.py with 2
tests for the walker behavior (first-handler raise, middle-handler
raise in a 3-handler try).
End-of-track report for the 4 sandbox bugs hit by the first Tier 2
run (send_result_to_send_20260616) and the audit infrastructure
added to prevent regression. 5 fixes (4 bugs + 1 audit) shipped as
6 atomic commits on master.
See the report for:
- Per-fix description, root cause, and file:line refs
- Live clone state after the fixes
- 38 default-on + 3 opt-in test inventory
- 4 conventions established
- Next steps for the user (re-run, merge review branch, etc.)
- Known follow-ups NOT in this track
Tier 2 sandbox invariant: no production script under ./scripts/ may
write to the global %TEMP% directory (C:\\Users\\Ed\\AppData\\Local\\
Temp\\). All scratch / intermediate files must live in:
- ./tests/artifacts/ (for test artifacts)
- C:\\Users\\Ed\\AppData\\Local\\manual_slop\\tier2\\ (for app data)
Writing to %TEMP% breaks the sandbox boundary: the OpenCode session
fires the 'ask' prompt for paths outside the project root, halting
autonomous ops (the 2026-06-17 bug with audit_exception_handling.py
output being written to %TEMP% by the agent's shell redirection).
Convention enforcement (per conductor/workflow.md Audit Script Policy):
- scripts/audit_no_temp_writes.py: the canonical audit. Same shape
as scripts/audit_exception_handling.py: --json for machine output,
--strict for the CI gate (exits 1 on any violation). Patterns
cover tempfile module, os.environ['TEMP'], C:\Users\Ed\AppData\Local\Temp, %TEMP%,
/tmp/, etc. Excludes the throw-away archive at scripts/tier2/
artifacts/ and itself (so it can find its own pattern defs).
- tests/test_no_temp_writes.py: default-on regression test. Calls
the audit with --strict and asserts exit 0. If a new script
under ./scripts/ ever uses %TEMP%, the test fails and CI breaks.
Current state: CLEAN. All 36 tier2 tests pass (1 new + 16 slash
command spec + 13 failcount + 6 opt-in). Sanity-checked: dropping
a fake 'import tempfile' script into ./scripts/ triggered exit 1
with 'FOUND 1 matches: scripts/_test_temp_check/test_uses_temp.py:1:
import tempfile'.
Future: also add a corresponding deny rule to the sandbox bash
permission in a follow-up if needed (already added in 03c9df84 for
the agent's own bash). The audit + test is the structural guard.
The Tier 2 agent wrote audit_exception_handling.py output to
C:\\Users\\Ed\\AppData\\Local\\Temp\\audit_initial.json via shell
redirection. This is OUTSIDE the sandbox allowlist (which is
C:\\projects\\manual_slop_tier2 + C:\\Users\\Ed\\AppData\\Local\\
manual_slop\\tier2 + C:\\Users\\Ed\\AppData\\Local\\manual_slop\\
tier2_failures). The OpenCode session-level guard fires the 'ask'
prompt for paths outside the project root, which has no answer in an
autonomous session, so ops halted mid-track.
Fix (3 layers):
1. opencode.json.fragment: add bash deny rule
'*AppData\\Local\\Temp\\*': 'deny' to BOTH the top-level
permission.bash (for default agents) and the tier2-autonomous
agent's permission.bash. The agent physically cannot run shell
commands that target the global Temp dir.
2. conductor/tier2/agents/tier2-autonomous.md: add 'Temp files'
convention telling the agent to use
C:\\Users\\Ed\\AppData\\Local\\manual_slop\\tier2\\ for scratch
/ audit-output / intermediate files, NOT %TEMP%.
3. conductor/tier2/commands/tier-2-auto-execute.md: same convention
in the slash command so the agent sees it at slash-command time.
Tests (default-on):
- test_agent_denies_temp_writes: agent prompt has the Temp deny in
frontmatter bash + the app-data dir note
- test_config_fragment_denies_temp_writes: both top-level and agent
bash have the deny rule
All 16 tier 2 slash command tests pass.
Also: cleaned up the leaked audit_initial.json + audit.json +
audit_after*.json from %TEMP% (they were leftovers from a prior
run). Re-ran setup against the live clone; opencode.json's agent
bash and top-level bash both have the deny rule.