I only want to add one soft_deny rule. What is the safest way to write it?
Put "$defaults" as the first element and your rule after it. The docs say the built-in rules are spliced in at that position and you keep inheriting updates to the built-in list. After editing, run claude auto-mode config to confirm the effective settings.
I put autoMode in the project's .claude/settings.json and nothing changed. Why?
The classifier does not read autoMode from project settings. The docs' reason is that those files live in the repo, so a checked-in repo could inject its own allow rules. Move it to ~/.claude/settings.json, managed settings, or pass it with --settings.
I need a mandatory stop before every push. What do I use?
Use permissions.ask, for example Bash(git push *). It is evaluated before the classifier and always prompts. The limit is that it only matches commands beginning with that text, so git -C <dir> push slips through; for full command text use a PreToolUse hook.
I'm not an engineer. Why does this matter to me?
If your team uses auto mode and someone edits this setting, protections such as the force-push rule can switch off without anyone noticing. Think of it as the difference between adding to a safety rulebook and rewriting it, separated by one default marker. After any change, run claude auto-mode config and read the result.
Auto mode is a permission mode where a classifier reviews each tool call. The official auto mode configuration page carries an easy-to-miss warning: if you set any of the arrays autoMode.environment, allow, soft_deny or hard_deny without the literal string "$defaults" inside it, your list replaces the built-in list for that section entirely. This article covers that trap, the rule precedence, and where the settings must live. Everything below comes from the official page unless marked otherwise.
This one keeps the built-in rules and adds one of your own:
{
"autoMode": {
"soft_deny": [
"$defaults",
"Never modify files under infra/terraform/prod/"
]
}
}
This one differs by a single line, "$defaults":
{
"autoMode": {
"soft_deny": [
"Never modify files under infra/terraform/prod/"
]
}
}
The official warning is blunt: leaving "$defaults" out of soft_deny discards every built-in soft Block rule, and the page names force push, curl | bash, production deploys and auto mode bypass; leaving it out of hard_deny discards the built-in data exfiltration rule. Each section is independent, so setting only environment leaves the other three default lists intact.
The docs describe four tiers inside the classifier: hard_deny blocks unconditionally, and neither user intent nor allow exceptions apply; soft_deny comes next and can be overridden by user intent and allow; allow acts as an exception to soft rules; finally, if the user's message directly and specifically describes the exact action Claude is about to take, the remaining soft blocks are lifted. The page's own example: asking Claude to "clean up the repo" does not authorize a force push, but asking it to "force-push this branch" does.
Two harder layers sit outside the classifier. permissions.deny blocks before the classifier is consulted and nothing can override it. A content-scoped permissions.ask rule such as Bash(git push *) always prompts, and the classifier cannot approve it. The docs also warn that such rules match commands that begin with that text, so git -C <dir> push is not checkpointed; to inspect the full command text, use a PreToolUse hook.
The classifier reads autoMode only from ~/.claude/settings.json, managed settings and the --settings flag. It does not read the project's .claude/settings.json or settings.local.json, because those live in the repo and a checked-in repo or build step could otherwise inject its own allow rules. If you wrote it in the project, it does nothing. Entries from each scope are combined; a developer can add but cannot remove what managed settings provide, and the page says plainly that a developer-added allow can override an organization soft_deny. The combination is additive, not a hard policy boundary; anything that must never run belongs in managed permissions.deny.
claude auto-mode defaults prints the four built-in lists; --label shows one rule by label prefix (v2.1.208+).claude auto-mode config prints what the classifier actually uses; run it after every edit.claude auto-mode critique has an AI review your custom rules for ambiguity, redundancy and likely false positives.claude auto-mode reset removes autoMode from your user settings (v2.1.212+) after a confirmation; managed and --settings rules still apply./auto-mode-setup drafts environment entries from your project and recent sessions. The docs page says it needs a Pro, Max or Team plan and cannot run in a cloud session, while the v2.1.304 release notes say it is now also available on Bedrock, Vertex, Foundry, the Claude apps gateway and telemetry-disabled sessions. The two statements differ and I cannot reconcile them, so trust what your own version does. It scans CLAUDE.md, README, settings and the commands Claude ran in recent sessions, never your messages, and on acceptance it adds "$defaults" to the allow, soft_deny and hard_deny lists it touches.A sensible order is to start with environment only (the docs say most organizations need nothing else) and, when you add rules, put "$defaults" first in every array. Those are the documented facts; the suggested order is my paraphrase of the official rollout advice, not my own testing.