Auto Coding Levels
Module 7.1: Auto Coding Levels
Section titled “Module 7.1: Auto Coding Levels”Estimated time: ~30 minutes
Prerequisite: Phase 6 (Thinking & Planning), Module 2.2 (Permission System)
Outcome: After this module, you will be able to pick a permission mode per task using the Risk × Familiarity matrix, switch it with
Shift+Tab/--permission-mode/permissions.defaultMode, and explain whyautomode is notbypassPermissions.
1. WHY — Why This Matters
Section titled “1. WHY — Why This Matters”You press “Yes” 40 times to add logging to ten functions. Next day you switch everything off and Claude “cleans up” a config file you needed. Same mistake twice: treating automation as a switch.
Claude Code ships that spectrum as permission modes. The three “levels” here are labels; the modes are the mechanism, enforced by Claude Code, not by the model.
2. CONCEPT — Core Ideas
Section titled “2. CONCEPT — Core Ideas”The modes the docs list
Section titled “The modes the docs list”The permissions page lists six modes plus one alias. This course groups them into three levels:
| Level | Mode | What runs without asking | Best for |
|---|---|---|---|
| 1 — Manual | default (alias manual) | Reads only | Reviewing every action, sensitive work |
| 1 | plan | Reads, plus classifier-approved commands when auto mode is available; no source edits until you approve a plan | Exploring before changing anything |
| 2 — Semi-Auto | acceptEdits | Reads, file edits, and mkdir/touch/rm/rmdir/mv/cp/sed inside the working dir | Iterating on code you’ll review in git diff |
| 2 | auto | Everything, with a classifier reviewing each action | Long tasks, prompt fatigue |
| 2 (CI) | dontAsk | Reads + pre-approved tools; anything that would prompt is denied | Locked-down scripts |
| 3 — Full Auto | bypassPermissions | Everything | Isolated containers/VMs only |
Read the acceptEdits row twice: rm and rmdir are in that set. Auto-approval is scoped to
your working directory and additionalDirectories — but inside that scope, a delete runs
without asking.
graph LR
L1["Level 1: default / plan<br/>you approve"] -->|Shift+Tab| L2["Level 2: acceptEdits / auto<br/>guardrails + classifier"]
L2 -->|sandbox only| L3["Level 3: bypassPermissions<br/>no prompts, no checks"]
How to set the mode
Section titled “How to set the mode”- During a session:
Shift+Tabcyclesdefault→acceptEdits→plan→ (autoif available) → back.bypassPermissionsonly joins the cycle if you started with it enabled;dontAsknever does. - One session:
claude --permission-mode plan(also works with-p). - Every session in a project:
permissions.defaultModein.claude/settings.json. Terminal sessions honor every value there exceptautoandbypassPermissions, which apply only from user or managed settings. - Org-wide off switch:
permissions.disableBypassPermissionsMode/disableAutoMode="disable"in managed settings.
What auto mode is — and isn’t
Section titled “What auto mode is — and isn’t”auto is the built-in starting mode on Pro/Max/Team. A second model, the classifier, reviews
each action and blocks anything that “escalates beyond your request, targets unrecognized
infrastructure, or appears driven by hostile content Claude read”. Anthropic reports 84% fewer
prompts in internal use with this two-layer classifier design (S13, “How we built Claude Code
auto mode”, 2026-03-25). The docs are blunt: “Auto mode reduces permission prompts but does not
guarantee safety.” Level 2 with a reviewer, not Level 3. If the classifier blocks 3 actions in a
row (or 20 total), auto mode pauses and you’re prompted again.
Risk × Familiarity matrix (keep this)
Section titled “Risk × Familiarity matrix (keep this)”| Task risk | Familiarity | Mode |
|---|---|---|
| Low (formatting, tests) | High | acceptEdits or auto |
| Low | Low | plan first, then acceptEdits |
| High (DB, auth, payments) | High | default + permissions.deny on hot paths |
| High | Low | default — always |
Modes set the baseline. permissions.allow/deny/ask rules layer on top, and deny rules block
in every mode, including bypassPermissions (Module 2.2). CLAUDE.md is advisory.
(S13):docs/references/anthropic-sources.md.
3. DEMO — Step by Step
Section titled “3. DEMO — Step by Step”Run in ~/cc-lab (src/math.js, tests/math.test.mjs, npm test). This machine’s user
settings start sessions in auto, so each command pins a mode.
Step 1: Read the mode indicator, then cycle it
# docs: permission-modes#switch-permission-modesclaude --permission-mode defaultStatus bar on start, then after each Shift+Tab:
# Output may vary ⏸ manual mode on ⏵⏵ accept edits on (shift+tab to cycle) ⏸ plan mode on (shift+tab to cycle) ⏵⏵ auto mode on (shift+tab to cycle)Why: that label is the only place the mode is shown — read it before risky work.
Step 2: Level 1 headless — plan mode proposes, never edits
# docs: permission-modes#analyze-before-you-edit-with-plan-modeclaude --permission-mode plan -p "Propose how to add a subtract function to src/math.js with a test. Do not edit any file."git status --short# Output may varyHere's the proposal (no files touched; the plan is saved at `~/.claude/plans/propose-how-to-add-keen-dahl.md`).…- `src/math.js:1-2` exports `add` and `divide` as one-liners.…Run `npm test` — expect 2 passing tests (`add`, `subtract`), 0 failing.git status prints nothing: plan mode read the repo and wrote only the plan.
Step 3: Level 1 interactive — the real permission prompt
# docs: permissions#permission-systemclaude --permission-mode defaultPrompt: Create a file hello.txt containing hi
# Output may vary⏺ Write(hello.txt) Create file hello.txt 1 hi Do you want to create hello.txt? ❯ 1. Yes 2. Yes, and switch to accept edits (auto-approve file edits and common file commands) for this session (shift+tab) 3. No Esc to cancel · Tab to amendOption 2 is the jump to Level 2. A Bash prompt offers a different second option,
Yes, and don't ask again for: npm test *, saved to .claude/settings.local.json as
Bash(npm test *). Press Esc and Claude reports User rejected write to hello.txt.
Step 4: Headless has no prompt — so the mode decides
# docs: headless#auto-approve-toolsclaude -p "Create a file hello.txt containing hi" --permission-mode defaultls hello.txt# Output may varyThe write to `hello.txt` was blocked pending your permission. Please approve the write request and I'll create the file, or let me know if you'd prefer a different approach.ls: hello.txt: No such file or directory--permission-mode default forces the stock behavior; on Pro, Max and Team plans the built-in
starting mode is auto, which permissions.defaultMode overrides. Level 2:
claude -p "Create a file hello.txt containing hi" --permission-mode acceptEditscat hello.txt# Output may varyCreated `/Users/luatnq/cc-lab/hello.txt` containing `hi`.hiStep 5: Make Level 2 the project default
# docs: permission-modes#start-in-a-different-modemkdir -p .claude && cat > .claude/settings.json << 'EOF'{ "permissions": { "defaultMode": "acceptEdits" }}EOFclaude# Output may vary ⏵⏵ accept edits on (shift+tab to cycle)Project settings outrank the user file, so the session starts at Level 2 with no flag.
Step 6: Level 3 — real flag, sandbox only
# docs: cli-reference — equivalent to --permission-mode bypassPermissionsclaude --dangerously-skip-permissionsThe flag is real; don’t run it on your host. Use it only inside a sandbox or container (Module 2.3). It refuses to start as root and deny rules still apply — but every prompt and the classifier are gone.
Clean up: rm hello.txt .claude/settings.json.
4. PRACTICE — Try It Yourself
Section titled “4. PRACTICE — Try It Yourself”Exercise 1: Count the prompts
Section titled “Exercise 1: Count the prompts”Goal: Feel the difference between Level 1 and Level 2 on a low-risk task. Instructions:
claude --permission-mode default, prompt: “Add a one-line JSDoc comment above each function in src/math.js”. Count the prompts.git checkout -- src, repeat with--permission-mode acceptEdits. Which matched the risk?
Expected result: one prompt per edit in default; zero in acceptEdits.
💡 Hint
Watch the status bar; in `acceptEdits` you review the result with `git diff`, not inline.✅ Solution
`default` prompts once per `Edit`. `acceptEdits` auto-approves edits inside the working directory, so the run is silent; `git diff src/math.js` is your review step.Exercise 2: Pick the mode
Section titled “Exercise 2: Pick the mode”Goal: Train the matrix. For each task, pick a mode and one rule.
- Prettier on 150 files. 2. Edit a DB migration. 3. New endpoint following an existing pattern.
- Change auth logic. 5. Generate tests for pure functions.
✅ Solution
| Task | Mode | Extra guardrail |
|---|---|---|
| Prettier | acceptEdits | git diff --stat after |
| Migration | default | "deny": ["Edit(./migrations/**)"] until reviewed |
| Endpoint | acceptEdits | plan first if the pattern is unclear |
| Auth | default | "deny": ["Read(./.env)"] |
| Tests | auto | Stop hook running npm test (Module 11.3) |
5. CHEAT SHEET
Section titled “5. CHEAT SHEET”| Command / Feature | Description | Example |
|---|---|---|
Shift+Tab | Cycle mode in-session | default → acceptEdits → plan → auto |
--permission-mode <mode> | Start in a mode; works with -p | claude --permission-mode plan |
permissions.defaultMode | Default per machine/project/org | {"permissions": {"defaultMode": "acceptEdits"}} |
/permissions | View/edit allow, ask, deny rules | rules evaluate deny → ask → allow |
/plan | Plan mode for one prompt | /plan refactor the parser |
--dangerously-skip-permissions | = --permission-mode bypassPermissions | sandbox/container only |
disableBypassPermissionsMode | Managed off switch | "disable" |
| Prompt keys | 1/Enter Yes · 2 session/rule · Esc cancel · Tab add a comment | — |
6. PITFALLS — Common Mistakes
Section titled “6. PITFALLS — Common Mistakes”| ❌ Mistake | ✅ Correct Approach |
|---|---|
Teaching or expecting a [y]/[a]/[n] prompt | It doesn’t exist. Prompts are numbered options; Esc cancels, Tab adds a note |
bypassPermissions on your laptop | Only inside a sandbox/container; deny rules still hold, nothing else does |
Treating auto as “totally safe” | It reduces prompts; it is not a substitute for review on sensitive changes |
defaultMode: "auto" in .claude/settings.json | Ignored there — put it in ~/.claude/settings.json or managed settings |
| Boundaries stated only in the prompt | The classifier reads them but compaction can drop them; add a permissions.deny rule |
| Same mode for every task | Use the matrix: familiarity and blast radius, not habit |
7. REAL CASE — Production Story
Section titled “7. REAL CASE — Production Story”Scenario: A Vietnamese team onboarding onto a 15-service backend with shared libraries.
Problem: Week 1 in default was slow but caught misunderstandings. By week 2 repetitive work
ran in acceptEdits and CI docs ran headless with --permission-mode acceptEdits in a
container. Then a developer ran a schema change in auto with a vague prompt: “Add user
preferences table”. Claude guessed the column types; the migration failed in staging.
Solution: The team rule became the matrix. Unfamiliar + high-risk → default, with
"deny": ["Edit(./migrations/**)"] until a human reviews. Familiar + low-risk → acceptEdits.
bypassPermissions only in the CI container. The migration was redone in plan mode, then
executed with acceptEdits.
Result: No further staging incidents from automation mismatches in the following two months.
Next: Module 7.2: Full Auto Workflow →