Claude Code Approvals: A read/edit/run/deploy Decision Log You Can Trust
Stop second-guessing Claude Code approvals. Split work into read, edit, run, and deploy, and keep a daily log of what you allowed and why.
Late on a Friday, I asked Claude Code to “just fix the links on this page.” What came back filled the screen: confirmation after confirmation. “Run this command?” I was tired, so I barely read it and hit Enter.
The next morning, the pricing on my live site had changed. While it was fixing links, the AI had also “helpfully” edited a separate file where I’d written the prices. The button that approved it was, unmistakably, mine.
The problem wasn’t how smart the AI was. The problem was that the line between what I approved yesterday and what I should stop today lived only in my head, and it drifted every single time. If “eh, good enough” moves with my mood at the end of a long week, an accident is only a matter of time. So today I want to write up how to get that line out of my head and onto paper: an approval log.
Key takeaways
- Split Claude Code approvals into read, edit, run, and deploy, and the hesitation disappears.
- Sort each action into allow, ask, or block, and record the reason and a proof command in one file per day.
- Hand the AI research and first drafts; keep four things for yourself: pricing, production deploys, deletions, and anything you can’t undo.
- Below are a copy-paste log template and a prompt that makes the AI draft the sorting for you.
- When in doubt, don’t put it in “allow.” That one rule alone all but ended the “while-I-was-at-it” accidents.
Split approvals into read, edit, run, and deploy
When you use Claude Code, all kinds of confirmations fly at you. The reason it’s exhausting is that you lump them into one yes-or-no question every time. Split the work into four kinds and the decision gets dramatically lighter.
- Read: just looking at a file or log. Almost always fine to allow.
- Edit: rewriting a file. A typo in an article is no big deal. A pricing table is another story.
- Run: executing a command. A local sanity check is cheap; anything that reaches the outside world deserves care.
- Deploy: pushing to the live site. I always treat this as the last line of defense.
Even within “edit,” fixing a typo in a blog post and touching a payment-config file carry completely different weight. That’s why I decide not just the type of action but which file it touches, as a pair.
Sort every action into three levels
Once you have four kinds, sort each into three levels. You don’t need any fancy vocabulary.
| Level | Meaning | Example |
|---|---|---|
| Allow | Go ahead without asking | Read the article folder, fix a typo in the body |
| Ask | Check with me once | Edit a pricing file, deploy to production |
| Block | Not this time | Bulk-delete files, force-overwrite |
There’s exactly one trick: if you hesitate even a little, do not put it in “allow.” Park it in “ask.” Later, once you’re sure “this is always safe,” promote it to “allow.” Hold every rein at first, and loosen only the ones you’ve proven safe. Just keeping that order stops accidents like the pricing one above.
One file per day: the log template
Trying to remember it all is what breaks down. One file a day, where you just write down that day’s sorting. The format doesn’t matter, but this is what I settled on. Copy it and use it as-is.
{
"date": "2026-06-07",
"scope": "only swapping article bodies and CTA links",
"read": { "allow": ["site/src/content/**", "site/src/lib/gumroadProducts.ts"] },
"edit": { "allow": ["new article files"], "ask": ["pricing", "payment settings", "production secrets"] },
"run": { "allow": ["npm run build", "checking the live URL renders"], "ask": ["deploy", "git push"] },
"deploy": { "askUntil": ["build passes", "the live URL h1 is correct", "each language reviewed by eye"] },
"nextTime": "Keep pricing in ask. Promote article-CTA swaps to allow after a safety check."
}
Writing it takes two or three minutes. But those two or three minutes erase the ten minutes you’d spend the next day going “wait, what did I do here yesterday?” The scope line pulls more weight than it looks. Write down how far today’s work goes first, and the moment the AI steps outside it, you notice.
What to delegate to the AI vs. what you decide yourself
Mix these two and you’ll have an accident. Draw the line clearly.
Fine to hand the AI
- Finding which files are likely involved
- Drafting the changes
- Showing you the before/after diff
- Running a command that checks “does the build pass?”
Things you must keep yourself
- Any change that touches pricing, payments, or signup forms
- Deploying to the live site (you press the deploy button)
- Deleting files or data
- Any task you can’t explain how to undo
My rule is simple: whenever “money,” “production,” “deletion,” or “can’t undo” is involved, I make the final call with my own hands. Conversely, everything else, the research and the drafting, I hand to the AI without a second thought. I touch on this same boundary in Claude Code for non-engineers, but even without technical knowledge, deciding “money and production are mine alone” is enough to stay safe.
A prompt that makes the AI draft the sorting
You can even have the AI help with the sorting itself. Just don’t take the result at face value; you look at it last. Paste the instructions below and use them directly.
For today's Claude Code work, sort the actions into "allow," "ask," and "block."
The four kinds are: read / edit / run / deploy.
For each kind, return:
1. A list of actions that may be allowed
2. A list of actions to confirm once
3. A list of actions to block this time
4. Proof commands to verify safety (e.g., npm run build)
5. A note for next time (the condition to promote ask -> allow)
For anything touching pricing, payments, production deploys, or deletion,
put it in "ask" if you're unsure.
The point is that last line. With it in place, you stop the AI from quietly loosening its own judgment with “this one’s probably fine to allow.” If you want to sharpen how you write prompts, pair this with advanced Claude Code prompt design.
Three places this pays off
1. Swapping out a blog CTA You want to replace just one signup link under a popular post. Asking “fix anything that looks related” casts far too wide a net. Instead, write down beforehand which files you may touch, which you won’t, and which live URL to verify. Now the post-work check shifts from “seems okay” to “on this evidence, it’s fine to publish.”
2. Triaging inbound inquiries You let the AI read incoming inquiries and surface the promising ones. Reading can be “allow.” But adding someone to your customer list stays in “ask.” Even if the AI misclassifies, it stops before writing to your real production data on its own.
3. Pre-publish checks for multilingual articles Even when the frontmatter language is set correctly, the body sometimes still sits there in English. Look across each language at the heading, the opening, and the CTA, and confirm a reader in that language understands what to do next. Pin this eyeball check to your log as a “must-do before deploy” item.
Copy-paste and run: a pre-deploy check script
A log is useless if you skip the one thing that matters, the pre-deploy check. So fold the checks you must always pass into a single script before publishing. Here’s an example that makes the machine confirm whether the build passes and whether the live URL’s heading is correct. It runs anywhere Node.js is installed.
node check-before-deploy.mjs https://claudecode-lab.com/blog/claude-code-permission-decision-log/
That’s the whole thing.
import { execSync } from "node:child_process";
// The live URL passed as an argument is what we check
const url = process.argv[2];
if (!url) {
console.error("Pass the live URL you want to check");
process.exit(1);
}
// 1. Confirm the build passes (if it fails here, do not deploy)
try {
console.log("Checking the build...");
execSync("npm run build", { stdio: "inherit" });
} catch {
console.error("Build failed. Stopping the deploy.");
process.exit(1);
}
// 2. Confirm the live URL has exactly one h1 heading
const res = await fetch(url);
const html = await res.text();
const h1Count = (html.match(/<h1[\s>]/g) || []).length;
if (res.status !== 200) {
console.error(`Can't open the URL (status ${res.status}). Revisit the deploy.`);
process.exit(1);
}
if (h1Count !== 1) {
console.error(`Found ${h1Count} h1 headings. Fix it to exactly one before deploying.`);
process.exit(1);
}
console.log("Build, URL, and heading checks passed. Safe to deploy.");
Only when this script goes green do you allow “deploy.” Put another way, nothing that fails to go green gets deployed, no matter what. The trick is to hand the decision to a machine’s pass/fail rather than a human’s mood.
Common mistakes and how to fix them
Honestly, I made every one of these.
Changing settings without writing down why. Update the config file but leave out the “why,” and tomorrow’s you repeats the same hesitation. The fix is simple: write one line of reasoning in the log’s “next time” field. Something like “pricing stays in ask because it ties directly to trust.”
Allowing deploy on momentum. The build passes, and on that momentum you allow it all the way through to deploy. But the pre-deploy check is a separate thing. Pin the items you review, the live URL’s heading, layout breakage, mobile rendering, to “ask until,” and don’t deploy until the machine check passes.
Treating light and heavy work the same. Run a typo fix and a signup-link or price change through the same “allow,” and the accident from the opening happens eventually. Put work that touches gumroad links, pricing, or forms on a different shelf from typo fixes. Write this boundary into your CLAUDE.md best practices as a rule, and you stop having to think it through each time.
FAQ
Q. What’s the difference between an approval log and a security setting? A. A security setting fixes “what is allowed”; an approval log records “why you made today’s call.” The setting is a rule; the log is closer to a diary. With both, tomorrow’s you, or your team, can reproduce the same decision.
Q. Writing it every day is a hassle. Any tips for keeping it up? A. Don’t aim for perfect. At first, just the “edit” and “deploy” columns are plenty. Get it down to a form you can fill in two or three minutes, and make pasting it the first input before you start work; that’s what makes it stick.
Q. Can I trust the AI’s suggested sorting? A. It’s handy as a draft, but the final call is a human’s. Especially for rows touching pricing, production, or deletion: even when the AI says “allow is fine,” drop it back to “ask” yourself. The goal is to reduce the effort of deciding, not to outsource the deciding.
Q. Any cautions for using this with a team? A. Collect the logs in one place, and for anything you put in “allow,” write a reason that lands the same way for anyone who reads it. An allow with no reason gets interpreted differently by different people, and that’s where accidents start. For how to widen approvals gradually, the safe autonomy ladder is a useful companion.
Q. Is all this really necessary for a small blog? A. The smaller the operation, the more directly a pricing or link accident hits revenue. If anything, it’s individuals and small teams who most benefit from starting with one rule: “money and production are always ask.”
Reference links
- Claude Code permissions guide
- Claude Code getting-started guide
- Anthropic official: Claude Code settings docs
What happened when I actually tried it
After running this approval log for about two weeks, the thing that helped most was, surprisingly, the “light” work. Typo fixes I could comfortably leave in allow, while pricing, links, signup forms, and deploy settings stayed in ask. Just writing that distinction down beforehand erased the recurring effort of reading the AI’s reply and then thinking, “wait, is this a task I’m allowed to approve?”
Where I hesitated most was, predictably, “run” and “deploy.” The build is fine to allow, but deploying without checking the live URL is still too soon. Once I’d verified the heading, layout, and mobile rendering with my own eyes a single time, I could promote that same kind of deploy to allow going forward. Because the steps get recorded this way, my honest take now is that the approval log works best not as a stiff security document but as a daily note for making decisions lighter.
If you want to tailor these permission boundaries to your own team, or hammer out your production-deploy rules together, training and consultation can help you turn this into concrete day-to-day practice.
Free PDF: Claude Code Cheatsheet
Enter your email and download the one-page Claude Code cheatsheet for commands, review habits, and safe workflows.
We handle your data with care and never send spam.
Level up your Claude Code workflow
Start with the free cheatsheet, move to the setup guide or prompt pack when you hit a clear bottleneck, and use consultation only when you need workflow design help.
About the Author
Masa
Engineer focused on practical Claude Code workflows. Runs claudecode-lab.com, a 10-language technical media site.
Related Posts
You Memorized Every Claude Code Command and Still Freeze? Here's the Safe First Move
You learned the whole cheatsheet but freeze on what to ask. Here are the steps and prompt to land your first safe change.
Claude Code on an Inherited Repo: Make the First Edit Safe
Before Claude Code touches an inherited codebase, lock down what it may read, what's off-limits, and the check to run. A day-one playbook.
How to Write a Brief for Claude Code's First Task
A copy-paste brief that keeps your first Claude Code request from going off the rails: goal, allowed scope, proof, and rollback on one page.
Related Products
The Complete Claude Code Setup & Configuration Guide
From install to team-ready workflow.
A practical guide to installation, CLAUDE.md, hooks, MCP servers, permissions, IDE setup, and CI/CD workflows.
Claude Code Quick Reference Cheatsheet
A free one-page reference for daily Claude Code work.
Keep the essential commands, file-reference patterns, CLAUDE.md reminders, prompting habits, review cues, and debugging workflow notes next to your editor.