protect_raw_export.py
hooks/protect_raw_export.py
#!/usr/bin/env python3
"""PreToolUse hook: only the scripts read the raw OPERA export, never the agent.
The export has guest-level sections. The permission rules deny the Read tool on
data/opera/, and this hook closes the other doors: a shell command (cat, grep,
head, a one-line python) or a search tool pointed at that folder. The only
command allowed to touch it is a plain `python3 scripts/<name>.py ...` call,
with no chaining, pipes or redirects. Exit code 2 blocks the call.
"""
import json
import re
import sys
RAW = re.compile(r"data/opera")
SCRIPT_ONLY = re.compile(r"^\s*python3\s+scripts/[\w.-]+\.py(\s+[^;&|<>`$()\n]*)?\s*$")
def main() -> int:
call = json.load(sys.stdin)
tool, args = call.get("tool_name", ""), call.get("tool_input", {})
if tool == "Bash":
cmd = args.get("command", "")
if RAW.search(cmd) and not SCRIPT_ONLY.match(cmd):
print("Blocked: only the scripts read the raw OPERA export. Run scripts/normalize.py and use outputs/normalized/.",
file=sys.stderr)
return 2
if tool in ("Read", "Grep", "Glob"):
target = " ".join(str(args.get(k, "")) for k in ("file_path", "path", "pattern", "glob"))
if RAW.search(target):
print("Blocked: the raw OPERA export is not for the agent. Use outputs/normalized/.", file=sys.stderr)
return 2
return 0
if __name__ == "__main__":
try:
sys.exit(main())
except Exception as err: # fail closed
print(f"Hook error, call blocked: {err}", file=sys.stderr)
sys.exit(2)