CCAR-F Study Guide

Domain 3 — Claude Code Configuration & Workflows (20%)

The recurring question in this domain is where does this belong — which file, which scope, which layer. Get the precedence tables into memory and most of these questions answer themselves.

3.1 CLAUDE.md and the memory hierarchy

ScopeLocationFor
Managed policy/Library/Application Support/ClaudeCode/CLAUDE.md (macOS), /etc/claude-code/CLAUDE.md (Linux/WSL), C:\Program Files\ClaudeCode\CLAUDE.mdOrg-wide standards. Cannot be excluded by individual settings
User~/.claude/CLAUDE.mdYour preferences, every project
Project./CLAUDE.md or ./.claude/CLAUDE.mdTeam standards, committed to source control
Local./CLAUDE.local.mdYour personal project notes; gitignore it

How loading actually works — this is exam material, not trivia:

  • Files from the working directory and every directory above it load at launch. They are concatenated, not overridden, ordered filesystem-root-down, so the file closest to where you launched is read last.
  • Within a directory, CLAUDE.local.md is appended after CLAUDE.md.
  • Files in subdirectories do not load at launch. They load on demand, when Claude reads a file in that subdirectory. This is the monorepo answer: a root CLAUDE.md for shared conventions plus per-package files for stack-specific rules, each loading only when relevant.
  • Imports use @path/to/file, resolve relative to the importing file, recurse to a maximum depth of four hops, and are skipped inside backticks or code fences. Imported content still loads at launch, so imports organise but do not save context.
  • Target under 200 lines per file. Adherence degrades as files grow.
  • claudeMdExcludes (glob patterns against absolute paths) skips other teams' ancestor files in a monorepo. Managed policy files are exempt.

The distinction the exam turns on — CLAUDE.md is context, not configuration. It is delivered as a user message after the system prompt; Claude reads it and tries to follow it. If the requirement is "must always" or "must never" — a compliance rule, a forbidden path, a mandatory pre-commit step — the answer is a hook or managed settings, never a line in CLAUDE.md.

Rules in .claude/rules/*.md break large instruction sets into topic files. With paths: frontmatter they become path-scoped and load only when Claude touches a matching file:

---
paths:
  - "src/api/**/*.ts"
---
# API rules
- Every endpoint validates input before use.
- Use the standard error envelope.

Rules without paths load unconditionally at the same priority as .claude/CLAUDE.md. User rules (~/.claude/rules/) load before project rules, so project rules win.

3.2 Settings precedence

Highest wins. Memorise the order:

  1. Managed settings — managed-settings.json / MDM / console (your organisation)
  2. Command line — claude --settings …
  3. Project local — .claude/settings.local.json
  4. Shared project — .claude/settings.json
  5. User — ~/.claude/settings.json

List keys such as permissions.allow merge across scopes rather than replacing one another. deny and ask rules apply immediately; allow rules and additionalDirectories wait until the folder is trusted.

3.3 Permission modes

ModeBehaviourUse for
default (Manual)Prompts on first use of each toolInteractive work
planReads files and runs read-only commands to explore; will not edit sourceBefore any large refactor — investigate, produce a plan, then execute
acceptEditsAuto-accepts file edits and common filesystem commands (mkdir, touch, mv, cp) inside the working directoryAutomation and CI where edits are the expected output
autoAuto-approves with a background classifier checking actions against your requestUnattended runs where you still want a safety review
dontAskDenies anything not pre-approved by permissions.allowLocked-down CI
bypassPermissionsSkips prompts almost entirelyIsolated containers/VMs only

Set the starting mode with permissions.defaultMode or --permission-mode. Organisations can block the dangerous ones with permissions.disableBypassPermissionsMode and permissions.disableAutoMode.

Permission rule syntax

RuleMatchesDoes not match
Bash(npm run build)exactly that commandnpm run build --watch
Bash(npm run *)npm run test --watchnpm install
Bash(ls *)ls, ls -lalsof — note the space before *
Bash(ls*)ls -la and lsof—
Read(./.env)that file—
WebFetch(domain:example.com)fetches to that hostother hosts
mcp__server__toolone MCP tool—

Evaluation: deny beats ask beats allow. Deny rules cannot be overridden by a lower-precedence allow.

