Block Marking a Filing Draft Final Without a Reviewer Tag
A generated draft that an agent itself labels "FINAL" can end up treated as final by whoever reads the file next, regardless of whether a human actually reviewed it. This requires an explicit `REVIEWER=` tag to appear in the same write before FINAL/APPROVED is allowed through.
1. Save this as the hook script
#!/usr/bin/env python3
"""PreToolUse hook — blocks a FINAL/APPROVED marker in filing content
unless a REVIEWER= tag is present. Wire to Write|Edit."""
import json, re, sys
data = json.load(sys.stdin)
content = (data.get("tool_input") or {}).get("content", "") or \
(data.get("tool_input") or {}).get("new_string", "")
if re.search(r"(?i)\b(FINAL|APPROVED)\b", content) and not re.search(r"REVIEWER=\S+", content):
print("BLOCKED: content marks this draft FINAL/APPROVED with no REVIEWER= "
"tag. Add the reviewer's name before this status is written.", file=sys.stderr)
sys.exit(2)
sys.exit(0)
Save to a path inside your project, e.g. .claude/hooks/block-filing-final-without-reviewer-tag.sh, then chmod +x it.
2. Wire it into .claude/settings.json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{"type": "command", "command": "python3 .claude/hooks/block-filing-final-without-reviewer-tag.py"}
]
}
]
}
}
Before you use this
A hook runs with your local shell's permissions — review the script above before adding it, the same way you'd review any script you didn't write yourself. See our guide on hook security risks for the specific CVEs this category of feature has already produced.
Related hooks