CC-201a · Module 2

Allowlisting Safe Commands

3 min read

Building an allowlist is an exercise in risk assessment. The question for every command is: what is the worst thing that happens if Claude runs this without asking? For tsc --noEmit, the answer is nothing — it is a read-only type check. For npm test, the answer is usually nothing — tests should be side-effect-free. For eslint --fix, the answer is minor file modifications that git can undo. These are all safe to auto-accept. The cost of asking for permission on every type check across a full development session is real — dozens of interruptions that add up to minutes of wasted time.

On the other side of the ledger: rm -rf can destroy your project in under a second. git push sends code to a shared remote that others pull from. npm publish ships a package to the world. Database commands modify state that may not be recoverable. These must always be gated. There is no productivity gain that justifies the risk of an unattended destructive operation. The rule of thumb: if the command is read-only or trivially reversible, auto-accept it. If it modifies shared state or is irreversible, always ask.

Do This

  • Auto-accept: tsc --noEmit, eslint, prettier, npm test, vitest, jest, cargo check
  • Auto-accept: git status, git diff, git log — all read-only git operations
  • Gate: git push, git commit, npm publish, rm, database migrations
  • Deny: rm -rf /, any command targeting system directories, production database access

Avoid This

  • Auto-accept git push because "it is usually fine" — it sends code to shared remotes
  • Gate tsc --noEmit — there is zero risk and the friction wastes time every session
  • Leave everything in Ask mode because it feels safer — the friction costs real productivity
  • Auto-accept npm install — it can execute arbitrary scripts in postinstall hooks