Strategist · Designer · Operator

Launch
with Ben



Research

I Counted Every Time Claude Code Auto Mode Said No

I parsed six weeks of my own Claude Code transcripts for auto mode classifier denials: 2.3 per 1,000 tool calls, 13 of 71 rules, and a script to run on yours.

The short version

Across 110,629 tool calls, Claude Code's auto mode classifier denied 251, or 2.3 per 1,000, and only 13 of its 71 blocking rules fired. The rate barely moved. What changed is that denials started naming the rule.

What you will learn

  • How to count your own auto mode denials from transcripts with a script
  • Which reason tags came up most in my data
  • Where autoMode settings go, and why project settings are ignored
  • How a merged fix sat undeployed for about 42 hours

Who it is for

Claude Code users who feel auto mode blocks too much and want a count before they change any settings.

Skip it if

You do not use auto mode. The numbers are also from one operator on one machine.

You leave with

A script to count your own denials, plus three fixes for the top row of your list.


I thought auto mode was blocking more. I was half right.

Across 110,629 tool calls in six weeks of real work, Claude Code’s auto mode classifier denied 251 of them: 2.3 per 1,000. Only 13 of its 71 blocking rules ever fired. The rate before and after 10 September moved from 2.06 to 2.42 per 1,000, a rise of about a sixth. What changed far more was that denials started telling me why.

One operator, one machine, 10 project checkouts, 16 August to 28 September 2026. Dataset and script.

For about two weeks it felt like my agents were refusing more. Deploys, config edits, anything near production. I started deleting permission rules project by project to make it stop. It did not stop.

It could only ever have removed one layer. On one project, two were stacked. An earlier agent had written a deny rule for every form of deploy into the project’s tracked .claude/settings.json on 4 September, and the commit that lifted some of them five days later kept wrangler pages deploy denied. Above that sat the classifier, and Anthropic’s auto mode docs are explicit about where it lives: it runs after the permission rules, and it reads its own autoMode block from ~/.claude/settings.json only, never from a project’s .claude/settings.json. My project edits could reach the first layer. They could not reach the second, and when I told the agent to fix the settings itself, the classifier refused that too, as [Self-Modification].

So I stopped trusting the feeling and counted that second layer.

How I counted

Every Claude Code session leaves a transcript under ~/.claude/projects/. When the classifier refuses a tool call, the agent receives an error that opens with one fixed sentence:

Permission for this action was denied by the Claude Code auto mode classifier. Reason: [Production Deploy].

The script parses every transcript line as JSON and keeps only tool_result blocks marked is_error: true that open with that sentence. The denominator is every tool call made in the same window.

That second condition matters more than it looks. My first count used a plain text search, and it was wrong three different ways. More on that at the end.

251denials in six weeks
2.3per 1,000 tool calls
13 of 71blocking rules that ever fired

What it actually refused

Reason tagDenialsFirst seenProjects
untagged (Blocked by classifier)16016 Aug9
Self-Modification2810 Sep4
Modify Shared Resources1416 Sep4
Production Deploy1011 Sep4
Irreversible Local Destruction919 Sep4
Interfere With Workloads616 Sep2
Secret-Store Writes618 Sep1
Auto-Mode Bypass, Merge Without Review, Safety Bypass Flag4 each11 to 24 Sep1 to 3
Credential Exploration323 Sep2
Blind Apply, External System Writes, Production Reads1 each18 to 25 Sep1

Every tag in that table is a rule name you can print yourself. claude auto-mode defaults lists the full rule set: on version 2.1.282 that is 1 hard deny (Data Exfiltration), 70 soft denies and 17 allow exceptions. In six weeks, my work touched 13 of those 71 blocking rules.

What the classifier checks

71 rules stand between every tool call and execution, from Git Destructive to Browser File Upload Exfil.

What my work ran into

13 of them ever fired. The other 58 never saw a real case in six weeks of building and deploying.

The rule set is broad. Real work hits a narrow slice of it, and that slice tells you exactly which of your habits the classifier distrusts.

Self-Modification leads because a lot of my work edits the agent’s own configuration: hooks, skills, ~/.claude itself. Seven of the 28 were an agent in one project editing the permission rules that were blocking its own deploy, twice within five minutes of me telling it to. That is my shape of work, not yours. Run the script and your top row will be different, which is the point of running it.

The rate barely moved. The labels arrived.

Here is the part the feeling got wrong. Split the window at the first tagged denial and compare rates, not raw counts:

PeriodDenialsTool callsPer 1,000
16 Aug to 9 Sep9646,5432.06
10 Sep to 28 Sep15564,0862.42

A rise of about a sixth. Not nothing. Nowhere near what it felt like.

What did change completely was the text. Before 10 September, every one of 96 denials read Blocked by classifier and nothing else. From then on, most carried a named rule. The client version lines up exactly: no build before 2.1.268 ever produced a tag, 2.1.268 produced 12 of each, and 2.1.278 produced 30 tagged against 2 untagged.

