Guardrails
Make your agent ask before it destroys something
Each rule makes the agent stop and ask before running a matching command, rather than banning it: these commands have legitimate uses, and in these incidents the failure was running them with no human looking. Cursor documents no deny list, so it is not here; use its sandboxed Run Mode (docs).
Claude Code
Add to .claude/settings.json in the project (or ~/.claude/settings.json for every project). Each matching command then asks you first, including in auto mode.
{
"permissions": {
"ask": [
"Bash(rm -r*)",
"Bash(rm -fr*)",
"Bash(rm -R*)",
"Bash(find * -delete*)",
"PowerShell(Remove-Item *)",
"Bash(cmd /c rmdir *)",
"Bash(cmd /c del *)",
"Bash(git reset --hard*)",
"Bash(git clean *)",
"Bash(git push --force*)",
"Bash(git push -f*)",
"Bash(git stash drop*)",
"Bash(git filter-repo*)",
"Bash(git worktree remove *)",
"Bash(npx prisma db push*)",
"Bash(prisma db push*)",
"Bash(npx prisma migrate reset*)",
"Bash(npx drizzle-kit push*)",
"Bash(drizzle-kit push*)",
"Bash(pnpm prisma db push*)",
"Bash(pnpm drizzle-kit push*)",
"Bash(terraform destroy*)",
"Bash(docker rm *)",
"Bash(docker volume rm *)",
"Bash(docker system prune*)",
"Bash(diskutil *)",
"Bash(lftp *)",
"Bash(rsync * --delete*)"
]
}
}Stronger control: Turn on the sandbox (/sandbox): shell commands can then write only to the project, a temp folder and directories you add. It runs on macOS, Linux and WSL2; on native Windows Claude Code runs commands unsandboxed. Docs
Codex
Save as ~/.codex/rules/stupidllm.rules and restart Codex. Codex's docs describe rules as controlling commands run outside its sandbox, and mark them experimental.
prefix_rule(pattern = ["rm", ["-r", "-rf", "-fr", "-R"]], decision = "prompt", justification = "Recursive delete: confirm the target first")
prefix_rule(pattern = ["git", "reset", "--hard"], decision = "prompt")
prefix_rule(pattern = ["git", "clean"], decision = "prompt")
prefix_rule(pattern = ["git", "push", ["--force", "-f"]], decision = "prompt")
prefix_rule(pattern = ["git", "stash", "drop"], decision = "prompt")
prefix_rule(pattern = ["git", "filter-repo"], decision = "prompt")
prefix_rule(pattern = ["git", "worktree", "remove"], decision = "prompt")
prefix_rule(pattern = ["npx", "prisma", ["db", "migrate"]], decision = "prompt")
prefix_rule(pattern = ["npx", "drizzle-kit", "push"], decision = "prompt")
prefix_rule(pattern = ["terraform", "destroy"], decision = "prompt")
prefix_rule(pattern = ["docker", ["rm", "rmi", "volume", "system"]], decision = "prompt")
prefix_rule(pattern = ["diskutil"], decision = "prompt")
prefix_rule(pattern = ["lftp"], decision = "prompt")Stronger control: Keep Codex's OS sandbox on (it limits writes, typically to the workspace) and leave approvals on for sessions that can reach data you cannot lose. Docs
Gemini CLI
Save as ~/.gemini/policies/stupidllm.toml. Workspace-level policy files are disabled in Gemini CLI, so this must be the user-level folder.
[[rule]]
toolName = "run_shell_command"
commandPrefix = ["rm -r", "rm -fr", "rm -R"]
decision = "ask_user"
priority = 100
denyMessage = "Destructive command: needs a human to confirm (stupidllm.com)"
[[rule]]
toolName = "run_shell_command"
commandPrefix = ["git reset --hard", "git clean", "git push --force", "git push -f", "git stash drop", "git filter-repo", "git worktree remove"]
decision = "ask_user"
priority = 100
denyMessage = "Destructive command: needs a human to confirm (stupidllm.com)"
[[rule]]
toolName = "run_shell_command"
commandPrefix = ["npx prisma db push", "npx prisma migrate reset", "npx drizzle-kit push", "prisma db push", "drizzle-kit push"]
decision = "ask_user"
priority = 100
denyMessage = "Destructive command: needs a human to confirm (stupidllm.com)"
[[rule]]
toolName = "run_shell_command"
commandPrefix = ["terraform destroy", "docker rm", "docker volume rm", "docker system prune", "diskutil", "lftp"]
decision = "ask_user"
priority = 100
denyMessage = "Destructive command: needs a human to confirm (stupidllm.com)"Stronger control: Policies in ~/.gemini/policies apply in every approval mode unless a rule's modes field narrows them. Docs
Copilot CLI
Pass on the command line. Copilot CLI matches the program name (and git/gh subcommands), so this blocks the whole command, not just its dangerous form.
copilot --deny-tool='shell(rm)' --deny-tool='shell(git reset)' --deny-tool='shell(git clean)' --deny-tool='shell(git stash)' --deny-tool='shell(git filter-repo)' --deny-tool='shell(git worktree)' --deny-tool='shell(diskutil)' --deny-tool='shell(lftp)'Stronger control: Avoid --allow-all-tools on a machine with data you cannot lose; --deny-tool takes precedence over it. Docs
The incidents behind each pattern
- Recursive deletes · 24 incidents: 0140, 0131, 0126, 0148, 0147, 0112, 0114, 0111, 0145, 0098, 0115, 0094, 0088, 0124, 0129, 0066, 0136, 0123, 0078, 0141, 0097, 0125, 0093, 0042
- Destructive git · 6 incidents: 0134, 0122, 0129, 0070, 0113, 0069
- Schema force-pushes · 2 incidents: 0067, 0068
- Volume, container and mirror deletes · 3 incidents: 0133, 0087, 0135
What rules cannot do
A pattern rule matches the command text the agent writes. Anthropic’s docs say plainly that it “isn’t a security boundary around the program”: /bin/rm, sh -c or a script that runs the same command gets past it. That has happened here: STUPID-2026-0124 went around a guard with cmd /c, and STUPID-2026-0128 deleted a home directory through /bin/rm. Rules also do nothing about the agent’s own internal cleanup bugs, prompt injection or leaked secrets. Use them with the sandbox, not instead of it, and keep backups.
Machine-readable and reviewed
Every rule here is in /guardrails.json with the incidents behind it, under the same CC BY 4.0 license as the records. If you want someone to check your team’s actual agent settings against all of this, that is a fixed-fee review.