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 is stored and who it applies to. A file can be managed by an organisation, user-wide in your home directory, project-wide and checked in, or local and personal. Settings are JSON files that hold 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.
This lesson uses one made-up example throughout: a payroll software company that keeps its payroll product in one repository. A team of developers works on it, and a nightly script checks the tax calculations. For this company, every configuration choice answers the same three questions: 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 are in .claude/rules/, and user rules are in ~/.claude/rules/. Frontmatter is the block of settings at the top of a markdown file. 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 payroll company could scope a currency-formatting rule to its tax calculation files this way. User rules load before project rules, so a project rule appears 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 holds the other kind of rule.
Skills are procedures packaged as a directory that holds a SKILL.md. Personal skills are in ~/.claude/skills/<name>/, and project skills are in .claude/skills/<name>/. Managed settings and plugins can supply them too. Claude invokes a skill when its description matches the task, or when you type /skill-name. The body loads only when the skill is used. When two skills share a name, enterprise takes priority over personal, and personal takes priority over project. That order is the opposite of settings precedence. If a developer at the payroll company 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 the skill to Claude without its description. off hides the skill everywhere. The /skills menu saves the choice to .claude/settings.local.json, a personal file, so the choice does not affect teammates.
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 given 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. If a command and a skill have the same name, the skill takes priority. If the payroll company has both files for /deploy, the skill runs. Both take arguments through $ARGUMENTS. $0 and $1 select individual argument positions, counting from zero, so $0 is the first argument.
Agents are subagents. Project subagents are defined in .claude/agents/, and user subagents are defined 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.
When subagent names clash, the order runs the same way as settings precedence, not the way skill name clashes run (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 takes priority over a project subagent of the same name. A model in the definition takes priority over CLAUDE_CODE_SUBAGENT_MODEL. So does a model that Claude passes at spawn time. If you set CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1 as well, 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 main session's mode instead. Say the payroll company has a reviewer subagent that must never edit the payroll code. Its permissionMode setting has no effect once the main session runs in acceptEdits. So remove the editing tools from 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. The load is capped at the first 200 lines or 25KB of the index. Topic files load on demand. Auto memory is per repository. It is shared across worktrees, which are extra checkouts of one git repository. It is machine-local, and it is on by default. What Claude learns about the payroll product on one developer's laptop stays on that laptop. To disable auto memory for one repository, set autoMemoryEnabled: false in that project's settings. The /memory toggle writes to your user settings and disables auto memory 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 (September 2026). A plugin usually comes from a marketplace. To share a plugin across repositories, a team sets two keys in each repository's .claude/settings.json. The team registers its private marketplace under extraKnownMarketplaces and enables the plugin under enabledPlugins. To cover a whole organisation instead, the same two keys are set in managed settings. The marketplace entry applies only in a folder the contributor has trusted. Setting enabledPlugins in the repository does not install the plugin. Each contributor still runs claude plugin install <name>@<marketplace> --scope project once. A plugin that a local directory or file marketplace lists by a relative path needs no install.
An output style sets Claude's role, tone and format for a whole session (September 2026). Styles are stored in .claude/output-styles/ or ~/.claude/output-styles/, and outputStyle chooses one. On Claude Code's full system prompt, a custom style removes 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 includes that section, so with the shorter system prompt 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 (Windows Subsystem for Linux),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 appears after a broader one instead of replacing it. Claude Code searches upward through the directory tree from the working directory. When Claude Code starts in foo/bar/, it puts foo/CLAUDE.md before foo/bar/CLAUDE.md. It puts each CLAUDE.local.md after the CLAUDE.md in the same directory. Files in subdirectories below the working directory load on demand. The payroll company's project CLAUDE.md says how to run the payroll tests. A developer's CLAUDE.local.md adds personal notes. Claude gets both files, and the personal notes come second.
You can put @path/to/import anywhere in a CLAUDE.md to import more content. The import path resolves against the importing file. The import expands at launch, and imports can recurse to a maximum depth of four hops. Repository initialisation is /init. It analyses the codebase and writes a starting CLAUDE.md that contains build commands, test instructions and conventions. If a CLAUDE.md exists, /init suggests improvements rather than overwriting the file. /context shows what loaded, under Memory files. /memory opens any of those files 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, a path pattern with wildcards such as *. It works from any settings file, but managed policy files cannot be excluded. A monorepo is one repository that holds the code of many teams. A developer in a monorepo can exclude another team's file from their own sessions. To do this, the developer sets claudeMdExcludes 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 if you add a personal CLAUDE.local.md, Claude Code stops reading AGENTS.md. 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 work the other way. They form a real precedence chain. From highest to lowest, the chain is 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, and it is checked in. The local file is personal and takes priority over the shared file. It is auto-gitignored: Claude Code adds **/.claude/settings.local.json to your global git excludes file.
That chain decides 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 restore the approval prompt for a command that 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 payroll company'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 be enforced whatever the model decides belongs in a deny rule or a hook. The payroll company's naming conventions go in CLAUDE.md. A ban on reading its bank credentials file goes in a deny rule.
A CLAUDE.md sentence does not enforce anything
"Never touch the production config" written into CLAUDE.md is a request. The client enforces the same prohibition when it is a permissions deny rule. 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 developer who clones the payroll product 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 the status line can stop updating while the main session is 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 the script would never find a cache stored under a process ID.
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 to resume a session.
claude --continue(-c) opens the most recent session in the current directory.claude --resumewith no argument opens the picker, a list of saved sessions to choose from.claude --resume <name-or-id>opens one session directly./resumeworks from inside a running session.
As of September 2026, sessions that claude -p or the Agent SDK creates do not appear in the picker. A plain claude --continue also does not open them. You can still resume them by ID, and claude -p --continue includes them. So the payroll company's nightly runs will not appear in a developer's picker.
A resumed session brings back the conversation and the model it was using. The permission mode has stricter rules (September 2026). It returns only on a terminal resume by --continue, by ID or by a unique name, without -p. Even then, the mode does not return in a few narrower cases. bypassPermissions and plan are two of them. In those cases, the session uses the mode that a new session would start in. The picker and /resume never restore the mode. claude -p --resume or -p --continue starts in the same mode as a new -p run, except in one narrow plan-mode case.
A resumed session does not keep launch flags either. Pass --add-dir, --mcp-config, --settings, --plugin-dir or --fallback-model again. Or move the setting into a settings file, because Claude Code re-reads settings files at every launch.
Inside a session, /clear starts an empty context for unrelated work. The old conversation stays on disk, and you can resume it. /compact [instructions] replaces history with a summary, so the same task continues. /context shows what uses the context window. A payroll developer who finishes the tax calculation and moves to the reports page runs /clear. A developer who is still in the middle of the tax calculation and has a full context window runs /compact. To try a riskier approach without losing the current one, use /branch, or --fork-session on a resume. Either one copies the conversation into a new session. The original session stays intact, and you can resume it.
Headless mode is claude -p (--print): you give it a prompt, and it returns a result. It accepts piped stdin up to 10MB. It exits 0 on success and non-zero on failure, so scripts can branch. It starts in the Manual permission mode on every plan, so scripted runs set which actions they may take without asking, with --permission-mode and --allowedTools. The payroll company's nightly check is a claude -p run that lists its tools.
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. The stream includes asystem/initevent with session metadata and ends with aresultmessage.
Token deltas (each new piece of output as it is generated) need stream-json plus --verbose and --include-partial-messages. Output that conforms to a schema needs --output-format json with --json-schema. You read that output from structured_output. In a stream-json run, subagent messages include 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 that a bare run needs has to come through a flag, such as --agents or --mcp-config. A hook in a teammate's home directory cannot change your CI build if the hook 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 stops both the hooks and the servers. 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:
defaultis labelled Manual in the CLI and hasmanualas an alias. It 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.- In
auto, a second model, the classifier, does the review instead of you. dontAskdenies anything that would have prompted. It runs 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 hold in every mode. Deny rules block even under bypassPermissions, and allow rules have no effect there. Shift+Tab cycles through the modes during a session. permissions.defaultMode sets the mode that sessions start in, 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 uses the built-in default instead. 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 make auto unavailable 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. Enable it 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 payroll product's build writes a cache, the company grants that one path. Setting sandbox.allowUnsandboxedCommands to false stops Claude from retrying a blocked command outside the sandbox. Every command Claude runs then stays sandboxed unless it is on the excluded list.
Give Claude more freedom to act without asking when the work is more isolated and easier to reverse, never because you are impatient. The payroll developer reading every tax calculation 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 you edit code that 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 part of the exam. Nearly every question is a placement question: given a stated need, which kind of file, which scope, which mode. The wrong options are real mechanisms used in the wrong place.
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 order for skill name clashes is enterprise, then personal, then project. This order is a common trap because settings precedence works the other way. Questions are based on the sentence from the memory page about enforcement, quoted above. When a question says must never, the right answer is configuration, not prose. What to track, pin and keep in parity is Domain 2 material. How Claude Code resolves these files is covered 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 whole setting rather than that one value.
Exam Traps
Assuming a project CLAUDE.md overrides the user CLAUDE.md, as local settings override project settings
Discovered CLAUDE.md files are concatenated into context, broadest scope first. So both are present, and the nearer file is read last. Settings are the configuration source with a real precedence chain: managed, command line arguments, local, project, user.
Assuming a project skill takes priority over a same-named personal skill, the way project settings override user settings
Settings run local over project over user. Skill name collisions invert that: enterprise overrides personal, personal overrides project. Subagent name clashes follow the settings direction, so a personal copy never takes priority over a project subagent.
Believing Claude Code needs an interactive terminal, or using invented flags such as --headless, --stream or --auto
Headless mode is claude -p (--print). Token deltas need --output-format stream-json with --verbose and --include-partial-messages. The actions Claude may take without asking are set with --permission-mode, and auto is one of its values. Flag names that are close to the real ones do not exist.
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. The old conversation stays on disk, and you can resume it through /resume. Sessions persist as JSONL transcripts either way.
Practice Scenario
An invoicing software company pins the model for its invoicing product 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 does the local file take priority?
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 run the same task interactively and headless with claude -p
- In a test 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 behaviour the exam tests, 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 slash command 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 a question can test.
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: When you watch a deny rule apply across modes, the enforcement sentence changes from something you memorised into something you 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