Next-Gen App & Browser Testing Cloud
Trusted by 2 Mn+ QAs & Devs to accelerate their release cycles

Pre-action checks for AI coding agents compared: permission modes, PreToolUse hooks, sandboxes, and branch rules, plus where each control fails.

Siddhant Sinha
Author

Samyak Goyal
Reviewer
Published on: August 26, 2026
Give a coding agent shell access and it will eventually run something you did not intend. Most teams respond by adding an approval prompt.
That works for a week. Then the prompts become noise, and the person clicking through them stops reading.
That prompt is one kind of pre-action check, the family of controls deciding whether an agent may act at all. The ones that hold under load share a property.
TL;DR
Pre-action checks decide whether an agent may perform an action. They come in four layers with very different failure modes, and the ones depending on a human reading a prompt are the weakest of the set.
A pre-action check runs before a tool call executes and decides whether it is allowed. It governs what an agent may touch, and never whether the change it wants to make is correct.
That distinction is the whole subject. Prevention limits blast radius, and blast radius is not the same thing as quality.
An agent can stay perfectly inside its permissions and still ship the wrong feature. No prompt catches that, because nothing about the action looked dangerous.
Seven controls cover most setups. The table sorts them by which layer they sit in, because that determines what happens when the layer above is misconfigured.
| Control | Layer | Blocks | Needs a human |
|---|---|---|---|
| Permission modes | Harness | Whole tool categories | Yes, per prompt |
| Plan mode | Harness | Everything until a plan is approved | Yes, once per task |
| PreToolUse hooks | Harness | Named commands and paths | No |
| Sandboxed execution | System | Anything outside the container | No |
| Protected paths | Repository | Writes to named files | No |
| Branch protection | Repository | Merges without review | Yes, at merge |
| CI required checks | Repository | Merges when a job fails | No |
Read the last column as a reliability score. Anything answering yes degrades under volume, and volume is the entire point of running agents.
Hooks are the most precise of the six. In Claude Code a PreToolUse hook fires before the tool call runs, and exiting with code 2 blocks it outright.
// a PreToolUse hook returning a deny decision instead of exit 2
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Destructive command blocked by hook"
}
}
// permissionDecision accepts: deny, allow, escalate
// escalate hands the decision back to the user rather than deciding for themThe escalate value is the one worth knowing. It lets a hook stay silent on routine calls and interrupt only on the cases you cannot decide programmatically.
Correctness. Every control above inspects the action an agent is about to take, and none of them knows what the finished change was supposed to do.
A permitted edit to a permitted file can still break checkout. The command looked ordinary because it was ordinary.
So the second half of the problem needs something that runs after the change exists. Kane CLI from TestMu AI covers that side, driving a real Chrome browser from a plain-language objective.
Command reference is in the Kane CLI introduction documentation. Why the check has to come from outside the agent is argued in can coding agents test their own code.
Every control on the table has a specific way it stops working. Knowing the failure mode matters more than knowing the feature.
The hook failure is the least obvious. Blocking a named command constrains one route to an outcome, not the outcome itself.
An agent that cannot call one command will often reach the same end state another way, without any intent to evade. Restricting the environment beats enumerating commands.
Because they are a decision, and decisions get cheaper each time you make one. A prompt that appears fifty times a day is not a control, it is a keystroke.
Security teams have a name for this pattern from multi-factor push notifications. The mechanism is sound and the human in the loop is the part that degrades.
Two properties tell you whether a prompt will survive contact with real usage.
So reserve prompts for the rare and the irreversible. Everything routine belongs in a hook or a sandbox where no attention is required.
Note: Prevention limits the damage. It cannot tell you the feature works. Start verifying on TestMu AI free and close the other half.
Harness controls are only as strong as the file they live in, and most teams configure the weakest one. Claude Code resolves settings through a fixed precedence chain.
| Precedence | File | Who controls it |
|---|---|---|
| 1, highest | managed-settings.json | Your organisation |
| 2 | Command line flags | You, this session |
| 3 | .claude/settings.local.json | You, this project |
| 4 | .claude/settings.json | Everyone in the project |
| 5, lowest | ~/.claude/settings.json | You, every project |
The top row is the one worth knowing. A managed policy cannot be widened by a developer having a frustrating afternoon, which makes it the only harness control with the durability of a repository rule.
Rules name a tool and what it may do. A deny entry is the useful half, because an allow list quietly grows and a deny list rarely does.
{
"permissions": {
"allow": [
"Bash(npm run lint)",
"Bash(npm run test *)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)"
]
}
}Put the deny entries in the shared project file so they travel with the repository. Anything left in a personal file protects one machine.
The layers matter because each one catches what the layer above missed. A harness control fails silently when misconfigured, and a repository control does not care how the agent was configured at all.
Teams usually build this stack inside out, starting with the harness because it is the layer they just installed. Outside in is the safer order.
Mapping real incidents to the layer that would have stopped them makes the ordering concrete.
| What went wrong | Layer that stops it |
|---|---|
| Agent force-pushed over main | Repository |
| A script reached a file outside the project | System |
| A migration ran against the wrong database | Harness, or repository if credentials are scoped |
| Secrets were written into a committed file | Repository, via protected paths |
| Checkout broke while every command was permitted | None, this is post-action |
The last row is the one worth sitting with. It is the most common failure and no pre-action layer appears in the column beside it.
For how these controls differ between harnesses, our comparison of Claude Code vs Antigravity covers the permission and review models side by side.
Order by what survives a distracted human, not by what is quickest to switch on.
The first two need no agent configuration and cannot be widened in a moment of impatience. That is why they come before the more precise tools.
Prevention and verification answer different questions. A team with only one of them is protected against exactly half of what agents get wrong.
Author
Siddhant Sinha is a Lead Member of Technical Staff at TestMu AI architecting Kane CLI, the command-line tool for browser automation from the terminal, where natural-language flows run in a real Chrome browser and return pass or fail with shareable proof. He has spent over three years at TestMu AI (formerly LambdaTest) building scalable platforms that run tests at scale on real Android and iOS devices. His expertise covers platform architecture, large-scale distributed systems, and CLI design, shaped by earlier cloud-native engineering at Semut.io, including building Elasticsearch as a service.
Reviewer
Samyak Goyal is a Senior Member of Technical Staff at TestMu AI engineering Kane CLI, the command-line tool that runs browser automation from the terminal, where a flow described in natural language executes in a real Chrome browser and returns pass or fail with shareable proof. He is a backend engineer with 4+ years of experience, previously an SDE at Innovaccer, where he built APIs, introduced Kafka, and cut deployment from weeks to hours. Samyak also builds multi-agent systems, skill-orchestration frameworks, and a personal copilot that indexes 200+ microservice repositories.
Did you find this page helpful?
More Related Blogs
TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance