3.3–3.4 settings.json and Claude Code's Operating Modes
3.3.1 settings.json as the Deterministic Control Surface
settings.json — at ~/.claude/settings.json for the user level and .claude/settings.json at the project level — is where Claude Code's behavior and permissions are actually configured. It's the deterministic control surface: which tools are allowed or denied, hook definitions (code that runs at defined points in the agent loop), environment variables, model selection, and MCP server configuration all live here.
"Deterministic" is the word to hold onto. An allow/deny rule or a hook defined in settings.json can block a dangerous command regardless of what the model proposes that turn — it doesn't matter whether the model "decided" to run rm -rf or was tricked into proposing it by adversarial input; the rule fires the same way every time, because it's enforced structurally, outside the model's discretion. This is the same idea that shows up under a different name in Domain 7 (security and safety): a prompt-level instruction is probabilistic, a settings.json rule or hook is deterministic.
- •Tool allow/deny lists — which tools Claude Code is permitted to invoke at all.
- •Hook definitions — deterministic code callbacks at defined points in the agent loop.
- •Environment variables and model selection.
- •MCP server configuration.
3.3.1 — Key Concept
settings.json (user: ~/.claude/settings.json, project: .claude/settings.json) configures tool permissions, hooks, env vars, model selection, and MCP servers — and it's deterministic: a rule or hook here enforces the boundary structurally, regardless of what the model proposes.
3.3.2 CLAUDE.md vs. settings.json: Probabilistic vs. Deterministic
Lesson 3.2 already flagged this pairing; here's the fuller version. A well-written CLAUDE.md instruction — "never run destructive commands" — is not an adequate substitute for a settings.json permission rule. The former is a probabilistic nudge: the model reads it as context and generally follows it, but adversarial input, an ordinary mistake, or a long context window drifting away from an early instruction can all cause it to be missed or overridden. The latter is a deterministic gate: the code either allows the action or it doesn't, independent of the model's reasoning that turn.
| CLAUDE.md | settings.json | |
|---|---|---|
| Nature | Context/memory loaded into the model's prompt | Executable configuration enforced outside the model |
| Compliance | Probabilistic — the model generally follows it | Deterministic — enforced structurally, every time |
| Right for | Conventions, architecture notes, commands, gotchas | Permission scoping and hook-based guardrails on high-stakes actions |
The exam consistently rewards routing permissions and hooks to settings.json and routing context/conventions to CLAUDE.md — never the reverse.
3.3.2 — Exam Trap
Exam trap: an answer choice that puts tool permissions, hooks, environment variables, or MCP server config inside CLAUDE.md. Every one of those belongs in settings.json. CLAUDE.md cannot enforce anything — it can only be read and (usually) followed.
3.3.3 The Full Hook Event Lifecycle
PreToolUse and PostToolUse are the two hook events that come up most, because they sit directly on the tool-call boundary -- one gates whether a call happens, the other gates what comes back. But the agent lifecycle has several more hook events, each bound to a different moment in a session, configured the same way in settings.json: a lifecycle event plus a command that runs when it fires.
| Event | Fires | Typical use |
|---|---|---|
| PreToolUse | Before a tool call executes | Block or approve the call before it runs |
| PostToolUse | After a tool call completes | Format, validate, log -- side effects on a call that already happened |
| UserPromptSubmit | Before the model processes a submitted prompt | Inject context, or validate the incoming prompt before any work starts |
| Stop | When the model finishes responding | Notifications, cleanup, committing an audit-log entry |
| Notification | On a permission request, or after 60 seconds of idle time | Forward that event to wherever you want it surfaced -- a chat channel, a monitoring dashboard, an audit log |
| SessionStart | At session init (start or resume) | Validate environment variables, confirm dependent services are reachable |
| SessionEnd | At session teardown | Final audit writes, teardown tasks, close-out notifications |
PreToolUse/PostToolUse bracket a single tool call; UserPromptSubmit/Stop bracket a single turn; SessionStart/SessionEnd bracket the whole session; Notification fires on a specific signal regardless of where in the lifecycle it occurs.
3.3.3 -- Key Concept
All seven events run as deterministic code, exactly like PreToolUse/PostToolUse -- they fire every time the event occurs, regardless of what the model decides. A scenario describing 'validate that a required service is reachable before the agent starts working' is describing SessionStart, not PreToolUse -- that check needs to happen once, at the very start of the session, not before every individual tool call.
3.4.1 Session Management and the Three Operating Modes
Claude Code conversations persist as sessions that can be resumed later rather than being lost the moment a terminal closes. /clear resets the conversation context to keep it focused — a manual antidote for when accumulated history has stopped being relevant to the current task (context rot). Beyond session basics, Claude Code exposes three operating-mode axes, and the exam consistently tests whether you can tell them apart: headless mode, streaming mode, and auto-mode.
Headless mode runs Claude Code non-interactively — for example claude -p "..." — with no interactive TUI, suited to scripting, CI pipelines, and automation. Streaming mode emits output incrementally, including structured stream-JSON, for programmatic consumption of output as it's produced rather than waiting for a final block. Auto-mode is reduced-friction autonomous operation: Claude proceeds with less step-by-step confirmation, trading human checkpoints for speed.
| Mode | What it does | Typical use |
|---|---|---|
| Headless | Runs non-interactively (e.g. claude -p), no TUI | Scripting, CI pipelines, automation |
| Streaming | Emits output incrementally, including stream-JSON | Programmatic consumption of output as it's produced |
| Auto-mode | Proceeds with less step-by-step confirmation | Faster iteration, at the cost of fewer human checkpoints |
Three independent axes. A single run can combine any of them — headless and streaming together describe a CI job consuming incremental output, for instance.
Headless (interactivity), streaming (output delivery), and auto-mode (autonomy) are orthogonal settings, not points on one spectrum — a run can be any combination of the three at once.
"claude -p" is shorthand for a small, specific flag set worth knowing individually. --print / -p is the flag that makes headless mode headless -- non-interactive output, no TUI, process the prompt and exit. --output-format is a separate, composable choice layered on top of that: a headless run can emit plain text, or it can emit structured output (e.g., stream-JSON) that a calling script parses incrementally instead of waiting for one final blob. --resume and --continue solve session continuity across separate invocations -- --resume reattaches to a specific named prior session, while --continue picks up the most recent session without naming one.
| Flag | What it controls |
|---|---|
| --print / -p | Non-interactive, headless output -- process the prompt, print the result, exit |
| --output-format | Selects structured output (e.g., stream-JSON) for programmatic consumption |
| --resume | Reattaches to a specific prior session and continues it |
| --continue | Continues the most recent session without needing to specify a session ID |
-p (interactivity) and --output-format (output shape) are two different dials, not one setting -- a headless run can combine either with either.
3.4.2 Headless vs. Auto-Mode: The Recurring Exam Trap
The single most repeated confusion in this task statement is headless mode vs. auto-mode, and the exam leans on it hard. Headless mode is about interactivity — is there a TUI prompting for confirmation, or not? Auto-mode is about autonomy — how many step-by-step confirmations does Claude ask for before acting, regardless of whether the session is interactive at all? A scenario describing "running in a CI pipeline" is describing headless mode; a scenario describing "letting Claude proceed without confirming each step" is describing auto-mode. They are independent settings — headless does not imply auto-mode, and a fully interactive session can still run in auto-mode.
Because auto-mode removes confirmation checkpoints, it raises the stakes of any single action Claude takes — there's no human in the loop to catch a bad call before it fires. That's exactly why auto-mode should always be paired with settings.json permission rules and hooks (from 3.3), not used unguarded: the deterministic controls that would otherwise be backed up by a confirmation prompt need to be enforced structurally instead, since the prompt-level checkpoint has been removed.
3.4.2 — Exam Trap
Exam trap: confusing headless mode (interactivity — no TUI, suitable for CI/scripting) with auto-mode (autonomy — fewer confirmations before acting). A question may describe "running in a CI pipeline" as a distractor for a question actually asking about auto-mode, or vice versa. Also don't assume streaming implies headless, or headless implies auto — the three axes are independent.
3.4.3 The Best-Practice Loop: Gather Context → Plan → Act → Verify
Anthropic's operational guidance for using Claude Code well is a repeatable loop: gather context, make a plan, act, and verify. Understand the task and codebase first; form an explicit plan rather than improvising step by step; execute that plan; and use tests or builds as ground-truth verification rather than trusting the model's own claim that it succeeded. Verification against an objective signal — a passing test, a clean build — is what actually closes the loop; a self-report ("I've completed the task") is not evidence on its own.
- 1.GATHER CONTEXT — understand the task and the relevant parts of the codebase before proposing anything.
- 2.MAKE A PLAN — form an explicit plan rather than improvising turn by turn.
- 3.ACT — execute the plan.
- 4.VERIFY — check against ground truth (tests, builds) rather than the model's own claim of success.
The loop is meant to be tightened over time, not re-invented every session: encode a repeated procedure once as a custom slash command (3.1) rather than re-typing a long, brittle prompt, and back a hard rule with a hook (3.3) rather than hoping a prompt instruction holds. Put together, this whole domain is really one connected system — components (3.1) that package behavior, memory (3.2) that carries context, configuration (3.3) that enforces boundaries deterministically, and modes (3.4) that determine how a session runs — all in service of the same gather → plan → act → verify discipline.
Where this shows up on the exam
Where this shows up on the exam: a scenario names a specific need — CI automation, incremental output for a dashboard, faster iteration with less confirmation — and asks which mode or practice fits. Map interactivity to headless, output delivery to streaming, autonomy to auto-mode (paired with settings.json/hooks), and any "how do I use Claude Code well" framing back to gather → plan → act → verify.
Key Takeaways
- ✓settings.json (user: ~/.claude/settings.json, project: .claude/settings.json) configures tool permissions, hooks, environment variables, model selection, and MCP servers — the deterministic control surface.
- ✓A settings.json allow/deny rule or hook blocks an action regardless of what the model proposes; a CLAUDE.md instruction is probabilistic and can be overridden — permissions and hooks always belong in settings.json, never CLAUDE.md.
- ✓Session management persists conversations as resumable sessions; /clear resets context to stay focused when history has stopped being relevant.
- ✓The three operating-mode axes are independent: headless mode (non-interactivity, e.g. claude -p, for CI/scripting), streaming mode (incremental/stream-JSON output for programmatic use), and auto-mode (reduced-confirmation autonomy).
- ✓Headless mode and auto-mode are the most commonly confused pair — headless is about interactivity, auto-mode is about autonomy, and neither implies the other.
- ✓Auto-mode should always be paired with settings.json permission rules and hooks, since removing confirmation checkpoints raises the stakes of any single action.
- ✓The best-practice loop is gather context → make a plan → act → verify, tightened over time with custom commands and hooks rather than long, brittle ad-hoc prompts.
- ✓The full hook lifecycle is PreToolUse, PostToolUse, UserPromptSubmit, Stop, Notification, SessionStart, and SessionEnd -- each bound to a different moment (a tool call, a turn, a specific signal, or the whole session)
- ✓SessionStart is the correct place to validate environment variables or confirm a dependent service is reachable -- not PreToolUse, which fires per tool call rather than once at session init
- ✓The headless/streaming flag set: --print/-p for non-interactive output, --output-format to select structured output like stream-JSON, and --resume/--continue for session continuity across invocations
Check Your Understanding
Test what you learned in this lesson.
Q1.A team wants to guarantee that a specific destructive shell command can never run, no matter what the model is told or decides mid-session. Where should this rule live?
Q2.A pipeline needs to run Claude Code with no interactive prompt at all, invoked from a CI script. Which mode is being described?
Q3.A developer enables auto-mode to speed up iteration but has not configured any settings.json permission rules or hooks. What is the risk, and what's the recommended fix?
Q4.Which sequence correctly describes Anthropic's best-practice operating loop for Claude Code?
Q5.A team wants to confirm that a dependent service is reachable before the agent begins any work in a new session. Which hook event fits?
Q6.A CI script needs Claude Code to run with no interactive prompt and to emit stream-JSON so the script can parse output incrementally. Which flags accomplish this?
Practice This Lesson