3.4 Hooks — the enforcement layer

Hooks run your code at fixed lifecycle events regardless of what Claude decides. When a question says "guarantee", "always", "block", or "must not", look for the hook.

EventFiresTypical use
SessionStartSession begins or resumesInject environment state
UserPromptSubmitBefore the prompt is processedValidate or block prompts, add context
PreToolUseBefore a tool runs — can blockEnforce prerequisites, forbid destructive commands
PostToolUse / PostToolUseFailureAfter success / after failureAuto-format, run tests, log, react to errors
PermissionRequest / PermissionDeniedA tool needs a decision / auto mode denied oneCustom approval policy
Stop / SubagentStopClaude finishes responding / a subagent endsVerification gates — continue: false keeps it working
PreCompact / PostCompactAround compactionPersist state before it is summarised away
SessionEndSession terminatesCleanup, audit
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{ "type": "command", "command": "$CLAUDE_PROJECT_DIR/.claude/guard.sh", "timeout": 30 }]
    }]
  }
}

Exit codes: 0 = success, JSON on stdout is parsed for a decision; 2 = block the action, stderr becomes the reason Claude sees; anything else = non-blocking error, the action proceeds. A JSON decision looks like:

{ "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "deny",
    "permissionDecisionReason": "Refund tool blocked: verification not recorded for this session."
} }

Handler types go beyond shell: command, http, mcp_tool, prompt, and agent. Matchers accept exact names, Edit|Write alternation, and regex such as mcp__.*.

3.5 Slash commands and skills

Custom commands live in .claude/commands/ (project, committed) or ~/.claude/commands/ (personal); subdirectories namespace them. Skills live in .claude/skills/<name>/SKILL.md and carry frontmatter that controls invocation:

FrontmatterEffect
descriptionWhat Claude matches on to invoke it automatically
allowed-toolsPre-approves tools for the turn, e.g. Bash(git add *) Read
disable-model-invocation: trueOnly a human can run it — the answer for deploys and other destructive commands
user-invocable: falseOnly Claude can run it; hidden from the / menu
context: forkRuns in an isolated subagent

Arguments arrive as $ARGUMENTS or positionally as $1, $2. Dynamic context is injected by executing a command with !`git diff HEAD`, and files are referenced with @path. Built-ins worth knowing: /init, /memory, /context, /compact, /clear, /permissions, /mcp, /agents, /plan, /review, /rewind, /resume, /doctor, /add-dir.

3.6 Headless mode and CI/CD

claude -p "Review this diff for security issues" \
  --output-format json \
  --permission-mode acceptEdits \
  --allowedTools "Read,Grep,Bash(npm test *)" \
  --append-system-prompt "You are a security reviewer. Report only exploitable findings." \
  --bare
FlagWhat it does
-p / --printNon-interactive run; reads stdin, prints the result
--output-formattext · json (result + session ID + usage + total_cost_usd) · stream-json (NDJSON events)
--json-schemaWith json, constrains the result into structured_output
--bareSkips auto-discovery of hooks, skills, commands, agents, plugins, MCP servers, auto memory and CLAUDE.md — the recommended mode for CI, because the run is identical on every machine
--permission-prompts noneNothing waits on a human; anything that would prompt is denied and Claude is told not to retry
--continue / --resume <id>Continue the last session / a specific one, from any directory

Exit code 0 on success, non-zero on failure; SIGTERM exits 143 and leaves the turn resumable. Without --bare, a -p session runs the repository's hooks and connects its .mcp.json servers in a folder you have never trusted — a supply-chain consideration the exam has been known to probe.

The CI false-positive scenario — When an automated reviewer floods PRs with noise, the correct fix is project-specific exceptions plus few-shot examples of good findings — narrow the rule, show the standard. Removing the security check entirely, or raising a generic "be less strict" instruction, is the wrong answer every time.

← Previous: Domain 2 — Tool Design & MCP Integration  |  Next: Domain 4 — Prompt Engineering & Structured Output →

Architect CCAR-F Real Exam Questions

Ready to Pass Your CCAR-F Certification?

Practice with authentic exam questions, verified explanations, and timed test simulation to guarantee your success.

Starting from $49.00
Take Practice Exam →