CLAUDE LABJP
2.1.273 — A round of connection work landed together: five opt-in headers for LLM gateways, and a notice when Claude Code stops trying to reconnect an MCP server09/29 — The date beside claude-sonnet-4-5 is 12 days out, but it is an earliest-possible estimate. The model is still Active, and public retirements get at least 60 days noticeMCP — People keep asking to reconnect a dropped server without ending the session. The disconnect is now announced, but reattaching is still something you do by handNEW — A scheduled task ran some days and not others. The cause was that only one folder had been bound to itWINDOWS — When Cowork fails on its very first task, check developer mode and the setup state before going looking for a causeHANDOFF — Before a long draft gets too heavy for one chat, decide on the three things the summary must carry into the next one2.1.273 — A round of connection work landed together: five opt-in headers for LLM gateways, and a notice when Claude Code stops trying to reconnect an MCP server09/29 — The date beside claude-sonnet-4-5 is 12 days out, but it is an earliest-possible estimate. The model is still Active, and public retirements get at least 60 days noticeMCP — People keep asking to reconnect a dropped server without ending the session. The disconnect is now announced, but reattaching is still something you do by handNEW — A scheduled task ran some days and not others. The cause was that only one folder had been bound to itWINDOWS — When Cowork fails on its very first task, check developer mode and the setup state before going looking for a causeHANDOFF — Before a long draft gets too heavy for one chat, decide on the three things the summary must carry into the next one
Articles/Claude Code
Claude Code/2026-08-20Beginner

Take Inventory of What You Allowed with Don't Ask Again in Claude Code

After clicking Don't ask again a few dozen times, can you still explain what you approved? Here is a script that counts your current rules, plus a way to rebuild permissions from the smallest possible set.

Claude Code253permissions10settings.json8security18solo development3

Last week I was moving between several repositories in one session.

A file I wanted to reference sat outside the working directory, and Claude Code refused to read it, exactly as it should have. So I killed the session, relaunched with --add-dir, and watched everything I had built up in that conversation disappear.

Only afterwards did I learn that this no longer requires a restart. It changed in v2.1.234 on August 17. If you have ever ended a session for the same reason, that one sentence may be the most useful thing here.

You can now open /permissions mid-response

Since v2.1.234, /permissions opens while Claude is still working, and the rules you change apply to the remainder of the current turn. /add-dir works mid-session too.

It reads like a small quality-of-life fix. In daily use it removes a choice I had been making badly for months:

The old optionsWhat it cost
Restart the session with wider flagsEverything in the conversation so far is gone
Grant broad permissions up frontYou lose track of what you actually approved

I drifted toward the second one. As an indie developer working alone, the rationalization comes easily: nobody else touches this machine, so why not click through. Several months of clicking Don't ask again later, I could no longer describe my own configuration.

The scope of "Don't ask again" now matches what the dialog shows

A second change landed in v2.1.235 on August 18. The text displayed in the confirmation dialog and the scope that Don't ask again actually covers are now always in agreement. When a rule cannot be displayed in full, the Don't ask again option no longer appears at all.

The point of the fix is to prevent a gap between what you thought you approved and what you really approved. Which also means the approvals you accumulated before this version deserve a look, because your memory of them may not be reliable.

Newer versions being safer does nothing about rules already sitting in your settings file. Auditing what is there, then rebuilding, is the natural order.

Count what you have

Permissions live in JSON, so jq can count them directly.

The script below reports how many deny, ask, and allow rules you have, broken down by tool. It reads .claude/settings.json from the project root by default, and accepts a path as an argument.

#!/bin/bash
# Inventory permission rules: counts per category, broken down by tool
F="${1:-.claude/settings.json}"
for KIND in deny ask allow; do
  N=$(jq -r ".permissions.$KIND // [] | length" "$F")
  echo "== $KIND: $N rules"
  jq -r ".permissions.$KIND // [] | .[]" "$F" \
    | sed 's/(.*//' | sort | uniq -c | sort -rn \
    | awk '{printf "   %-10s %s\n", $2, $1}'
done
echo "== additionalDirectories: $(jq -r '.permissions.additionalDirectories // [] | length' "$F")"

The sed 's/(.*//' step strips everything from the opening parenthesis onward, turning Bash(git status:*) into plain Bash. The question worth answering is not which individual rules exist but which tool is carrying most of your trust.

