“Please only change the drafts” is a sensible working instruction. But it is not yet a technical checkpoint. A hook can apply a recurring rule at the point where a specific action has been prepared. This turns a general request into a verifiable decision about a particular tool call.
The Claude Code reference describes PreToolUse, among other events: it occurs after the tool parameters have been created and before the call is processed. The hook can return a decision. The following examples explain a draft of our own; no hook configuration was installed or run for them.
What information is available at the decision point?
Our learning project contains a drafts folder and a reference file next to it. The agent should only edit drafts. A sensible rule therefore looks at the specific target of a write action. It does not decide whether the entire content of the conversation is trustworthy.
The interface provides the tool name and the input. For a suitable file request, the target can be determined from them. An unknown tool or an incomprehensible input should trigger a state of its own. A silent error in the checking program must not look like a successfully checked path.
A decision is a structured return value
An illustrative denial value in the documented PreToolUse structure looks like this. The reason is our own wording; it describes the local rule, not a general assessment of the user.
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "The target file is outside the drafts area."
}
}
This excerpt is the return value, not a complete checking program. It contains neither the registration of the hook nor the reading and checking of the input. This very separation is helpful: the rule, the technical evaluation and the interface output can be looked at independently.
Belonging to a path is more than a matching prefix
A mere comparison of character strings can confuse neighbouring folders with similar names. Your own rule should therefore work with unambiguously resolved paths and check whether the target actually belongs to the intended root folder. Different separators and links have to be taken into account in the environment in use.
own rule logic, schematic:
Input fully readable? Otherwise check status unknown.
Tool belongs to the write path being handled? Otherwise not checked.
Resolve target and permitted root unambiguously.
Target really inside the root? Otherwise deny.
Assess only the specific call being handled.
This sketch deliberately does not suggest complete protection. External programs in particular, which themselves change further files, need different consideration from a single file field. A permitted start file says nothing yet about which follow-up actions a script carries out.
Four probes make the reach visible
In a throwaway project, create a permitted file, a protected reference and a neighbouring folder with a similar name. Add an invalid input. For each case, write down beforehand which decision is expected. Then look at both the return value and the actual execution.
Also test a failure of the checking program itself. The failure behaviour depends on the event and the configuration and is therefore part of acceptance. A missing message is no evidence that the rule was checked successfully.
For each probe, also note whether the hook was reached at all. An action that takes a different route can bypass the rule without its internal path check having worked incorrectly.
A hook is not a complete protective framework
PreToolUse concerns tool calls. Context can enter the session by other routes; the current reference explicitly describes limits in this respect. A hook therefore replaces neither permissions nor control of the environment, and it is not a general safeguard against prompt injection.
Start with a single local rule and document the routes it covers and does not cover. The technical gain lies in an understandable checkpoint. Whether this checkpoint is set up correctly in your version has to be shown by an actual trial with the appropriate interfaces.
Sources and documentation status: 25 October 2026.

