Prompts are suggestions. Settings are rules.
If you only write "never run dangerous shell commands" in CLAUDE.md, the model can still try them. Claude Code lets you put an explicit allow / deny list in .claude/settings.json so the runtime blocks the tool call before it runs.
Minimal example
{
"permissions": {
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force*)",
"Bash(git reset --hard*)",
"Bash(sudo *)"
],
"ask": [
"Bash(npm publish*)",
"Bash(gh pr merge*)"
]
}
}
Exact matcher syntax can vary by Claude Code version — treat this as the shape, then confirm against your installed docs. The point is: put the policy where the tool layer enforces it.
Why this beats a longer prompt
- A deny in settings fails closed. A sentence in
AGENTS.mdis soft. - You can keep
CLAUDE.mdshort (house rules + stack map) and still be strict on shell. - Pair with a
PreToolUsehook for patterns settings cannot express, and aStophook so the agent cannot say "done" whiletscis red.
I keep the deny list, hooks, and short house-rules file together in Vildanden Agent Config. The free sample is enough to try the pattern.
Top comments (0)