Enforce before acting
Retrieval tells an agent what the policy is; check_action stops it from breaking it. Call it right
before a side-effectful step and branch on the verdict: proceed on allowed, stop and cite the rule
on blocked, escalate on needs_human. There are two natural places to wire it in. See
how gnt works for why enforcement has to sit outside the model's own reasoning.
Claude Code PreToolUse hook
A PreToolUse hook runs before every tool call. gnt ships one: it checks the guarded,
world-changing tools against your rules and blocks the call on blocked or needs_human, so
enforcement doesn't depend on the model choosing to ask.
Code
This writes a PreToolUse entry to ~/.claude/settings.json, wired to gnt hooks check-action.
By default it guards Bash, Write, Edit, NotebookEdit, and WebFetch — reads (Grep,
Glob, Read, WebSearch) pass through untouched, since check_action's retrieval + LLM-judge
round trip has real latency and there's nothing to enforce on a read. Widen or narrow the matcher
in ~/.claude/settings.json after installing if you want to gate an installed connector's own
mcp__* tools too.
Most checks retrieve your rules and run a real model judgment against them, so expect a couple of
seconds on a genuine side-effectful call — that's the cost of grounding a verdict in your actual
rules rather than guessing. A small set of routine, read-only commands (a bare ls, pwd, git status, git diff, git log, or git branch with no arguments) skip that round trip entirely and
return in milliseconds, still logged, still going through gnt — everything else, including the same
commands with flags or arguments, gets the full check.
If check_action can't complete at all (network error, gnt unreachable), the hook fails open by
default — the tool call proceeds rather than stalling your session. Pass --fail-closed at install
time to block instead whenever the check itself fails, not just on a real blocked verdict. A real
blocked verdict always blocks. needs_human follows the returned enforcement_action: Strict
requires a human, while Observe can return proceed after the uncertainty is durably audited.
Fail-open only governs what happens when gnt couldn't be reached to answer at all.
Code
No harness besides Claude Code has a pre-execution hook point gnt can install into today. Everyone else uses the system prompt pattern below.
System prompt instruction
For agents without a hook layer, add a standing policy-check instruction to the system prompt. Pair it with the hook above for defense in depth: the prompt guides the model, the hook enforces regardless.
Code