Claude Code was spending 85% of its context window reading node_modules.
..and I was already following best practices according to the docs blocking in my config direct file reads: "deny": ["Read(node_modules/)"]
Found this out after hitting token limits three times during a refactoring session. Pulled the logs, did the math: 85,000 out of 100,000 tokens were being consumed by dependency code, build artifacts, and git internals.
Allowing Bash commands was the killer here.
Every grep -r, every find . was scanning the entire project tree.
Quick fix: Pre-execution hook that filters bash commands. Only 5 lines of bash script did the trick.
The issue: Claude Code has two separate permission systems that don't talk to each other. Read() rules don't apply to bash commands, so grep and find bypass your carefully crafted deny lists.
The fix is a bash validation hook.
.claude/scripts/validate-bash.sh:
.claude/settings.local.json:
"hooks":{"PreToolUse":[{"matcher":"Bash","hooks":[{"command":"bash .claude/scripts/validate-bash.sh"}]}]}Won't catch every edge case (like hiding paths in variables), but stops 99% of accidental token waste.
.png)

![Braid groups are cool [pdf]](https://news.najib.digital/site/assets/img/broken.gif)