Skip to content

Course · Claude Code · Permissions & modes

Loosen the leash with Shift+Tab and accept-edits

A mechanical rename - say processPayment to capturePayment in the course’s payments service (a seven-file Express and TypeScript app), where the function is defined in src/payments/processor.ts and called from src/index.ts and tests/payments.test.ts - is the same safe edit repeated. In Claude Code’s default permission mode (a permission mode is a named posture that decides which actions stop and ask before they run), every one of those edits prompts you. Approving each one is exactly the friction that makes people stop using an agent for the boring jobs it is best at. The fix is to move the whole category of “edit a file” from ask to allow for the duration of the task, and the fastest way to do that is one keypress.

Press Shift+Tab in a running session and Claude Code cycles through the permission modes available to you; the current one shows in the status bar. The base cycle is:

default → acceptEdits → plan → default …
manual edits flow research/propose

Two more rungs slide into the cycle when they are available: auto (most actions run, a background classifier blocks unsafe ones) when your account and model qualify, and bypassPermissions (no normal prompts) only after you start the session with an enabling flag. One mode never appears in the cycle: dontAsk, which denies any call that would otherwise prompt; it is set with --permission-mode dontAsk because it is built for scripts, not sessions. The permission-modes reference owns the current list and labels, and the details of how each mode’s blocking works.

One press from default lands you in acceptEdits. Now the rename runs end to end without stopping. The transcript is illustrative:

> [Shift+Tab]
⏵⏵ accept edits on
> finish the rename across all remaining files
⏵ Edit src/index.ts ✓ applied
⏵ Edit tests/payments.test.ts ✓ applied
Done. Renamed processPayment → capturePayment in 3 files
(9 occurrences). The suite still passes.

You are approving a class of file edits for this task, then reviewing the result as one unit. Use git status, git diff --stat, git diff --check, and git diff after the run. This swaps inline per-edit review for after-the-fact batch review, which fits mechanical changes when you trust the direction.

One mechanical fact about that scope: acceptEdits does not lapse when the task ends. The mode persists until you cycle it back to default yourself - the cycle diagram above is the route back - so before starting a second, less reversible task in the same session, shift back toward the tighter rungs first.

The keypress is the easy part. Knowing which rung a task deserves is the discipline, and it never comes from how hard the work is. It comes from two properties of the task itself: how reversible a mistake is, and how far its effects reach. Set them for the rename - tracked files, your own repo - and see where it lands, then toggle either one up and watch how fast the ladder tightens. The dial is generic across tools; the mapping to Claude Code’s modes is the one above, except that plan is a posture change off the ask-frequency axis, not a looser rung on it.

Two questions decide how much leash a task earns - neither of them is “how hard is it.” Set both for the work in front of you and read the rung it lands on.

If the agent’s worst single action went wrong, undoing it would take…
…and its consequences would reach
  1. Run free, no fencedisposable environments onlyNothing pauses it and nothing contains it. No combination on this dial lands here - it belongs only where the whole environment is disposable: a throwaway container, an already-isolated CI runner.
  2. Run free inside a fencethis taskNo prompts; the boundary does the protecting. The agent grinds end to end inside a sandbox, container, or scratch worktree, and you review the whole batch once at the end.
  3. Auto-apply edits, gate the rest
  4. Ask before acting
  5. Read & propose only

A mechanical rename across your own repo is the canonical case: the worst outcome is a git diff you throw away. Prompting on every one of twenty-four identical edits doesn’t add safety - it teaches you to stop reading prompts, which is where real risk starts. Let it run inside the fence and review the batch once.

The rung names are generic on purpose - every tool spells its own versions of them, and most let you set different rungs for different categories of action. The judgment underneath is the same two questions, asked per task, never answered once for all time.

If the dial does not render, the rule it encodes is short: reversible and contained work earns a looser mode; anything irreversible or far-reaching earns a tighter one, whatever the effort involved.

This is the part that makes accept-edits safe rather than reckless, and it is worth being precise about. Loosening the leash on edits does not loosen it on everything:

  • It auto-approves file edits and a handful of routine filesystem commands (mkdir, touch, mv, cp, and the like), but only for paths inside your working directory. An edit to something outside the project still stops and asks.
  • It does not auto-approve arbitrary shell commands. The agent wanting to run npm test or curl still prompts; an allow rule is the tool for that.
  • It still stops and asks before touching protected paths - your .git directory, Claude Code’s own .claude configuration, shell startup files such as .zshrc, your .mcp.json. Those are guarded in normal permission modes; bypassPermissions is the exception, and the hands-off lesson explains why it belongs only in a container.

So accept-edits is a scoped loosening. Ordinary edits get smoother while other actions remain subject to rules and prompts; that mix of loosening and enforcement is the course’s control principle at work - what guides execution, enforces boundaries, or allows intervention. The exact behavior is versioned; check the permission-modes docs rather than trusting a fixed memory of it.

You will have noticed plan mode in the cycle, the rung where the agent reads and proposes but makes no source edits. It is not a guarantee in a session started with the bypass-enabling flag - when bypassPermissions is the active mode or sits in your mode cycle - so check the cycle before relying on it as a safety boundary. It earns its own chapter.

The rename is done. The next kind of friction is a test-and-build loop, and accept-edits will not answer repeated shell prompts. Pre-approve the commands you trust.