Run it against a configuration like this:

{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./**/*.pem)",
      "Bash(rm -rf:*)",
      "Bash(git push --force:*)"
    ],
    "ask": [
      "Bash(git push:*)",
      "Bash(npm publish:*)",
      "Edit(./content/**)"
    ],
    "allow": [
      "Bash(git status:*)",
      "Bash(git diff:*)",
      "Bash(npm run test:*)",
      "Bash(npm run build:*)",
      "Read(./src/**)",
      "Read(./docs/**)",
      "WebFetch(domain:code.claude.com)"
    ],
    "additionalDirectories": ["../shared-assets"]
  }
}

and you get:

== deny: 4 rules
   Read       2
   Bash       2
== ask: 3 rules
   Bash       2
   Edit       1
== allow: 7 rules
   Bash       4
   Read       2
   WebFetch   1
== additionalDirectories: 1

Fourteen rules total is still small enough to read line by line. Once the count climbs past forty or fifty, scanning the list stops telling you anything, and the rule set starts costing you on every turn. If your inventory came back larger than you expected, the walkthrough on sessions that get heavier as permission rules pile up covers how to shrink the set without giving up safety.

One caveat: this only looks at project settings. Your user-level configuration has the same structure, so count both. Which file receives a rule created by Don't ask again depends on the option you pick in the dialog.

Start from the smallest set and add on demand

Once you know what you have, rebuild it. I work through deny, then ask, then allow, because that mirrors how the rules are evaluated.

CategoryMeaningWhat belongs here
denyAlways refused, and it wins over the othersAnything you cannot afford to have touched
askConfirmed every timeActions you cannot take back
allowRuns without a promptThings you repeat many times a day

Four concrete steps:

  1. Fill in deny first. Credential files, private keys, rm -rf, git push --force. When in doubt, add it here — a deny rule costs you a rewrite, a missing one costs you a repository
  2. Put "reversible but visible outside" actions in ask. Pushing, publishing packages, writing into a public directory. A single confirmation stops most of what goes wrong
  3. Keep allow minimal at the start. git status, git diff, and your test command are usually enough for the first day
  4. When you hit a wall, open /permissions and add exactly one rule. No restart required anymore

Steps 3 and 4 only became practical with the mid-turn change. Until now, "I do not want to interrupt my work" pushed everyone toward granting broad access up front, and that broad access stayed. Now the grant can happen at the moment of actual need, at the size of the actual need.

If the matcher syntax itself is the unfamiliar part — how patterns like Bash(npm run test:*) are written — the piece on building a tool permission policy from scratch lays out the basic shapes.

Three things to try before restarting

When something is blocked mid-task, this is the order I check:

  1. Open /permissions. It opens during a response now. Look at which category the rule sits in — anything in deny will not be rescued by adding it to allow
  2. Check whether you are reaching outside the working directory. If so, /add-dir handles it without leaving the session
  3. Compare the pattern against the command that actually ran. Writing Bash(npm test:*) while your project uses npm run test is a mismatch I have created more than once

Only when none of the three helps do I consider restarting. Previously I jumped straight to a restart, so the list is exactly three steps longer than it used to be — and considerably cheaper.

One thing to do today

Before you close today's session, open /permissions and read the list once, especially if you clicked Don't ask again at any point. If even one rule is there that you cannot explain, that rule is your starting point.

My own inventory turned up an allowance I had added half a year ago for a project I no longer work on. Finding something like that is not evidence of a careless setup — it is evidence that you kept working instead of stopping, which was the right call at the time. It just deserves a second pass now that a second pass is cheap.

Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $15 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Claude Code2026-08-21
My read-deny rules never reached inside the folder I had allowed
An audit of how far permissions.deny Read rules actually reach in a working tree where secrets and source code live side by side, with a script you can run today.
Claude Code2026-08-27
Trusting the allow rules in your repo, or moving them to the environment
On disposable machines, the permissions.allow rules committed to your repo are dropped while the workspace waits to be trusted. Here is what gets dropped and what survives on 2.1.246, where each kind of rule belongs, and a preflight that catches the gap before a run starts.
Claude Code2026-04-13
Claude Code Tool Permissions: Custom Allow/Deny Policies
Learn how to control Claude Code tool permissions with allowedTools, disallowedTools, and settings.json. Includes project-specific permission patterns for frontend, backend, and read-only review scenarios.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links