For deploys, the feeling had a real cause: the stacked rules above, one set of which an earlier agent wrote and the classifier would not let a later one remove. For everything else, my guess is that “it’s blocking more” was really “it’s telling me more.” A bare refusal slides past. A refusal that says [Production Deploy] is memorable, and you start noticing every one.

The refusal that cost 42 hours

One of those 10 Production Deploy denials is worth telling in full, because the refusal was the smaller of two failures.

1
25 Sep, 14:42. A worktree agent writes a fix for a consent banner that was showing to US visitors when it should not.
2
26 Sep, 16:11. The agent ends its session with a table of everything still outstanding, the fix among them, and says in so many words: “yes, all of it needs landing.” That is its last message.
3
26 Sep, 16:31. The pull request is merged. Nothing is deployed.
4
28 Sep, morning. I see the banner on a site I run, from the US, and report it to a fresh session that has never heard of the bug.
5
28 Sep, 10:13. That session finds the merged fix, tries to deploy it, and gets Reason: [Production Deploy]. I run the deploy myself.

Forty-one hours and forty-two minutes between merge and the first deploy attempt. The classifier cost me minutes of that. The rest was a correct handoff that lived in the only place a closed session takes with it: its own transcript.

The worktree agent did nothing wrong. It said the right thing to the right question. But a sentence in a chat is not a queue, and my main session later wrote its own handoff across a context reset that listed other pull requests and not this one. Nobody dropped the item. It never had anywhere to be dropped from.

The fix was a rule, not a tool: any lane that ends with “still needs deploying” files that as an issue in the same commit. It is the same idea behind the rule that stopped my agents deferring work to “next session”, and it closes a hole in how I run three agents in parallel worktrees. That setup deploys once from the main checkout after everything merges. Here, nothing told the main checkout there was anything to deploy.

Count your own, then fix what shows up

The script is the artifact here. It reads your transcripts locally and prints nothing but counts; no project names leave your machine.

curl -O https://launchwithben.com/research/auto-mode-denials-2026-09/count-denials.py
python3 count-denials.py                # summary and per-category table
python3 count-denials.py --csv out/     # plus the CSVs this post publishes

Then work down your top rows:

claude auto-mode defaults --label 'Production Deploy'   # the exact wording of one rule
claude auto-mode config                                 # what the classifier actually uses

Inside a session, /permissions has a Recently denied tab where you can mark a denial for retry. From there, Anthropic’s docs give three fixes, and the choice depends on what was refused:

  • A destination you use all the time (your git org, an internal domain, a bucket): add it to autoMode.environment, or run /auto-mode-setup to draft the entries.
  • A command you never want reviewed: add an allow rule. It is prose, not a pattern: "Production Deploy: allow npm run deploy from the worker/ directory of my-site".
  • A one-off you did intend: say so in your next message and let the agent retry.

Before you edit autoMode

Do

  • Put it in ~/.claude/settings.json. Project settings files are ignored on purpose, so a cloned repo cannot grant itself permissions
  • Keep "$defaults" in every list you touch. Without it you replace the built-in rules instead of adding to them

Don't

  • Write tool patterns like Bash(npm test) in autoMode. The classifier reads natural language

That second rule is not theoretical. While writing this I opened my own ~/.claude/settings.json and found an environment block written for a single project. It named that repo as the only trusted one and had no "$defaults", so it applied to every other project on the machine. I have not yet measured how many of my denials it caused. That is the next count.

Three ways my first count was wrong

A first draft of this post reported 23 Production Deploy denials in one day, starting 11 September. Each of those three numbers was wrong, and each for a different reason.

  • A text search counts conversation, not events. Once an agent quotes a denial back, or my own CLAUDE.md quotes the tag names, every later session contains the string. My instructions file was inflating the count it was meant to explain.
  • I counted three tags when there were 14 categories. The 23 was close to the real 26 tagged denials on 23 September, across all rules. I had pinned the whole peak on one of them.
  • I missed the 160 untagged denials entirely, which moved the start date back almost a month.

The last error was mine, during the fact-check. A failed command that printed the draft, which quotes the denial sentence, got counted as a denial. That is why the script now requires the sentence to open the result. I have been caught by my own instrument before: my agent memory measurement carries the errata to prove it.

Related:

Sources

  • Claude Code docs, Configure auto mode: the classifier’s precedence, why project settings are ignored, "$defaults", the claude auto-mode subcommands and the Recently denied tab.
  • Anthropic, How we built Claude Code auto mode: what the classifier is for, from the people who built it.
  • claude auto-mode defaults, run locally on Claude Code 2.1.282, and again on 2.1.284 on 5 October with identical counts: the 71 blocking rules and 17 allow exceptions counted above.
Ben Peetermans

Ben Peetermans

I build MVPs and run ad campaigns with AI, and I write these notes from real projects. Twenty years shipping for the web. If you want someone who works with these tools every day to build yours, that is what I do.