WARSHALL
Docs/Agents/Approvals

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.

ActionWhat happens
ApproveThe command runs without a question.
AskThe terminal asks you, and the agent waits for the answer.
DenyThe 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.

RuleExamplesDefault
Recursive or forced deletionrm -rf, and on Windows rd /s, Remove-Item -RecurseDeny
Disk and filesystem toolsmkfs, dd of= on macOS and Linux, format, diskpart on WindowsDeny
System shutdown or rebootshutdown, rebootDeny
Force pushgit push --forceDeny
Remote script executioncurl | sh, iwr | iexDeny
Publishing packagesnpm publish, cargo publish, twine uploadDeny
Firewall and network configurationnetsh on Windows, iptables, ufw on LinuxDeny
Services and scheduled tasksschtasks on Windows, launchctl on macOS, systemctl on LinuxDeny
Windows registry editsreg add, reg delete, regeditDeny
History rewrite and hard resetgit reset --hard, git clean -fAsk
System package managersapt install, brew install, winget install, choco installAsk
Global package installsnpm install -gAsk
Killing processeskill -9, pkill, and on Windows taskkill /fAsk
Privilege elevationsudo, runasAsk
Permission rewriteschmod -R, chown -R, and on Windows icacls, takeownAsk

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 jq

A 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.