Zerf home

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)