Feature: deny rules should support a reason/message field
Summary
When a deny rule in settings.json blocks a tool call, there's no way to provide context about why it was denied or what the agent should do instead. A reason field would let project maintainers guide agent behavior directly from the permissions config.
Use case
In our project, all build/test commands should go through mise run rather than being invoked directly (e.g. cargo test, npm run). We can deny those commands today:
{
"permissions": {
"deny": [
"Bash(cargo:*)",
"Bash(npm:*)"
]
}
}
But the agent has no idea why and may just try a different approach or ask the user. Ideally we could write:
{
"permissions": {
"deny": [
{
"rule": "Bash(cargo:*)",
"reason": "Use `mise run` instead of cargo directly"
},
{
"rule": "Bash(npm:*)",
"reason": "Use `mise run` instead of npm directly"
}
]
}
}
Current workarounds
- Add guidance to CLAUDE.md (but the agent may still attempt the command before reading it)
- Use a PreToolUse hook that returns a deny decision with a reason (works but heavyweight for simple cases)
Proposal
Allow deny rules to be either a string (current behavior) or an object with rule and reason fields. When a deny rule with a reason blocks a tool call, the reason is surfaced to the agent so it can self-correct.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