← blog··7 min read

Teach Claude Code's Auto Mode About Your Setup in One Command

Claude Code 2.1.304 made /auto-mode-setup available in more places. It drafts the trusted-infrastructure list auto mode needs so it stops blocking your own repos. What it reads, what it writes, and the one mistake that wipes your safety rules.

claude-codeauto-modepermissionsproduct-update
Kev Gary
Founder & Lead Instructor, Claude Camp

If you run Claude Code in auto mode, you've probably hit this: it's flying along, then it stops on something completely ordinary. Pushing to your own company's GitHub org. Writing to a bucket your team owns. Installing from your private package registry. The block message names a rule like [Data Exfiltration] and you think: that's my own bucket.

It's not a bug. It's the classifier doing what it was told. By default it trusts exactly two things: your working directory and the remotes configured on the current repo. Everything else looks like "outside," and outside is where exfiltration lives.

Claude Code 2.1.304 (October 19) lists a guided fix for this: /auto-mode-setup. Per the docs, the command itself has existed on Pro, Max, Team and Enterprise for a while. What 2.1.304 changed is where it works: sessions with feature-flag fetching off (telemetry disabled, third-party providers like Bedrock and Vertex, the Claude apps gateway) used to get "Unknown command." If that was you, update and try again.

What it actually does

You type /auto-mode-setup. Claude Code asks how you use the project, then offers two optional scans. Then it builds a draft of an autoMode.environment list, which is a set of plain-English sentences describing what's yours. You accept or discard the draft as a whole.

What it always reads:

  • This project's CLAUDE.md, README.md, config files and git remotes
  • Your existing autoMode and permissions.allow settings
  • The hosts, buckets and command names from commands Claude ran in your recent sessions in this project (never your messages)

The two opt-in scans add the first word of each command in your shell history, and the remote hosts and repo names under your home directory.

Before setupAfter setuppush to acme-corp orgblockedwrite s3://acme-buildsblockedinstall from registryblockedtrusts: working dir + its remotespush to acme-corp orgallowedwrite s3://acme-buildsallowedinstall from registryallowedpost to pastebinblockedtrusts: the above + what you listed

Why a list of sentences works

The entries are prose, not regex. The docs say to write them "the way you would describe your infrastructure to a new engineer." A typical entry looks like this:

{
  "autoMode": {
    "environment": [
      "$defaults",
      "Source control: github.example.com/acme-corp and all repos under it",
      "Trusted cloud buckets: s3://acme-build-artifacts",
      "Internal package registry: artifacts.example.com"
    ]
  }
}

The classifier reads those as context for deciding what "external" means. Anything not listed is still a potential exfiltration target, which is the point. You're not turning safety off. You're shrinking the set of things it has to be suspicious of.

If you're a solo operator, most of this is a few lines: your GitHub org, maybe one bucket, maybe one internal domain. If you're on a team, this is the file that cuts the false-positive noise for everyone, and the docs let an admin push it through managed settings.

The one mistake that matters

This is the part I'd tattoo on the wall. Setting environment, allow, soft_deny or hard_deny without the literal string "$defaults" replaces the whole built-in list for that section.

For soft_deny, that means losing force push, curl | bash, production deploys and auto-mode bypass. For hard_deny, it means losing the built-in data exfiltration rule. Per the docs, that's the full replacement, not a merge.

"soft_deny": ["$defaults", "your rule"]force pushcurl | bashyour rule"soft_deny": ["your rule"] (no $defaults)force push curl | bashyour rule

/auto-mode-setup handles this for you. Per the docs, when it adds entries to the rule lists, it includes "$defaults" so the built-ins stay. It writes the environment list without it, but only because the draft spells out the built-in entries it left unchanged. If you hand-edit the file afterward, keep that string in every list you touch.

After you accept the draft

Three habits I'd build in:

  1. Run claude auto-mode config. It prints what the classifier is actually using, with your settings applied. Confirm your entries are there.
  2. Run claude auto-mode critique if you wrote custom rules. It flags entries that are ambiguous, redundant or likely to cause false positives.
  3. Put hard stops in permissions, not in autoMode. The docs are explicit: for actions that must never run, permissions.deny blocks before the classifier is consulted and can't be overridden. A developer-added allow entry can override an organization's soft_deny, so the classifier layer is additive, not a hard policy wall.

One more detail worth knowing: the classifier ignores autoMode in project-level .claude/settings.json. That's deliberate, since a checked-in repo could otherwise grant itself permissions. Your config lives in ~/.claude/settings.json.

The other two things in 2.1.304

Code Review gained Quick, Standard and Deep levels, which is handy if you've been using one setting for everything. And Pro and Max plans now get a warning when resuming an inactive conversation would use a large share of your 5-hour limit. That one pairs well with the idle compaction change I wrote about last week.

What I'd do today

Update, run /auto-mode-setup once in your busiest project, read the draft before accepting it, then check the result with claude auto-mode config. If you've been approving the same prompts by hand for a month, this is the afternoon-saving fix.

Primary sources: the Claude Code changelog, the auto mode configuration docs, and the permission modes page.

// keep reading

Related posts

← all postsPublished October 26, 2026