Questions? Call 1.800.716.8955

Chapter 4

Claude Code (3.1%)

What the exam tests: how Claude Code is configured and operated: its components, the CLAUDE.md hierarchy, settings.json, sessions, slash commands, and headless and automated use. Expect one or two items, but Claude Code concepts also appear in Domains 2, 7, and 8.

Core components

  • Component What it is Where it lives
  • CLAUDE.md
  • (memory)

Instructions and project facts loaded into every session Project root, subfolders, ~/.claude/CLAUDE.md

Rules Modular instruction files, optionally scoped to file paths .claude/rules/ Skills Folders with a SKILL.md (name, description, instructions) plus optional scripts and references; loaded only when relevant

.claude/skills/<name>/ or

~/.claude/skills/

Commands Reusable prompts invoked as /name .claude/commands/ (Skills can also be invoked by slash name)

Agents (sub‐

agents)

Specialized helpers with their own system prompt, tools, and model, run in a separate context

  • .claude/agents/*.md
  • Agent
  • memory

Persistent notes an agent or subagent keeps across sessions Memory directory configured per agent

Hooks Shell commands run at lifecycle events (PreToolUse, PostToolUse, Stop, and others)

settings.json

MCP servers External tools and data sources .mcp.json or settings Plugins Installable bundles of the above Installed from a marketplace Skills use progressive disclosure: only the name and description sit in context until Claude decides the skill is relevant, then the full instructions load. That keeps many skills available without bloating context.

The CLAUDE.md hierarchy

Claude Code reads memory files from several levels and combines them. More specific files add to or refine broader ones.

Figure 4. Claude Code combines CLAUDE.md files from broad to specific

Organization (managed policy): set by IT for every user on a machine.

User: ~/.claude/CLAUDE.md, your personal preferences across all projects.

Project: ./CLAUDE.md (or .claude/CLAUDE.md), checked into git and shared with the team. Subdirectory: CLAUDE.md files in subfolders, loaded when Claude works in that part of the tree.

Files can import others with @path/to/file. Run /init in a new repository to generate a starter CLAUDE.md from the codebase. Keep CLAUDE.md short and factual: build and test commands, conventions, architecture notes, and "gotchas." Long, stale CLAUDE.md files waste context on every turn.

settings.json

Settings control permissions, hooks, environment variables, the default model, and MCP servers. Scope File Shared?

Managed (enterprise) System-level managed settings Enforced, cannot be overridden Project .claude/settings.json Yes, committed to git

Local project .claude/settings.local.json No, git-ignored personal overrides User ~/.claude/settings.json No, applies to all your projects

Precedence runs from most to least authoritative: managed, then command-line arguments, then local project, then project, then user. Permission rules use allow, ask, and deny lists such as "Bash(npm run test:*)" or "Read(./.env)". A deny rule wins over an allow.

Features you should recognize

Session management. claude --continue resumes the most recent session; claude -- resume picks one. /clear starts fresh context; /compact summarizes history to free space.

  • 1. Organization managed policy set by IT for every user on a machine
  • 2. User ~/.claude/CLAUDE.md: your preferences across all projects
  • 3. Project ./CLAUDE.md: checked into git, shared with the team
  • 4. Subdirectory CLAUDE.md in a subfolder: loaded when Claude works there

More specific

Built-in slash commands. Examples include /init, /clear, /compact, /model, / permissions, /hooks, /mcp, /agents, /memory, and /context.

Custom slash commands. Markdown prompts in .claude/commands/ or Skills, which can accept arguments.

Headless mode. claude -p "prompt" runs non-interactively for scripts and CI, with -- output-format text, json, or stream-json.

Streaming mode. stream-json output emits events as they happen, so another program can follow progress live.

Permission modes. Default (ask before risky actions), accept-edits, plan mode (read-only planning), and auto mode (a classifier approves routine actions and blocks risky ones). A fully bypassed mode exists for isolated sandboxes only.

Codebase modernization. The guide stresses using Claude Code to plan and execute large refactors: ask for a plan first, work in small steps, and run tests after each.

Worked example 4.1: a good project CLAUDE.md

A strong CLAUDE.md is short, specific, and things Claude cannot infer from the code. Here is one for a TypeScript API service:

# Orders API

## Commands

- Install: `pnpm install`

- Test: `pnpm test` (unit), `pnpm test:int` (needs Docker running)

- Lint and typecheck: `pnpm check` (run before every commit)

## Conventions

- Handlers live in src/routes/, one file per resource.

- All money values are integer cents. Never use floats for currency.

- Database access only through src/db/repo.ts; no raw SQL in handlers.

## Gotchas

- The `legacy/` folder is frozen. Do not modify it.

- Integration tests share a database; run them serially.

@docs/architecture.md

Why it works: commands are copy-paste ready, conventions explain the non-obvious, and the long architecture document is imported rather than pasted. Compare with a weak CLAUDE.md that says "write clean code" and "follow best practices," which costs context on every turn and changes nothing.

Worked example 4.2: settings.json with permissions and a hook

A shared project .claude/settings.json that allows routine commands, protects secrets, and runs the linter after each edit:

  • CLAUDE CODE (3.1%)
  • {
  • "permissions": {

"allow": ["Bash(pnpm test:*)", "Bash(pnpm check)", "Read(./src/**)"], "ask": ["Bash(git push:*)"],

"deny": ["Read(./.env)", "Read(./secrets/**)", "Bash(rm -rf:*)"] },

  • "hooks": {
  • "PostToolUse": [
  • {
  • "matcher": "Edit|Write",

"hooks": [{ "type": "command", "command": "./scripts/lint-edited-file.sh" }] }

  • ]
  • }
  • }
  • Exam reading points:

deny beats allow. Even if another rule allowed reading files broadly, .env stays blocked. ask keeps a human in the loop for pushes.

The hook runs every time Claude edits or writes a file, regardless of what the prompt says. (The hook receives a JSON description of the tool call on standard input, including the edited file path; the script reads it and lints that file. See the Claude Code hooks reference for the exact payload.)

A PreToolUse hook command can block an action by exiting with a blocking status and printing a reason that Claude sees.

Personal tweaks (a different model, extra allowed commands) go in .claude/ settings.local.json, which is git-ignored.

Worked example 4.3: writing a Skill

A team wants every release note written the same way. Instead of pasting the format into CLAUDE.md, they create .claude/skills/release-notes/SKILL.md:

---

name: release-notes

description: Write customer-facing release notes from merged pull requests. Use when asked for release notes, a changelog entry, or a "what's new" summary.

---

# Release notes

  • 1. Run `scripts/merged_prs.sh <from-tag> <to-tag>` to list merged PRs.
  • 2. Group changes under: New, Improved, Fixed. Skip internal refactors.
  • 3. One line per change, written for customers, starting with a verb.
  • 4. Link each line to its PR.
  • 5. Follow the tone guide in reference/tone.md.

How progressive disclosure plays out: at session start only the name and description are in context (a few dozen tokens). When a user asks for release notes, Claude reads the full SKILL.md, then opens reference/tone.md and runs the script only as needed. The description is doing the routing work, so it must say both what the skill does and when to use it.

Worked example 4.4: a custom subagent

A read-only security reviewer, stored at .claude/agents/security-reviewer.md: ---

name: security-reviewer

description: Reviews code changes for security issues. Use after significant changes to auth, payments, or input handling.

  • tools: Read, Grep, Glob
  • model: sonnet
  • ---

You are an application security reviewer. Look for injection, broken access control, secrets in code, and unsafe deserialization. Report findings as a list with file, line, severity, and a suggested fix. Do not edit files.

The main session can delegate to it, and the reviewer works in its own context. Its tool list makes it unable to edit anything, which is an enforced boundary, not just an instruction.

Worked example 4.5: headless Claude Code in CI

A team wants every pull request to get an automated first-pass review comment. A CI step might run:

claude -p "Review the diff in this PR for bugs and missing tests. Output a short markdown report." \

  • --output-format json \
  • --allowedTools "Read,Grep,Glob,Bash(git diff:*)" \
  • > review.json

Then a later step posts the result field from review.json as a PR comment. Key choices: noninteractive -p mode, machine-readable output, and a narrow allow-list so the CI agent can read and diff but not edit or push. The API key comes from the CI secret store, never the repository. Use --output-format stream-json when another process needs live progress, such as a dashboard that shows each tool call as it happens.

Worked example 4.6: a session workflow for a large refactor

A developer must move a service from callbacks to async/await across 60 files. Start in plan mode. Ask Claude to read the code and propose a migration plan with ordering and risks. Nothing is edited.

Review and adjust the plan. Save it to MIGRATION.md so it survives /clear.

CLAUDE CODE (3.1%)

Switch to normal or accept-edits mode and do one module at a time, running pnpm test after each.

When context fills with old diffs, run /compact, or /clear and point Claude back at MIGRATION.md.

Commit after each green module so any step can be rolled back.

This is the "codebase modernization" pattern the exam guide names: plan, small steps, verify, persist state outside the context window.

Scenario drills

A developer's personal CLAUDE.md preference ("always explain changes in Spanish") is confusing teammates. Where should it live? Claude Code keeps reading .env during debugging. What is the enforceable fix? A team has 30 reference documents Claude occasionally needs. CLAUDE.md or Skills? A CI job must fail the build if Claude's review finds a critical issue. Which output format helps?

A subagent "reviewer" sometimes edits files despite its prompt saying not to. What should change?

A new repository has no CLAUDE.md. What is the quickest good starting point? Answers:

In the user-level ~/.claude/CLAUDE.md, not the shared project file.

A deny rule for Read(./.env) in settings (a hook can enforce it too).

Skills, or files referenced from Skills, so they load only when relevant.

--output-format json, so the job can parse a severity field and set the exit code. Remove edit and write tools from its tools list.

Run /init and then trim and correct what it generates.

Common traps

Putting secrets or personal preferences in the shared project CLAUDE.md or .claude/ settings.json. Use settings.local.json or user-level files.

Expecting a CLAUDE.md instruction to be enforced. It is guidance; use permissions or hooks for enforcement.

Loading huge reference docs into CLAUDE.md instead of a Skill that loads on demand. Running headless in CI with broad permissions. Grant only the tools the job needs.

Where should a team's shared build and test commands go?

A developer wants to allow npm test without prompts on their machine only. Which file?

Why are Skills cheaper on context than pasting the same instructions into CLAUDE.md?

How do you run Claude Code in a CI pipeline and parse its result?

Answers: The project CLAUDE.md committed to git. .claude/settings.local.json. Only the skill's name and description load until it is needed (progressive disclosure). Headless mode: clau de -p "..." --output-format json.

CLAUDE CODE (3.1%)

Use ← → to move between sections