What You Need to Know
Claude Code reads its configuration from files on disk and from flags on the command line. A component is one kind of file it loads: rules, skills, commands, agents and agent memory. A scope is where a file lives and who it applies to: managed by an organisation, user-wide in your home directory, project-wide and checked in, or local and personal. Settings are JSON files holding values such as the model and the permission rules. A permission mode decides which actions Claude may take without asking. A session is one saved conversation.
Take a cake shop that keeps its online ordering site in one repository. Two developers work on it, and a nightly script checks the order pages. For the cake shop, every configuration choice has the same shape: which file, at which scope, in which mode. Each answer is a file you can open or a flag you can pass.
Five Components, Five Places on Disk
Rules are markdown constraints. Project rules live in .claude/rules/ and user rules in ~/.claude/rules/. A project rule with no paths frontmatter loads at launch with the same priority as .claude/CLAUDE.md. With paths frontmatter, the rule applies to matching files instead. The cake shop could scope a price-formatting rule to its checkout files this way. User rules load before project rules, so a project rule sits later in context. Neither set overrides the other. Where the two conflict, Claude may follow either, so keep them consistent. The permissions block in settings.json carries the other kind of rule.
Skills are procedures packaged as a directory holding a SKILL.md. Personal skills live in ~/.claude/skills/<name>/ and project skills in .claude/skills/<name>/. Managed settings and plugins can supply them too. Claude invokes a skill when its description matches the task, or you type /skill-name. The body loads only when used. When two skills share a name, enterprise beats personal and personal beats project. That is the opposite way to settings precedence. If a cake shop developer has a personal skill with the same name as a project skill, the personal one runs.
To change a skill's visibility without editing its SKILL.md, set skillOverrides in settings (September 2026). user-invocable-only hides the skill from Claude but keeps /name working for you. name-only lists it to Claude without its description. off hides it everywhere. The /skills menu saves the choice to .claude/settings.local.json, a personal file, so teammates are unaffected.
Commands come in three kinds:
- Built-in slash commands execute fixed CLI logic:
/init,/clear,/compact,/context,/memory,/resume,/permissions,/model,/agents. - Bundled skills such as
/doctorand/code-revieware prompts handed to Claude. - Custom commands have merged into skills.
The docs say so explicitly (August 2026): .claude/commands/deploy.md and .claude/skills/deploy/SKILL.md both create /deploy and work the same way. Existing command files keep working, and the skill wins a name clash. If the cake shop has both files for /deploy, the skill runs. Both take arguments through $ARGUMENTS. $0 and $1 index individual positions, counting from zero, so $0 is the first argument.
Agents are subagents. Project subagents are defined in .claude/agents/ and user ones in ~/.claude/agents/. The frontmatter requires name and description, while tools, model and memory are optional. Each subagent runs in its own context window, with the markdown body as its system prompt. Only its final result returns to the main conversation.
Subagent name clashes follow the settings direction, not the skills one (September 2026). Managed definitions come first, then --agents JSON for the current session, then .claude/agents/, then ~/.claude/agents/, then plugins. So a personal copy never shadows a project subagent of the same name. A model in the definition, or one Claude passes at spawn time, outranks CLAUDE_CODE_SUBAGENT_MODEL. Set CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1 as well and every subagent runs on that model, with two exceptions. A fork, and a skill that runs in a subagent with model: inherit, both stay on the main conversation's model. The force setting needs Claude Code v2.1.257 or later.
A definition's permissionMode is ignored while the main session is in acceptEdits, auto or bypassPermissions. The subagent takes the parent's mode instead. Say the cake shop has a reviewer subagent that must never edit the order code. Its permissionMode setting stops counting once the main session runs in acceptEdits. So take the editing tools out of its tools list.
Agent Memory is auto memory, stored at ~/.claude/projects/<project>/memory/. A MEMORY.md index loads at the start of every conversation, capped at its first 200 lines or 25KB. Topic files load on demand. Auto memory is per repository, shared across worktrees, machine-local and on by default. What Claude learns about the order site on one cake shop laptop stays on that laptop. To switch it off for one repository, set autoMemoryEnabled: false in that project's settings. The /memory toggle writes your user settings and switches it off across all your projects. CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 does the same.
A plugin bundles skills, subagents, hooks and MCP servers as one installable unit, usually from a marketplace (September 2026). To share one across repositories, a team registers its private marketplace under extraKnownMarketplaces and enables the plugin under enabledPlugins, both in each repository's .claude/settings.json. To cover a whole organisation instead, the same two keys go in managed settings. The marketplace entry applies only once a contributor trusts the folder.
An output style sets Claude's role, tone and format for a whole session (September 2026). Styles live in .claude/output-styles/ or ~/.claude/output-styles/, and outputStyle chooses one. On Claude Code's full system prompt, a custom style drops the built-in software engineering instructions, such as how to scope changes and verify work. Setting keep-coding-instructions: true in its frontmatter keeps them. The shorter system prompt never carries that section, so there the field changes nothing.
your-repo/
├── CLAUDE.md # project instructions, checked in
├── CLAUDE.local.md # personal instructions, gitignored
└── .claude/
├── settings.json # team configuration, checked in
├── settings.local.json # personal configuration, auto-gitignored
├── rules/testing.md # standing constraints, optionally path-scoped
├── skills/release-notes/SKILL.md
├── commands/release-notes.md # same /release-notes; the skill wins
└── agents/reviewer.md
CLAUDE.md is what you write for Claude. Auto memory is what Claude writes for itself. Both are context, and neither enforces anything.
CLAUDE.md Concatenates, settings.json Overrides
CLAUDE.md files come in four scopes, broadest first:
- Managed policy:
/Library/Application Support/ClaudeCode/CLAUDE.mdon macOS,/etc/claude-code/CLAUDE.mdon Linux and WSL,C:\Program Files\ClaudeCode\CLAUDE.mdon Windows. IT deploys it, and individual settings cannot exclude it. - User:
~/.claude/CLAUDE.md. - Project:
./CLAUDE.mdor./.claude/CLAUDE.md. - Local:
./CLAUDE.local.md, which you gitignore.
Claude Code concatenates the files it discovers into context. They do not override each other. A more specific file lands after a broader one instead of replacing it. Claude Code walks up the directory tree from the working directory. Launched in foo/bar/, it orders foo/CLAUDE.md before foo/bar/CLAUDE.md, and each CLAUDE.local.md after its sibling. Files in subdirectories below load on demand. The cake shop's project CLAUDE.md says how to run the order-site tests. A developer's CLAUDE.local.md adds personal notes. Claude gets both, the personal notes second.
@path/to/import pulls in more from anywhere in a CLAUDE.md. The import resolves against the importing file and expands at launch, recursing to a maximum depth of four hops. Repository initialisation is /init. It analyses the codebase and writes a starting CLAUDE.md of build commands, test instructions and conventions. Where one exists, it suggests improvements rather than overwriting. /context shows what loaded, under Memory files. /memory opens any of it for editing.
Two controls, both dated September 2026, change which instruction files load at all. The first is claudeMdExcludes. It skips CLAUDE.md and rules files by path or glob and works from any settings file, though managed policy files cannot be excluded. A monorepo developer can keep another team's file out of their own sessions by setting it in .claude/settings.local.json. Asking Claude in a sentence to ignore that file does not work, because the sentence only adds more context.
The second is AGENTS.md, which Claude Code reads from v2.1.277. By default it reads AGENTS.md only when no CLAUDE.md, .claude/CLAUDE.md or CLAUDE.local.md exists in the working directory or above it. So adding a personal CLAUDE.local.md switches AGENTS.md off. Setting Project instructions to claude-md-and-agents-md in /config loads both. Claude Code ignores that value in project and local settings files.
Settings run the other way, as a real precedence chain. From highest to lowest it runs managed, command line arguments, local .claude/settings.local.json, project .claude/settings.json, then user ~/.claude/settings.json. Managed settings cannot be overridden. The project file is the team baseline, checked in. The local file is personal and outranks the shared one. It is auto-gitignored: Claude Code adds **/.claude/settings.local.json to your global git excludes file.
That chain settles single values such as model. List settings such as permissions.allow merge across files instead (September 2026). A local file can add entries but never remove a shared one. To get a prompt back for a command the team allows, add an ask rule. Rules are checked deny first, then ask, then allow, so the ask rule is reached before the allow rule. If the cake shop's project file allows the test command, a developer who wants to approve each run adds an ask rule locally.
{
"permissions": {
"defaultMode": "default",
"allow": ["Bash(npm run test *)", "Bash(git diff *)"],
"deny": ["Bash(git push *)", "Read(./.env)"]
},
"model": "claude-sonnet-5-5",
"env": { "NODE_ENV": "test" }
}The memory page states the split directly: "Settings rules are enforced by the client regardless of what Claude decides to do. CLAUDE.md instructions shape Claude's behavior but are not a hard enforcement layer." Conventions belong in CLAUDE.md. Anything that must hold whatever the model decides belongs in a deny rule or a hook. The cake shop's naming conventions go in CLAUDE.md. A ban on reading its payment keys file goes in a deny rule.
A sentence is not a control
"Never touch the production config" written into CLAUDE.md is a request. The same prohibition as a permissions deny rule is enforced by the client. Deny rules block in every permission mode, including bypassPermissions, where allow rules have no effect at all.
A cloned repository cannot grant itself capability (September 2026). Its .claude/settings.json may hold permissions.allow rules and additionalDirectories, plus .mcp.json approvals such as enabledMcpjsonServers. These take effect only once someone accepts the workspace trust dialog for that folder. Deny and ask rules apply regardless, because they only restrict. A new cake shop developer who clones the order site gets its deny rules at once, and its allow rules after trusting the folder.
The status line is another settings entry. statusLine runs your script with session JSON on stdin. It re-runs the script on events such as a new assistant message. So it can go quiet while the main session sits idle, unless refreshInterval adds a timer. A script that caches its output should store the cache under the input's session_id. A process ID changes on every run, so a cache stored under it would never hit.
Sessions, Headless and Streaming
Sessions save continuously as local JSONL transcripts at ~/.claude/projects/<project>/<session-id>.jsonl, so exiting loses nothing. There are four ways back in.
claude --continue(-c) opens the most recent session in the current directory.claude --resumewith no argument opens the picker.claude --resume <name-or-id>goes straight to one session./resumeworks from inside a running session.
As of September 2026, sessions created by claude -p or the Agent SDK stay out of the picker and out of a plain claude --continue. They still resume by ID, and claude -p --continue includes them. The cake shop's nightly runs will not crowd a developer's picker.
A resumed session brings back the conversation and the model it was using. The permission mode is fussier (September 2026). It comes back only on a terminal resume by --continue, by ID or by a unique name, without -p. Even then bypassPermissions and plan do not come back, among a few narrower cases. They fall back to the mode a new session would start in. The picker and /resume never restore the mode. claude -p --resume or -p --continue starts where a new -p run would, bar one narrow plan-mode case.
Launch flags do not survive a resume either. Pass --add-dir, --mcp-config, --settings, --plugin-dir or --fallback-model again. Or move the setting into a settings file, which is re-read at every launch.
Inside a session, /clear starts an empty context for unrelated work. The old conversation stays on disk and resumable. /compact [instructions] replaces history with a summary, so the same task continues. /context shows what is eating the window. A cake shop developer who finishes the checkout and moves to the gallery page runs /clear. One still mid-checkout with a full window runs /compact. To try a riskier approach without losing the current one, /branch (or --fork-session on a resume) copies the conversation into a new session. The original stays intact and resumable.
Headless mode is claude -p (--print): prompt in, result out. It accepts piped stdin up to 10MB. It exits 0 on success and non-zero on failure, so scripts can branch. It starts in Manual on every plan, so scripted runs declare their own autonomy with --permission-mode and --allowedTools. The cake shop's nightly check is a claude -p run with its tools listed.
Output takes one of three formats:
--output-format text, the default.json: one payload carryingresult,session_id, cost and usage.stream-json: newline-delimited events, carrying asystem/initevent of session metadata and ending with aresultmessage.
Token deltas need stream-json plus --verbose and --include-partial-messages. Schema-conforming output needs --output-format json with --json-schema, read back from structured_output. In a stream-json run, subagent messages carry parent_tool_use_id, the ID of the tool call that started the subagent. A null value marks the main conversation. By default you get only a subagent's tool calls and results. --forward-subagent-text adds its text and thinking (September 2026).
# Structured result plus the session id, for a scripted follow-up
session_id=$(claude -p "Review the auth module for missing error handling" \
--permission-mode dontAsk --allowedTools "Read,Grep" \
--output-format json | jq -r '.session_id')
claude -p "Now list only the issues you rated high severity" --resume "$session_id"
# Token deltas as they are generated
claude -p "Explain the retry logic in worker.py" \
--output-format stream-json --verbose --include-partial-messagesDated current-state note (September 2026): --bare skips auto-discovery of hooks, skills, custom commands, subagents, installed plugins, MCP servers, auto memory and CLAUDE.md. The docs recommend it for scripted and SDK calls and expect it to become the default for -p. Anything a bare run needs has to arrive by flag, such as --agents or --mcp-config. A hook in a teammate's home directory cannot change your CI build if it was never read.
A -p run never shows the workspace trust dialog. In a folder nobody has trusted, it ignores the project's permissions.allow rules with a stderr warning. Without --bare, it still runs the hooks in the project's settings files and connects its .mcp.json servers. For a checkout you did not write, --bare or --setting-sources user keeps both out. The run's allowlist then belongs on the command line, with --allowedTools.
The Permission-Mode Axis
The permission mode is one setting with six exact values:
default, labelled Manual in the CLI withmanualas an alias, auto-approves reads only.acceptEditsadds file edits and the common filesystem commandsmkdir,touch,rm,rmdir,mv,cpandsedfor paths inside the working directory (September 2026).planreads and explores, while edits stay blocked until you approve the plan.autoputs a second model, the classifier, in the review seat instead of you.dontAskdenies anything that would have prompted, running only pre-approved tools and the read-only command set.bypassPermissionsruns everything without checks, for isolated containers and VMs only.--dangerously-skip-permissionsis its flag form.
Two rules outlive every mode. Deny rules block even under bypassPermissions, and allow rules have no effect there. Shift+Tab cycles modes mid-session. permissions.defaultMode sets where sessions start, with two exceptions in .claude/settings.json and .claude/settings.local.json (September 2026). An auto value there does not take effect, and Claude Code falls back to the built-in default. Nor does bypassPermissions, which starts the session in Manual.
From Claude Code v2.1.283 (September 2026), interactive terminal and VS Code sessions start in auto mode on every plan and provider. claude -p starts in Manual on every plan. A managed defaultMode only sets the starting point, and people can still switch to auto. To take auto out of reach altogether, an organisation sets disableAutoMode to "disable" in managed settings.
The Bash sandbox is a separate layer (September 2026). A mode decides whether Claude asks. The sandbox has the operating system limit which files and hosts a command and its child processes can reach. Switch it on with sandbox.enabled or /sandbox. When a tool needs one extra writable path, such as a build cache, sandbox.filesystem.allowWrite grants it inside the sandbox. The docs prefer that to exempting the tool through excludedCommands. If the order site's build writes a cache, the cake shop grants that one path. Setting sandbox.allowUnsandboxedCommands to false closes the escape hatch in which Claude retries a blocked command outside the sandbox. Every command Claude runs then stays sandboxed unless it is on the excluded list.
Raise autonomy in proportion to isolation and reversibility, never in proportion to impatience. The cake shop developer reading every checkout change in a diff uses acceptEdits. The nightly CI check uses dontAsk with an explicit allowlist. In general:
acceptEditsfor edits you will read in a diff.planbefore touching code you do not know.dontAskwith an explicit allowlist for CI.autofor an unattended run whose commands cannot be listed in advance.bypassPermissionsonly where the whole environment is disposable.
In the exam
Domain 3 is one sub-skill and the smallest slice of the exam. Nearly every item is a placement question: given a stated need, which file family, which scope, which mode. The distractors are real mechanisms parked in the wrong slot.
The guide names the components as Rules, Skills, Commands, Agents and Agent Memory. It names the features as session management, built-in and custom slash commands, headless mode, streaming mode and auto-mode. It adds the CLAUDE.md hierarchy, repository initialisation and settings.json configuration.
The skills collision order, enterprise over personal over project, is a favourite trap because settings run the other way. Items are built from the memory page's enforcement sentence quoted above. When a stem says must never, the keyed answer is configuration, not prose. What to track, pin and keep in parity is Domain 2 material. How Claude Code resolves these files is here.
The guide's auto-mode feature is the permission-mode axis, and the config values are exact. The guide's term predates the current values and is broader than the mode now literally named auto. Read it as naming the axis rather than that one value.
Exam Traps
Reading the CLAUDE.md hierarchy as a precedence chain, so a project file is assumed to override the user file the way a local settings file overrides a project one.
Discovered CLAUDE.md files are concatenated into context, broadest scope first, so both are present and the project text simply appears later. Settings are the surface with a real precedence chain: managed, command line arguments, local, project, user.
Assuming shared beats personal, or personal beats shared, without checking which mechanism is in play.
For a single-value setting, .claude/settings.local.json overrides the checked-in .claude/settings.json while ~/.claude/settings.json sits at the bottom, so local beats project beats user; list settings such as permissions.allow merge instead. For skills with a name collision it inverts: enterprise overrides personal, personal overrides project. Subagent names follow the settings direction, project over user.
Believing Claude Code needs an interactive terminal, or reaching for invented flags such as --headless, --stream or --auto.
The documented surfaces are claude -p / --print, --output-format text|json|stream-json with --verbose and --include-partial-messages for token deltas, and --permission-mode taking default/manual, acceptEdits, plan, auto, dontAsk or bypassPermissions. Near-miss flag names are the standing distractor here.
Treating /compact and /clear as interchangeable ways to free context, and assuming a cleared conversation is gone.
/compact replaces history with a summary so the same task continues; /clear starts an empty-context conversation for unrelated work, and the old one stays on disk, resumable through /resume. Sessions persist as JSONL transcripts either way.
Practice Scenario
A seismograph manufacturer pins the model for its sensor-firmware repository in the checked-in .claude/settings.json. One engineer's sessions in that repository keep starting on a different model, and that model is named in a .claude/settings.local.json on their machine. Why is the local file winning?
Build Exercise
One Repo, Every Surface
What you'll learn
- How to confirm which instruction files actually loaded into a session
- How the CLAUDE.md hierarchy concatenates while settings precedence overrides
- How a deny rule enforces what a CLAUDE.md sentence only requests
- How to drive the same task interactively and headless with claude -p
- In a scratch repository, run /init, read the CLAUDE.md it generates, then run /context and find the file under Memory files
Why: Repository initialisation and the /context check are the two mechanisms the guide names, and seeing the file listed proves loading rather than assuming it.
You should see: A generated CLAUDE.md with build and test commands, listed under Memory files in /context.
- Add one team convention to the project CLAUDE.md and one personal line to a gitignored CLAUDE.local.md, start a fresh session, and confirm both are present with the local content read after the project content
Why: Concatenation ordered broadest to most specific is the keyed behaviour, and it is easier to remember once you have watched two files coexist rather than one replace the other.
You should see: Both instructions in effect, with nothing overridden.
- Create the same invocable twice: a command file at .claude/commands/release-notes.md and a skill at .claude/skills/release-notes/SKILL.md with a description and $ARGUMENTS in the body, then run /release-notes
Why: The merge of custom commands into skills is current, dated material, and the collision rule is the part an item can key.
You should see: One /release-notes entry, running the skill rather than the command file.
- Add a checked-in .claude/settings.json with one permissions.deny rule for a command you never want run, verify it with /permissions, then ask for that command in a session and again after cycling permission modes with Shift+Tab
Why: Watching a deny rule hold across modes is what converts the enforcement sentence from something memorised into something observed.
You should see: The command refused every time, whichever mode the status bar reports.
- Run one small task headless with claude -p and --output-format json, extract .result and .session_id with jq, then send a follow-up with --resume, and finish by writing down which surface carried each behaviour and which scope choice would hide it from a teammate
Why: The scripted path plus the per-surface inventory is the placement skill the whole sub-skill tests.
You should see: A JSON payload, a captured session id, a follow-up that continues the same conversation, and a six-line inventory.
Sources
- How Claude remembers your project — Claude Docs, the CLAUDE.md scopes, concatenation and load order, @path imports and the four-hop cap, /init, user and project rules, claudeMdExcludes, AGENTS.md and the Project instructions setting, and auto memory
- Settings files and precedence — Claude Docs, the five settings scopes, the exact precedence chain, list settings merging across files and the auto-gitignored local file
- Configure permissions — Claude Docs, permission rule syntax for allow, ask and deny, and what workspace trust gates in interactive and -p sessions
- Choose a permission mode — Claude Docs, the six mode values, deny rules binding in every mode, the acceptEdits command set, and where a session starts
- Extend Claude with skills — Claude Docs, SKILL.md locations, the name-collision order, skillOverrides and the merge of custom commands into skills
- Commands — Claude Docs, built-in slash commands against bundled prompt-based skills
- Create custom subagents — Claude Docs, .claude/agents/ definitions, name precedence, model resolution, permissionMode, isolated context and result-only return
- Manage sessions — Claude Docs, JSONL transcripts, resume entry points, which resumes restore the permission mode, launch flags a resume drops, and /branch
- Run Claude Code programmatically — Claude Docs, claude -p, the output formats, streaming flags, subagent messages in the stream and bare mode
- CLI reference — Claude Docs, the --bare and --forward-subagent-text flags
- Connect Claude Code to tools via MCP — Claude Docs, project server approvals and workspace trust
- Manage Claude Code plugins for your organization — Claude Docs, extraKnownMarketplaces and enabledPlugins in a repository's settings
- Output styles — Claude Docs, custom styles and keep-coding-instructions
- Configure the sandboxed Bash tool — Claude Docs, allowWrite, excludedCommands and allowUnsandboxedCommands
- Customize your status line — Claude Docs, when the status line updates, refreshInterval and caching on session_id
- Claude Certified Developer Foundations Exam Guide — Domain 3, Claude Code Operation — Anthropic