Claude Code Configuration & Workflows
Everything Domain 3 tests: the CLAUDE.md hierarchy, path-scoped rules under .claude/rules/, skills and slash commands with real tool-scoping, when to use plan mode versus direct execution, and headless -pinvocation for CI/CD. This is the "Code Generation with Claude Code" and "Claude Code in CI/CD" scenarios, made concrete.
3.1 CLAUDE.md hierarchy: project vs user
Claude Code reads project context from a file named CLAUDE.md, and it exists at two levels that the exam expects you to tell apart on sight:
| Project-level CLAUDE.md | User-level ~/.claude/CLAUDE.md | |
|---|---|---|
| Location | At the repo root, alongside the code | In the user's home directory, outside any repo |
| Scope | Every contributor working in this repo | Only this person, across every repo they touch |
| Version control | Committed — reviewers see changes to it in PRs | Not committed, not shared |
| Typical content | Coding standards, architecture notes, build/test commands, protected paths | Personal formatting preferences, preferred verbosity, personal shortcuts |
Both files load into the same Claude Code session and their content is simply concatenated into context — there is no override semantics to memorise, just "shared team standard" goes in the repo, "my personal preference" goes in the home directory. CLAUDE.md also supports an @path/to/file import syntax, letting a short CLAUDE.md pull in longer reference documents without bloating the file itself:
# CLAUDE.md (repo root)
## Commands
- Build: npm run build
- Test: npm test
- Lint: npm run lint
## Architecture
See @docs/architecture.md for the service boundaries and data flow.
Never edit generated files under src/generated/.
## Style
Prefer named exports. Match existing test structure in fixtures/.~/.claude/CLAUDE.md, not the project file. Flip the stem to "the whole team must follow this build command" and the answer flips to project-level.3.2 .claude/rules/ — path-scoped instructions
CLAUDE.md is blanket context — it loads into every session regardless of what Claude happens to be touching. When an instruction only matters for a subset of files, a blanket instruction is noise the rest of the time. .claude/rules/ solves this: each rule is a Markdown file with YAML frontmatter specifying a paths field (glob patterns, e.g. src/api/**/*.ts), and the instruction body only loads into context when Claude is working with a matching file. A rule with no paths field loads unconditionally, same as CLAUDE.md.
# .claude/rules/test-fixtures.md
---
paths:
- "**/*.test.ts"
---
When editing or adding test files, always reuse the existing helpers in
fixtures/ (buildUser, buildOrder, mockClock) instead of constructing test
data inline. If a fixture you need doesn't exist yet, add it to
fixtures/ rather than duplicating setup logic in the test file.This rule is invisible to Claude while it is editing src/api/orders.ts, and loads automatically the moment Claude opens or edits anything matching **/*.test.ts. That precision is the entire value proposition over a CLAUDE.md instruction: scope the instruction to where it is relevant, not to every session.
.claude/rules/ question with a pathsanswer. A requirement phrased as "in this repo, Claude should always Y" (no file-type qualifier) points back to CLAUDE.md instead.3.3 Skills and slash commands
Two related but distinct customization mechanisms live under .claude/, and the exam tests telling them apart:
Slash commands — .claude/commands/*.md
A custom slash command is a Markdown file under .claude/commands/, invoked explicitly by name as /command-name. It can take arguments via $ARGUMENTS, making it a reusable, parameterised prompt template a developer triggers on demand — nothing loads unless someone types the command.
# .claude/commands/fix-issue.md
Fetch GitHub issue $ARGUMENTS, understand the bug it describes, locate
the relevant code, and propose a fix. Do not open a PR — stop after
presenting the diff for review.Agent Skills — packaged instructions Claude loads when relevant
A Skill is not manually invoked by name — Claude decides to load it when its description matches what the current task needs. Skill frontmatter carries three fields the exam likes to test against each other, because two of them sound like the same thing and are not: context: fork runs the skill in an isolated context (the same context-isolation idea as subagents in Domain 1, applied to a skill); allowed-tools pre-approves the listed tools so Claude can call them during that turn without a permission prompt — it does not restrict anything else, every other tool the session is permitted to use remains callable, just with its normal prompt; disallowed-toolsis the field that actually removes tools from the skill's available pool while it is active — that is the real restriction mechanism.
# .claude/skills/dependency-audit/SKILL.md
---
name: dependency-audit
description: Reviews dependency-update PRs for supply-chain risk —
new transitive deps, license changes, suspicious postinstall scripts.
Use when a PR modifies package.json or a lockfile.
context: fork
disallowed-tools: Bash, Write, Edit
---
Examine the diff to package.json and the lockfile. Flag new
dependencies, license changes, and any postinstall/prepare script
additions. You have no write access — report findings only.disallowed-toolsis the real, declarative security boundary — it ties directly back to Domain 1's anti-pattern #6 (unrestricted tool access): a skill built to review code has no business holding Bash or Write, regardless of what the parent session is permitted to do. allowed-tools solves a different problem entirely (skipping approval friction for tools you already trust the skill to use) and confusing the two is a genuine, exam-tested trap.
allowed-tools: Read, Grep, Globso the skill can't touch Bash or Write." This is the exam's favourite Domain 3 trap: allowed-toolsonly pre-approves what's listed, it does not remove anything else from the pool — Bash and Write would still be callable (just subject to a normal permission prompt). Real restriction is disallowed-tools. A description-field warning is a separate, weaker trap: that's prompt-based enforcement, the anti-pattern this feature exists to avoid.3.4 Plan mode vs direct execution
Claude Code can work two ways: plan mode, where Claude proposes an approach and gets it explicitly approved before touching any files, or direct execution, where it goes straight to editing. Neither is universally correct — the exam rewards matching the mode to the task's blast radius and ambiguity.
| Direct execution | Plan mode | |
|---|---|---|
| Best when | Small, well-defined, low-risk change — a typo fix, a one-line config tweak, an isolated bug with an obvious cause | Larger, higher-risk, or ambiguous change — a multi-file refactor, a schema migration, anything touching auth or billing |
| Overhead if misapplied | Using it for a large ambiguous change risks an unreviewed mistake across many files | Using it for a trivial one-line fix is pure ceremony — a review step with nothing meaningful to review |
3.5 Headless mode for CI/CD
Claude Code can run without any interactive terminal session at all, using the -p (print) flag. This is what makes it usable inside CI/CD: a pipeline step invokes Claude, Claude does its work and prints a result, and the process exits — no prompt is ever waiting on a human.
claude -p "review this diff for security issues" --output-format jsonPaired with --output-format json (or stream-json for incremental output), the result comes back as a structured envelope instead of free-text stdout — conceptually containing the result text Claude produced, cost information for the run, and a session id identifying that invocation. A CI script parses this envelope directly; it never needs to regex-scrape a paragraph of prose looking for a verdict.
Session isolationmatters just as much as the flags: each CI invocation — each PR, each run — should start a fresh session in its own working directory. Reusing one long-lived session across multiple PRs risks one PR's diff, findings, or conversation history leaking into another's review.
-p is the only shape built for unattended execution.3.6 Choosing the right invocation shape for CI
Put 3.5 together into the exam's favourite synthesis question: given a requirement like "review PRs and post structured findings a bot can parse," the correct combination is always the same shape:
- Headless
-p— never interactive mode on a CI runner. --output-format json(orstream-json) — never the default free-text output parsed downstream with regular expressions.- A fresh, isolated session per invocation — never one long-lived session shared across unrelated PRs.
Checkpoint quiz — Domain 3
Exam-style: one scenario, one correct answer, three plausible mistakes. Click an option to lock in and see the explanation.
A team of eight engineers wants every contributor's Claude Code session to know the repo's testing commands and architecture notes, checked into source control so reviewers see changes to it in PRs. Where should this content live?
One engineer always wants Claude to prefer functional React components and avoid default exports, across every repo they touch — nobody else on the team shares this preference. Where does this belong?
The team wants Claude to always reuse helpers from fixtures/ when editing test files, but this instruction is irrelevant noise when Claude is editing anything else in the repo. What is the architecturally correct way to encode this?
A security-conscious team builds a custom Agent Skill that reviews dependency-update PRs. They want a frontmatter setting that guarantees the skill can never call Bash or Write while it is active — no matter what tools the parent session otherwise has permission to use. Which frontmatter field actually enforces that?
A CI pipeline needs Claude Code to review each PR's diff and post structured findings a bot can parse and turn into inline comments. This runs unattended on a shared runner used across many concurrent PRs. Which invocation is correct?
Quick glossary
Every term below appears somewhere in this course. If a question uses a word you're unsure of, check here before re-reading the whole lesson.
Agentic loop
The repeating cycle behind any Claude-powered agent: send a request, check what Claude wants to do next (stop_reason), run a tool if asked, send the result back, repeat until Claude is done.
stop_reason
A field on Claude's response telling your code why it stopped talking — e.g. it wants to call a tool (tool_use), it finished (end_turn), or it ran out of room (max_tokens).
tool_use / tool_result
tool_use is Claude asking your code to run something (a search, a database lookup...). tool_result is your code's answer, sent back so Claude can continue.
Subagent / Agent tool
A helper Claude spawns to do one focused piece of work in its own separate memory space, then reports back a summary — so the main conversation doesn't get cluttered with the helper's scratch work.
Hooks (PreToolUse / PostToolUse)
Small scripts that run automatically around a tool call — one right before it (can block it entirely) and one right after (can react to the result). Used for rules that must always hold, not just usually hold.
MCP (Model Context Protocol)
A standard way to connect Claude to external systems — databases, internal tools, company APIs — through a shared plug-in format instead of custom one-off code every time.
MCP Tools vs Resources vs Prompts
The three things an MCP connection can offer: Tools are actions Claude decides to call itself; Resources are data the surrounding app decides to hand Claude; Prompts are ready-made instructions a person picks, like a menu option.
.mcp.json
A config file listing which external MCP connections a project uses — shared with the whole team via version control, with any secret keys kept out of it and read from environment variables instead.
CLAUDE.md
A plain-text file Claude reads automatically at the start of every session in a project — the place for standing instructions like coding conventions or how the codebase is organized.
.claude/rules/
Instructions that only switch on for certain files (e.g. only when editing test files), instead of loading into every single session the way CLAUDE.md does.
Agent Skill
A packaged set of instructions Claude loads by itself when a task matches, without anyone typing a command — think of it as an instruction manual Claude picks up automatically off the shelf.
allowed-tools vs disallowed-tools
Two different settings that sound alike: allowed-tools just skips the usual 'are you sure?' prompt for tools you've pre-approved — it doesn't block anything else. disallowed-tools is what actually removes a tool from what's available.
Plan mode
A mode where Claude describes what it's about to do and waits for a yes before touching any files — used for bigger or riskier changes, skipped for small obvious ones.
Message Batches API
A cheaper way to send Claude a large pile of requests when nobody is waiting on the answer right away — costs about half as much, but can take up to a day to come back.
Prompt caching
A way to avoid Claude re-reading the same large, unchanging block of text (like a system prompt or a codebase) on every single request — it's remembered for a while, which is both cheaper and faster.
Context window
The total amount of conversation and text Claude can 'see' at once for a given request. When a conversation runs long, older parts may need to be summarized or dropped to make room.
Hub-and-spoke (multi-agent)
A setup where one coordinator agent hands out tasks to several helper agents and collects their answers — the helpers never talk directly to each other, only to the coordinator.
Anti-pattern
A design choice that looks reasonable but causes real problems in practice — this course names seven specific ones the exam likes to hide inside wrong answers.