CCAR-F · module 2 of 5 · 20% of the exam

Claude Code configuration and workflows

Weight: 20 percent of the exam. Tests whether you can configure Claude Code for a team the way an architect would: shared, version controlled, correctly scoped, and safe to run unattended.

What the exam expects

Every question sits inside one of the six published scenario contexts, and Domain 2 leans hardest on three: a team adopting Claude Code with slash commands, CLAUDE.md, and plan mode; developer productivity tooling built on the built-in tools and MCP servers; and Claude Code running headless inside CI/CD.

The exam is not testing whether you can recite a settings key. It tests whether you put configuration in the right layer, and whether you reach for the right primitive: an instruction file, a rule, a skill, a hook, a permission rule, or a permission mode. Most wrong answers are real features applied at the wrong layer.

Four ideas carry most of the weight:

  1. Instruction files are context, not enforcement.
  2. Scope determines who gets the configuration and who can override it.
  3. Load timing determines what a piece of configuration costs and when it applies.
  4. Unattended runs need a mode that denies rather than one that waits.

Instruction files: what loads, when, and who wins

CLAUDE.md files exist at four scopes. In load order from broadest to most specific: a managed policy file deployed by the organization, the user file at ~/.claude/CLAUDE.md, the project file at ./CLAUDE.md or ./.claude/CLAUDE.md, and the personal, gitignored ./CLAUDE.local.md.

The critical mechanic is that these files are concatenated, not overridden. Claude Code walks up the directory tree from the working directory, collecting every CLAUDE.md and CLAUDE.local.md, and orders content from the filesystem root down to the working directory, so instructions closer to where you launched are read last. If two files contradict each other, nothing resolves the conflict; Claude may pick either one.

Files above the working directory load in full at launch. Files in subdirectories below it load on demand, the first time Claude reads a file there. That lazy loading has an exam-relevant consequence: after compaction, the project root CLAUDE.md is re-read from disk and re-injected, but nested files and path-scoped rules are not. If a convention silently stops applying after a long session, a nested instruction file is the first suspect.

Diagram of the four CLAUDE.md scopes loading in order from managed policy to user to project to local, concatenated rather than overridden, with subdirectory files loading on demand and not re-injected after compaction.

For anything past roughly 200 lines, the answer is .claude/rules/. A rules file with paths frontmatter loads only when Claude works with matching files, which is the one mechanism that genuinely reduces context cost. The tempting wrong answer is @path imports: they help you organize, but imported content is expanded and loaded at launch alongside the importer, so total context is unchanged.

Two team-scale controls round this out. claudeMdExcludes takes glob patterns matched against absolute paths at any settings layer, which is how a developer in a monorepo skips other teams' ancestor files. And a managed policy CLAUDE.md, deployed to the platform's managed location or embedded in managed settings under the claudeMd key, cannot be excluded by any individual setting. That exemption is the whole reason the managed scope exists.

Skills versus instruction files versus subagents

The dividing line the exam cares about is when the content loads.

Put it inWhen
CLAUDE.mdA short fact needed in every session: build commands, conventions that differ from tool defaults
.claude/rules/ with pathsA convention that applies only to some file types or directories
A skillA procedure, checklist, or bulky reference that matters occasionally and can carry templates and scripts alongside it
A subagent, or a skill with context: forkWork whose intermediate context (large file sweeps, long tool loops) should not land in the main conversation
A hookAnything that must happen regardless of what Claude decides

A skill is a directory containing SKILL.md plus optional supporting files. Only its description sits in context by default; the body loads on invocation. That is why a vague description is the number one reason a skill never fires: Claude matches on the description, so it must say what the skill does and when to use it, key use case first.

Frontmatter fields worth knowing cold:

  • disable-model-invocation: true keeps the description out of context and lets only a human invoke it. This is the right setting for anything with side effects: deploy, commit, send a message.
  • user-invocable: false is the mirror image: background knowledge Claude should apply, hidden from the slash menu.
  • allowed-tools pre-approves tools for the turn that invokes the skill only. The skill's rendered content persists in the conversation for the rest of the session, but the permission grant clears on your next message. Session-wide pre-approval belongs in permissions.allow.
  • context: fork runs the skill as a subagent with no access to the conversation history, so only the result returns.
  • paths limits automatic activation to matching files.

Arguments substitute as $ARGUMENTS, and positionally as $ARGUMENTS[0] or the shorthand $0, $1, $2.

Skill precedence runs the opposite way to instruction files: on a name collision, enterprise beats personal beats project. A personal code-review skill shadows the project's. That inversion is a favorite exam target. Nested skills in a monorepo do not collide; they become available under a directory-qualified name such as apps/web:deploy, and invoking the unqualified name loads the root skill plus a note listing the variants.

