{"license":"CC BY 4.0 — https://creativecommons.org/licenses/by/4.0/","attribution":"StupidLLM, AI Agent Incident Database, https://www.stupidllm.com/guardrails/","generated_at":"2026-10-29T12:43:51.510Z","decision":"ask","limits":"Pattern rules match the command text an agent writes. They are not a security boundary: /bin/rm, sh -c or a script running the same command gets past them (see STUPID-2026-0124 and STUPID-2026-0128). Use them with the agent's sandbox, not instead of it.","agents":{"claude-code":{"name":"Claude Code","where":"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.","sandbox":{"text":"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.","url":"https://code.claude.com/docs/en/sandboxing"}},"codex":{"name":"Codex","where":"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.","sandbox":{"text":"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.","url":"https://developers.openai.com/codex/agent-approvals-security"}},"gemini-cli":{"name":"Gemini CLI","where":"Save as ~/.gemini/policies/stupidllm.toml. Workspace-level policy files are disabled in Gemini CLI, so this must be the user-level folder.","sandbox":{"text":"Policies in ~/.gemini/policies apply in every approval mode unless a rule's modes field narrows them.","url":"https://github.com/google-gemini/gemini-cli/blob/main/docs/reference/policy-engine.md"}},"github-copilot":{"name":"Copilot CLI","where":"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.","sandbox":{"text":"Avoid --allow-all-tools on a machine with data you cannot lose; --deny-tool takes precedence over it.","url":"https://docs.github.com/en/copilot/concepts/agents/about-copilot-cli"}},"cursor":{"name":"Cursor","where":null,"sandbox":{"text":"Cursor documents a command allowlist and a sandbox for terminal commands, but no deny list, and calls these best-effort guardrails rather than a hard security boundary. Use the sandboxed Run Mode.","url":"https://cursor.com/docs/agent/security"}}},"mechanisms":[{"id":"recursive-delete","label":"Recursive deletes","incidents":["STUPID-2026-0042","STUPID-2026-0066","STUPID-2026-0078","STUPID-2026-0088","STUPID-2026-0093","STUPID-2026-0094","STUPID-2026-0097","STUPID-2026-0098","STUPID-2026-0111","STUPID-2026-0112","STUPID-2026-0114","STUPID-2026-0115","STUPID-2026-0123","STUPID-2026-0124","STUPID-2026-0125","STUPID-2026-0126","STUPID-2026-0129","STUPID-2026-0131","STUPID-2026-0136","STUPID-2026-0140","STUPID-2026-0141","STUPID-2026-0145","STUPID-2026-0147","STUPID-2026-0148"],"rules":{"claude-code":["Bash(rm -r*)","Bash(rm -fr*)","Bash(rm -R*)","Bash(find * -delete*)","PowerShell(Remove-Item *)","Bash(cmd /c rmdir *)","Bash(cmd /c del *)"],"codex":["prefix_rule(pattern = [\"rm\", [\"-r\", \"-rf\", \"-fr\", \"-R\"]], decision = \"prompt\", justification = \"Recursive delete: confirm the target first\")"],"gemini-cli":["commandPrefix = [\"rm -r\", \"rm -fr\", \"rm -R\"]"],"github-copilot":["shell(rm)"]},"export":{"claude-code":"{\n  \"permissions\": {\n    \"ask\": [\n      \"Bash(rm -r*)\",\n      \"Bash(rm -fr*)\",\n      \"Bash(rm -R*)\",\n      \"Bash(find * -delete*)\",\n      \"PowerShell(Remove-Item *)\",\n      \"Bash(cmd /c rmdir *)\",\n      \"Bash(cmd /c del *)\"\n    ]\n  }\n}","codex":"prefix_rule(pattern = [\"rm\", [\"-r\", \"-rf\", \"-fr\", \"-R\"]], decision = \"prompt\", justification = \"Recursive delete: confirm the target first\")","gemini-cli":"[[rule]]\ntoolName = \"run_shell_command\"\ncommandPrefix = [\"rm -r\", \"rm -fr\", \"rm -R\"]\ndecision = \"ask_user\"\npriority = 100\ndenyMessage = \"Destructive command: needs a human to confirm (stupidllm.com)\"","github-copilot":"copilot --deny-tool='shell(rm)'"}},{"id":"destructive-git","label":"Destructive git","incidents":["STUPID-2026-0069","STUPID-2026-0070","STUPID-2026-0113","STUPID-2026-0122","STUPID-2026-0129","STUPID-2026-0134"],"rules":{"claude-code":["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 *)"],"codex":["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\")"],"gemini-cli":["commandPrefix = [\"git reset --hard\", \"git clean\", \"git push --force\", \"git push -f\", \"git stash drop\", \"git filter-repo\", \"git worktree remove\"]"],"github-copilot":["shell(git reset)","shell(git clean)","shell(git stash)","shell(git filter-repo)","shell(git worktree)"]},"export":{"claude-code":"{\n  \"permissions\": {\n    \"ask\": [\n      \"Bash(git reset --hard*)\",\n      \"Bash(git clean *)\",\n      \"Bash(git push --force*)\",\n      \"Bash(git push -f*)\",\n      \"Bash(git stash drop*)\",\n      \"Bash(git filter-repo*)\",\n      \"Bash(git worktree remove *)\"\n    ]\n  }\n}","codex":"prefix_rule(pattern = [\"git\", \"reset\", \"--hard\"], decision = \"prompt\")\nprefix_rule(pattern = [\"git\", \"clean\"], decision = \"prompt\")\nprefix_rule(pattern = [\"git\", \"push\", [\"--force\", \"-f\"]], decision = \"prompt\")\nprefix_rule(pattern = [\"git\", \"stash\", \"drop\"], decision = \"prompt\")\nprefix_rule(pattern = [\"git\", \"filter-repo\"], decision = \"prompt\")\nprefix_rule(pattern = [\"git\", \"worktree\", \"remove\"], decision = \"prompt\")","gemini-cli":"[[rule]]\ntoolName = \"run_shell_command\"\ncommandPrefix = [\"git reset --hard\", \"git clean\", \"git push --force\", \"git push -f\", \"git stash drop\", \"git filter-repo\", \"git worktree remove\"]\ndecision = \"ask_user\"\npriority = 100\ndenyMessage = \"Destructive command: needs a human to confirm (stupidllm.com)\"","github-copilot":"copilot --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)'"}},{"id":"schema-force-push","label":"Schema force-pushes","incidents":["STUPID-2026-0067","STUPID-2026-0068"],"rules":{"claude-code":["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*)"],"codex":["prefix_rule(pattern = [\"npx\", \"prisma\", [\"db\", \"migrate\"]], decision = \"prompt\")","prefix_rule(pattern = [\"npx\", \"drizzle-kit\", \"push\"], decision = \"prompt\")"],"gemini-cli":["commandPrefix = [\"npx prisma db push\", \"npx prisma migrate reset\", \"npx drizzle-kit push\", \"prisma db push\", \"drizzle-kit push\"]"],"github-copilot":[]},"export":{"claude-code":"{\n  \"permissions\": {\n    \"ask\": [\n      \"Bash(npx prisma db push*)\",\n      \"Bash(prisma db push*)\",\n      \"Bash(npx prisma migrate reset*)\",\n      \"Bash(npx drizzle-kit push*)\",\n      \"Bash(drizzle-kit push*)\",\n      \"Bash(pnpm prisma db push*)\",\n      \"Bash(pnpm drizzle-kit push*)\"\n    ]\n  }\n}","codex":"prefix_rule(pattern = [\"npx\", \"prisma\", [\"db\", \"migrate\"]], decision = \"prompt\")\nprefix_rule(pattern = [\"npx\", \"drizzle-kit\", \"push\"], decision = \"prompt\")","gemini-cli":"[[rule]]\ntoolName = \"run_shell_command\"\ncommandPrefix = [\"npx prisma db push\", \"npx prisma migrate reset\", \"npx drizzle-kit push\", \"prisma db push\", \"drizzle-kit push\"]\ndecision = \"ask_user\"\npriority = 100\ndenyMessage = \"Destructive command: needs a human to confirm (stupidllm.com)\"","github-copilot":null}},{"id":"infra-teardown","label":"Volume, container and mirror deletes","incidents":["STUPID-2026-0087","STUPID-2026-0133","STUPID-2026-0135"],"rules":{"claude-code":["Bash(terraform destroy*)","Bash(docker rm *)","Bash(docker volume rm *)","Bash(docker system prune*)","Bash(diskutil *)","Bash(lftp *)","Bash(rsync * --delete*)"],"codex":["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\")"],"gemini-cli":["commandPrefix = [\"terraform destroy\", \"docker rm\", \"docker volume rm\", \"docker system prune\", \"diskutil\", \"lftp\"]"],"github-copilot":["shell(diskutil)","shell(lftp)"]},"export":{"claude-code":"{\n  \"permissions\": {\n    \"ask\": [\n      \"Bash(terraform destroy*)\",\n      \"Bash(docker rm *)\",\n      \"Bash(docker volume rm *)\",\n      \"Bash(docker system prune*)\",\n      \"Bash(diskutil *)\",\n      \"Bash(lftp *)\",\n      \"Bash(rsync * --delete*)\"\n    ]\n  }\n}","codex":"prefix_rule(pattern = [\"terraform\", \"destroy\"], decision = \"prompt\")\nprefix_rule(pattern = [\"docker\", [\"rm\", \"rmi\", \"volume\", \"system\"]], decision = \"prompt\")\nprefix_rule(pattern = [\"diskutil\"], decision = \"prompt\")\nprefix_rule(pattern = [\"lftp\"], decision = \"prompt\")","gemini-cli":"[[rule]]\ntoolName = \"run_shell_command\"\ncommandPrefix = [\"terraform destroy\", \"docker rm\", \"docker volume rm\", \"docker system prune\", \"diskutil\", \"lftp\"]\ndecision = \"ask_user\"\npriority = 100\ndenyMessage = \"Destructive command: needs a human to confirm (stupidllm.com)\"","github-copilot":"copilot --deny-tool='shell(diskutil)' --deny-tool='shell(lftp)'"}}]}