Approvals
Before an agent runs a command, Warshall decides whether it may. One rule table decides for every provider, Claude Code, Codex and local endpoint models alike. A fence around the terminal’s own checkout is checked first, before any rule.
Auto mode
Settings > Terminal carries a Command approvals section with two rows.
- Auto mode is on by default. A command that matches no rule runs without asking. Turn it off and every command that matches no rule asks you first.
- Ask timeout (seconds) is 120 by default, and takes 10 to 3600. It is how long a question waits for your answer. When it runs out, the command is denied.
The rule table
Below it, Dangerous commands lists one row per rule. Each row shows the commands it covers, what they do, and three buttons for its action.
| Action | What happens |
|---|---|
| Approve | The command runs without a question. |
| Ask | The terminal asks you, and the agent waits for the answer. |
| Deny | The command is refused, and the agent is told why. |
The built in rules match the operating system you run. Rules for shell commands apply everywhere, because agents on Windows run bash commands through Git Bash. Rules for tools that exist on only one system appear only there. Operations that can destroy data or the machine default to Deny. Risky but routine ones default to Ask.
| Rule | Examples | Default |
|---|---|---|
| Recursive or forced deletion | rm -rf, and on Windows rd /s, Remove-Item -Recurse | Deny |
| Disk and filesystem tools | mkfs, dd of= on macOS and Linux, format, diskpart on Windows | Deny |
| System shutdown or reboot | shutdown, reboot | Deny |
| Force push | git push --force | Deny |
| Remote script execution | curl | sh, iwr | iex | Deny |
| Publishing packages | npm publish, cargo publish, twine upload | Deny |
| Firewall and network configuration | netsh on Windows, iptables, ufw on Linux | Deny |
| Services and scheduled tasks | schtasks on Windows, launchctl on macOS, systemctl on Linux | Deny |
| Windows registry edits | reg add, reg delete, regedit | Deny |
| History rewrite and hard reset | git reset --hard, git clean -f | Ask |
| System package managers | apt install, brew install, winget install, choco install | Ask |
| Global package installs | npm install -g | Ask |
| Killing processes | kill -9, pkill, and on Windows taskkill /f | Ask |
| Privilege elevation | sudo, runas | Ask |
| Permission rewrites | chmod -R, chown -R, and on Windows icacls, takeown | Ask |
A few rules carry their system’s own name. On Windows the disk rule reads Disk and volume tools. The services rule reads Services and launch agents on macOS and Services and units on Linux.
You can change the action of a built in rule, but not remove it.
To add your own rule, fill in the row under the list. Type a command prefix and a description, pick the action, and press Add rule. The prefix is matched as the exact text you typed, wherever it starts after a space, a separator or the start of the line. It is never read as a pattern you did not write. Your own rules have an x to remove them.
When several rules match one command, the strictest action wins. Deny beats Ask, and Ask beats Approve.
Answering a question
A command set to Ask shows up in the terminal as a card titled Approval required. It names the rule, shows the command and counts down the time left. Press Approve or Deny. If the countdown runs out, the command is denied.
Afterwards the transcript keeps one line with the command and the outcome.
Approved: git reset --hard HEAD~1
Denied: npm install -g serve
Denied (timed out): sudo apt install jqA command set to Deny never asks. The terminal prints a Blocked line with the command and the rule that stopped it.
The worktree fence
A terminal’s agent works in that terminal’s own checkout. It may not reach the project folder you opened, or any other terminal’s checkout of the project. This is enforced, not asked for in a prompt. Every tool call is checked against the run’s own directory before any approval rule.
- Anything inside the run directory is allowed.
- Anything inside the project folder or inside the app’s worktrees folder is refused, for reading and for writing.
- Changing directory out of the run directory is refused. So is a directory change the fence cannot work out, such as a path built by the command while it runs. The fence never guesses.
- Writing a file anywhere else is refused, except in the temp folder and in the provider’s own settings folder.
- Reading a file anywhere else is allowed, for example a global config or a library on disk.
The fence reads paths from the tool call’s path fields, from the paths inside a command line, and from the file lines of a patch. Environment variables that name a folder are expanded first. Plain text is never scanned, so a file that only mentions the project folder is not treated as touching it.
A refused call shows in the terminal as a Blocked line marked outside the checkout. The agent is told which directory it should work in, so it corrects itself on the next call.
The fence judges each call by its own text. It cannot see a path that a script builds after it starts running.
On the phone
A paired phone shows the same approval card on the terminal it belongs to, with Approve and Deny. You can answer on either device. The first answer counts, and the card disappears from the other.
When something fails
The gate fails closed. If a decision cannot be made or an answer cannot be read, the call is denied with the reason. It is never let through by default.
- If Codex’s approval hook cannot be written, the run does not start and the terminal reads Failed to write the approval hook.
- A custom rule that cannot be read is skipped, and every other rule still applies.