Bible Network Crypto DeFi Onchain RWA AI Agent Stablecoin Chain SAFU CryptoTax DeFAI AGI Claude Me Claude Skill Claude Design Claude Cowork
Independent Media
Not affiliated with any project
Learn Claude Skills. Do Everything Better.
claudeskill-me.com
LATEST
Watching Claude Code Compaction and Hooks Through OpenTelemetry: Reading the compaction, hook_execution_complete and precompute_reuse Fields  ·  Blind Spots in Bash Permission Rules: deny Misses /bin/rm, bash -c and git -C, and devbox run * Lets Any Inner Command Through  ·  CLAUDE.md Too Long? Use .claude/rules/ and paths So Rules Load Only When Claude Touches Matching Files  ·  Chromium Says No usable sandbox! Inside Claude Code's Sandbox: What --no-sandbox, excludedCommands and allowNestedUserNamespaces Each Give Up  ·  Claude Code v2.1.309 Fixes a Batch of Sandbox and Permission Gaps: Startup Files Outside the Sandbox, denyWrite Through Symlinks and More  ·  The auto mode $defaults Trap: Leave One String Out of autoMode.soft_deny and the Built-In Force-Push Rules Disappear
practice

The auto mode $defaults Trap: Leave One String Out of autoMode.soft_deny and the Built-In Force-Push Rules Disappear

30-Second Version · For the impatient
Leave "$defaults" out of an auto mode array and you have not added a rule, you have replaced the whole built-in list.

Full Explanation +
01 · Why did this happen?

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.

02 · What is the mechanism?

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.

03 · How does it affect me?

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.

04 · What should I do?

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.

Full Content +

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.

Two spellings, very different results

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.

Rule precedence

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.

Where the settings go: project-level autoMode is ignored

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.

Tools for checking your work

  • 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.

Sources: Configure auto mode - Claude Code Docs, Claude Code changelog - Claude Code Docs
Diagram
auto mode 的檢查順序與 $defaults 陷阱一次工具呼叫依序經過 permissions.deny、ask、hard_deny、soft_deny、allow;autoMode 只從使用者與 managed 設定讀取,陣列漏掉 "$defaults" 會取代內建清單Order of checks for one tool call in auto modepermissions.denyBlocks before the classifier. Nothing overrides itpermissions.ask (content-scoped)Always prompts. Classifier cannot approveautoMode.hard_denyUnconditional. Intent and allow do not applyautoMode.soft_denyBlocks, unless allow or explicit user intent clears itautoMode.allowExceptions to soft_denyWhere autoMode is read~/.claude/settings.jsonmanaged settings--settings flagNOT .claude/settings*.json in the repoThe trapAn array without "$defaults"replaces the built-in listfor that sectionVerify: claude auto-mode configDraft: /auto-mode-setupClaude Skill Me · claudeskill-me.com
Feel free to share. Please credit the source.
Ask a Question
Please enter at least 10 characters
Related Articles
Blind Spots in Bash Permission Rules: deny Misses /bin/rm, bash -c and git -C, and devbox run * Lets Any Inner Command Through
practice · Oct 23
Claude Code Hooks Fail Open by Default: A Missing Script, a Timeout or Exit 1 Lets the Action Through — Using onFailure: "block" from v2.1.295
practice · Oct 19
Your Hook Says "Blocking Error" But the File Still Changed? PostToolUse and PreToolUse Don't Actually Block the Same Way
practice · Sep 28
Chromium Says No usable sandbox! Inside Claude Code's Sandbox: What --no-sandbox, excludedCommands and allowNestedUserNamespaces Each Give Up
advanced · Oct 23
Related News
More Related Topics