Hooks: the only enforcement layer

Everything above shapes behavior. Only hooks enforce it. A hook is a shell command, HTTP call, MCP tool call, prompt, or subagent bound to a lifecycle event, and it runs regardless of what Claude decides.

The events carrying the most exam weight are PreToolUse (fires before a tool call and can block it), PostToolUse (fires after a call succeeds, the home of auto-formatting and linting), UserPromptSubmit, SessionStart, Stop, and SubagentStop. Matchers filter on tool name for tool events, using exact strings (Bash, Edit|Write) or a regular expression.

Two control paths matter. Exit code 2 blocks the action and feeds stderr back to Claude as an error. Exit 0 with JSON on stdout gives finer control: a PreToolUse hook can return permissionDecision of allow, deny, ask, or defer, plus a permissionDecisionReason that Claude sees. That reason field is the difference between a hook and a static deny rule: reach for a hook when the decision depends on logic a path pattern cannot express and you want Claude to understand why and change approach.

Permissions, modes, and settings precedence

Permission rules come in three lists: allow, ask, and deny. Syntax is Tool or Tool(specifier), for example Bash(npm run build), Read(./.env), WebFetch(domain:example.com). Deny rules are absolute: they apply in every mode, including bypassPermissions, and cannot be overridden by an allow rule at a lower settings layer. That is why a secret file is protected with Read(./.env) in deny and never with an instruction in CLAUDE.md.

Bash rules have sharp edges the exam likes. Compound commands are split on &&, ||, ;, |, and newlines, and a rule must match each subcommand independently, so an allow rule cannot be smuggled past by chaining. A fixed set of wrappers (timeout, time, nice, nohup, stdbuf, and a few shell builtins) is stripped before matching, but environment runners such as devbox run, mise exec, npx, and docker exec are deliberately not in that list, so Bash(devbox run *) authorizes whatever follows run. Write one rule per inner command. A trailing * with a space enforces a word boundary, so Bash(ls *) matches ls -la but not lsof.

Permission modes set the baseline:

ModeRuns without askingUse for
default (labeled Manual)Reads onlySensitive work, getting started
acceptEditsReads, file edits, common filesystem commandsIterating on code you will review as a diff
planReads and exploration, no source editsUnderstanding before changing
autoEverything, with background safety checksLong tasks, fewer interruptions
dontAskOnly pre-approved tools; everything else is deniedLocked-down CI and scripts
bypassPermissionsEverythingIsolated containers and VMs only

For an unattended job, dontAsk is almost always the answer, because it denies instead of waiting. A CI run in default or acceptEdits mode hangs on the first unapproved command and dies at the job timeout.

Settings live in managed policy, ~/.claude/settings.json, the committed .claude/settings.json, and the gitignored .claude/settings.local.json. Team rollout means committing the shared layer (settings, skills, hooks) so every clone gets the same baseline, and leaving the local file for individual deviation. Protected paths such as .git, .claude, and .vscode are never auto-approved except in bypassPermissions, and permissions.allow entries do not pre-approve them.

One more scoping rule: --add-dir grants file access, not configuration discovery. Skills and subagents load from an added directory; instruction files require CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD; commands are not loaded at all. The permissions.additionalDirectories setting is weaker still and grants file access only.

Plan mode and headless CI/CD

Plan mode lets Claude read and explore without editing source, then presents a plan you approve. Its value is a cheap review point before any edit exists, which pays off when the change spans unfamiliar code and a wrong approach is expensive to unwind. It does not enforce that later edits match the plan text. Make it the default for a sensitive repository with permissions.defaultMode: "plan" in the committed project settings.

Headless runs use claude -p. --output-format json puts the text in result; adding --json-schema puts the schema-conformant value in structured_output, removing prose parsing from the pipeline. --bare skips auto-discovery of hooks, skills, plugins, MCP servers, auto memory, and CLAUDE.md, which is what makes a run reproducible across machines, at the cost that it does not read stored credentials or CLAUDE_CODE_OAUTH_TOKEN and needs ANTHROPIC_API_KEY.

For GitHub, anthropics/claude-code-action@v1 infers its mode from configuration: supply a prompt input and it runs in automation mode with output in the workflow run log; omit it and it waits for the @claude trigger phrase and replies as a comment. Three gotchas: passing the default GITHUB_TOKEN means GitHub will not trigger further workflows on Claude's commits; public repositories withhold secrets from fork pull request runs; and a plain text prompt has no tools until you grant them with --allowedTools in claude_args or an allow rule in the settings input.

How to think through the question

Domain 2 scenarios almost always describe a symptom, then ask what to do, what is wrong, or what the root cause is. Work the problem in this order.

Step 1: identify which primitive the symptom belongs to. Scan for the signal words. "Sometimes ignores," "usually follows," and "one in ten" mean an instruction file is being used where a hook is needed. "Consumes context" or "adherence dropped as the file grew" points at load timing and path-scoped rules. "Developers each configured" means a scope problem. "Hangs," "timed out," "unattended," and "runner" mean permission mode. "Cannot be turned off by the developer" means managed policy.

Step 2: decide what the question is actually asking. A first-step question rewards the cheapest reversible move. A root-cause question rewards the mechanic, not the remedy. A "which change most improves" question is comparative: two options may both help, and you want the one that addresses the cause rather than the symptom.

Step 3: eliminate options that ignore a stated constraint. If the scenario says other teams own those files, deleting them is out. If it says the team wants a guarantee, any instruction file answer is out. If it says every developer on clone, a user-scope or manual answer is out.

Step 4: eliminate over-engineering. A subagent for a checklist, a classifier for a two-branch decision, a wrapper service around a permission problem. The exam consistently prefers the primitive built for the job.

Step 5: check for the inverted-intuition trap. Skills resolve enterprise over personal over project. Instruction files concatenate broad to specific. Imports do not save context. Deny beats allow across layers. These four reversals account for a large share of the hard questions.

Worked example. A team wrote "always run the linter before creating a commit" in CLAUDE.md. It works most of the time, but roughly one commit in ten skips it, and the team treats this as a compliance requirement.

Step 1: "most of the time" plus "compliance requirement" is the enforcement signal. Step 2: this is a what-should-they-do question, so we want the mechanism, not a patch. Step 3: the stated constraint is compliance, which eliminates every answer that leaves the behavior probabilistic, including repeating the instruction in three files and moving it to a managed CLAUDE.md (managed scope changes who gets it, not whether it is enforced). Step 4: making it a manual-only skill is not over-engineering so much as backwards, since it would run less often. Step 5: the reversal here is that managed policy sounds like enforcement and is not. The answer is a hook, because hooks execute at fixed lifecycle events regardless of what Claude decides.

Exam traps

  • Managed CLAUDE.md as enforcement. It cannot be excluded, which is a scope guarantee. It is still context, not a hard control. Enforcement is hooks and permission rules.
  • @path imports to save context. They organize; they do not reduce tokens. Path-scoped rules do.
  • Applying instruction-file intuition to skills. Skills resolve enterprise over personal over project, so your personal skill shadows the team's.
  • Assuming allowed-tools lasts the session. The skill content persists; the grant expires on your next message.
  • acceptEdits for CI. It auto-approves edits and common filesystem commands only, so the job still hangs on the first other shell command. dontAsk denies instead of waiting.
  • bypassPermissions because the job is automated. It removes safety checks on a machine holding repository credentials. Least privilege means an explicit allowlist plus a denying mode.
  • A prefix allow rule on an environment runner. Bash(devbox run *) authorizes anything after run, because runners are not in the stripped wrapper list.
  • --add-dir as a way to import another repository's configuration. It grants file access; skills load, instruction files need an environment variable, commands do not load at all.
  • Forgetting that --bare drops credentials too. Reproducibility comes with an API key requirement.
  • Blaming a permission or model problem for a post-compaction behavior change. Nested instruction files and path-scoped rules are not re-injected after compaction.

Quick reference

Symptom or requirementAnswer
Must happen every time, no exceptionsHook
Must never be readable or runnabledeny rule (applies in every mode)
Org-wide, developer cannot excludeManaged policy CLAUDE.md or claudeMd in managed settings
Long file, poor adherence.claude/rules/ with paths frontmatter
Repeated multi-step procedureSkill
Side-effecting skill Claude keeps auto-runningdisable-model-invocation: true
Background knowledge, no slash commanduser-invocable: false
Skill eats the main contextcontext: fork
Same baseline for every developerCommit .claude/settings.json and .claude/skills/
Personal deviation.claude/settings.local.json, CLAUDE.local.md
Personal notes across worktreesImport a home directory file from CLAUDE.md
Unattended run must not hang--permission-mode dontAsk plus explicit allow rules
Same result on every machine--bare plus explicit flags and ANTHROPIC_API_KEY
Pipeline needs a parseable value--output-format json --json-schema, read structured_output
Review before editing, repo-widepermissions.defaultMode: "plan" in committed settings

Ready to test this domain?

Drill mode gives instant feedback: pick a wrong answer and you immediately see why it is wrong.

Start the drill

Not an official source. This is a free, independent study resource from siasola, built by an engineer who sat these exams and wanted better prep material to exist. It is not affiliated with, endorsed by, or sponsored by Anthropic. Claude is a trademark of Anthropic, PBC. Exam facts follow the official exam guides; registration for the real exams happens through the Anthropic Partner Academy and Pearson VUE, not here.