Domain 3 — Claude Code Configuration & Workflows
CLAUDE.md memory hierarchy and its modular alternatives (@import, .claude/rules/), custom slash commands and Agent Skills with their frontmatter options, path-scoped conditional rules, the choice between plan mode and direct execution, iterative refinement techniques such as input/output examples and test-driven iteration, and non-interactive invocation of Claude Code in CI/CD pipelines. Expect scenario items framed around Scenario 2 (Code Generation with Claude Code), Scenario 4 (Developer Productivity) and Scenario 5 (Claude Code for Continuous Integration).Configure CLAUDE.md files with appropriate hierarchy, scoping, and modular organization
What you need to know
- User-level memory never reaches teammates. Only committed project and directory files do.
- Works for the veteran, broken for the new hire = a rule parked at user level.
- Run
/memoryfirst; it lists the files actually loaded. -
@importpulls standards in by reference;.claude/rules/splits topics into separately ownable files. - Scoping and sharing only — the guide gives no precedence between the three levels.
Show the three levels of CLAUDE.md configuration as a tree of scopes, which of them travel through version control to teammates, and which modular files (@import targets, .claude/rules/) hang off each level. It describes scoping and sharing only, not any precedence or override order.
Click a level to highlight the edge label describing its own scope — personal to one machine, or committed and received by every clone.
Worked examples
Diagnosing the "new hire gets no conventions" bug
Scenario 2 · Code Generation with Claude CodeA team lead has been telling Claude Code for months to use a specific error-handling wrapper and to never edit generated migration files. It works flawlessly in their sessions. A new engineer joins, clones the repo, and Claude immediately edits a generated migration.
The first move is /memory in each session to list loaded memory files. The lead's session loads ~/.claude/CLAUDE.md; the new engineer's does not, because that file exists only on the lead's machine. The rules were user-scoped all along. The fix is to move the team-relevant instructions into the committed project-level file and leave only genuinely personal preferences (e.g. preferred commit-message tone) in the user-level file.
bash Verify what is actually loaded, then move the rules into version control
# In each engineer's session, list the loaded memory files
/memory
# Move the team-relevant rules out of personal memory and commit them
git add CLAUDE.md .claude/rules/
git commit -m "chore: move error-handling and migration rules to project memory"Monorepo: per-package CLAUDE.md that imports only relevant standards
Scenario 4 · Developer Productivity with ClaudeA monorepo has packages/api (GraphQL), packages/web (React) and infra/ (Terraform). A single root CLAUDE.md containing every convention would push infra rules into every frontend session and waste context.
Instead the root file carries only universal facts, and each package's directory-level CLAUDE.md uses @import to include the standards files its maintainers know are relevant. Nothing is duplicated: the shared standards live once under docs/standards/ and are referenced from wherever they apply.
markdown packages/api/CLAUDE.md — a thin file that imports the standards it needs
# API package
This package owns the public GraphQL schema.
## Standards that apply here
@docs/standards/graphql-conventions.md
@docs/standards/testing.md
@docs/standards/error-handling.md
## Local notes
- Resolvers live in `src/resolvers/`; never call the database directly from a resolver.
- Schema changes require a matching entry in `CHANGELOG.md`.Splitting a 900-line CLAUDE.md into .claude/rules/
A CLAUDE.md that has grown to hundreds of lines is hard to review, and pull requests touching it produce unreadable diffs. Split it by topic into .claude/rules/testing.md, .claude/rules/api-conventions.md and .claude/rules/deployment.md, each owned by the team that cares about it. The remaining CLAUDE.md becomes a short orientation document. This also sets you up for path scoping (task statement 3.3): once rules are separate files they can be activated conditionally instead of always loaded.
text Repository layout after the split
repo/
CLAUDE.md # short: what the project is, how to build it
.claude/
rules/
testing.md # test layout, fixtures, coverage expectations
api-conventions.md # versioning, error envelope, pagination
deployment.md # release process, migration safety
packages/
api/CLAUDE.md # directory-level, @imports the API standards
web/CLAUDE.mdAnti-patterns
- Putting team-wide coding standards in
~/.claude/CLAUDE.mdinstead of a committed project-level file because user-level memory is never shared through version control and new teammates silently get nothing. - Growing one monolithic root
CLAUDE.mdinstead of splitting topics into.claude/rules/files or importing them because the file becomes unreviewable and loads irrelevant context into every session. - Copy-pasting the same standards text into every package
CLAUDE.mdinstead of using@importbecause the copies drift apart and nobody knows which one is authoritative. - Guessing why behavior differs between sessions instead of running
/memoryto see which files are loaded because the hierarchy is invisible until you inspect it.
How it is examined
- Stems that describe "works for the senior engineer, not for the new team member" are asking you to identify user-level vs project-level scoping — pick the answer that moves instructions into version-controlled project configuration.
- The tempting wrong answer is usually "tell the new hire to copy the file into their
~/.claude/directory": it restores the behavior but leaves the standard unshared and unreviewable. - When the stem mentions a huge
CLAUDE.mdand wasted context, the right answers involve@importselectivity or.claude/rules/topic files, not shortening prose or raising a context limit.
Why this is true
Claude Code builds its instruction set ("memory") by combining several CLAUDE.md files. The skill being measured is knowing which file a given instruction belongs in, and diagnosing the symptoms when it sits in the wrong one.
The three levels
| Level | Path | Applies to | Reaches teammates? |
|---|---|---|---|
| User | ~/.claude/CLAUDE.md |
every project that one user opens | No — never version-controlled |
| Project | .claude/CLAUDE.md or root CLAUDE.md |
everyone who clones the repo | Yes |
| Directory | a CLAUDE.md inside a subdirectory |
one package or service in the tree | Yes |
The guide describes scoping and sharing here and nothing more. It states no precedence or override order between the levels, so an answer that ranks one level over another is inventing a rule.
The diagnostic pattern
The "works on my machine" configuration bug: a senior engineer's conventions are honored in their sessions, but a new team member does not receive them. The cause is almost always instructions parked in user-level ~/.claude/CLAUDE.md instead of project-level configuration. The fix is to move them into the committed project file.
/memory is the instrument. It lists the memory files actually loaded in the current session, so you can see what Claude is really reading before theorizing about behavior that differs between sessions or teammates.
Keeping it modular
Two mechanisms stop CLAUDE.md from growing into an unreadable monolith.
| Mechanism | What it does | Reach for it when |
|---|---|---|
@import |
references an external file from inside CLAUDE.md |
each package should pull in only the standards its maintainers know apply |
.claude/rules/ |
holds topic-specific rule files: testing.md, api-conventions.md, deployment.md |
one file has grown too large to review or own |
The split into .claude/rules/ also makes each topic separately reviewable, and it is the prerequisite for the path scoping in 3.3.
The trade-off to remember: project and directory files are shared and code-reviewed; user-level files are private and invisible to review. Anything the team must obey has to be committed.
Exam guide, verbatim — what is measured
Knowledge of
- The CLAUDE.md configuration hierarchy: user-level (~/.claude/CLAUDE.md), project-level (.claude/CLAUDE.md or root CLAUDE.md), and directory-level (subdirectory CLAUDE.md files)
- That user-level settings apply only to that user—instructions in ~/.claude/CLAUDE.md are not shared with teammates via version control
- The @import syntax for referencing external files to keep CLAUDE.md modular (e.g., importing specific standards files relevant to each package)
- .claude/rules/ directory for organizing topic-specific rule files as an alternative to a monolithic CLAUDE.md
Skills in
- Diagnosing configuration hierarchy issues (e.g., a new team member not receiving instructions because they're in user-level rather than project-level configuration)
- Using @import to selectively include relevant standards files in each package's CLAUDE.md based on maintainer domain knowledge
- Splitting large CLAUDE.md files into focused topic-specific files in .claude/rules/ (e.g., testing.md, api-conventions.md, deployment.md)
- Using the /memory command to verify which memory files are loaded and diagnose inconsistent behavior across sessions
Create and configure custom slash commands and skills
What you need to know
- Project directory = shared through version control. Home directory = yours alone.
-
context: forkisolates a skill in a sub-agent context; only its result returns. -
allowed-toolsnarrows tool access during execution;argument-hintprompts for missing parameters. - Load timing decides: every session →
CLAUDE.md; only for this task → skill. - Personal variant of a team skill: same directory idea, different name, no effect on colleagues.
Help the learner choose the right home for an instruction on two axes — always needed versus invoked on demand, and team-wide versus personal — with each of the four cells naming the file location that fits.
Show that a skill declared with context: fork executes in an isolated sub-agent context and returns only a summary, so the main session context is preserved.
Worked examples
A project-scoped /review-pr command every engineer gets from the repo
Scenario 2 · Code Generation with Claude CodeThe team keeps rewriting the same pre-PR review prompt from memory, and everyone's version differs. Putting it in .claude/commands/review-pr.md makes it a committed, reviewable artifact: /review-pr behaves identically for everyone, and improving the prompt is a normal pull request. Had it gone in ~/.claude/commands/, only its author would have it — the same scoping trap as 3.1.
markdown .claude/commands/review-pr.md — committed, so the whole team has /review-pr
---
description: Review the current branch against our team review criteria
argument-hint: [base-branch]
---
Review the diff between $ARGUMENTS (default: main) and HEAD.
Check, in this order:
1. Error handling on every new external call.
2. Test coverage for new branches, using the fixtures in tests/fixtures/.
3. Public API changes — flag anything that needs a CHANGELOG entry.
Report findings grouped by severity. Do not comment on formatting;
the linter owns that.context: fork for a verbose codebase-analysis skill
Scenario 4 · Developer Productivity with ClaudeAn "audit dependencies" skill reads every package.json in a monorepo, greps for usages and produces pages of intermediate notes. Run inline, it fills the main conversation with noise and crowds out the actual task.
Declaring context: fork runs it in an isolated sub-agent context: the exploration happens there and only the summary comes back. The same reasoning applies to exploratory skills such as "brainstorm three alternative designs" — you want the conclusions, not the discarded branches. Adding allowed-tools limited to read-only and file-write operations guarantees the audit cannot take destructive actions, and argument-hint makes the expected scope explicit.
markdown .claude/skills/dependency-audit/SKILL.md
---
name: dependency-audit
description: Audit dependency versions and unused packages across the monorepo
context: fork
allowed-tools: Read, Grep, Glob, Write
argument-hint: <package-path or "all">
---
Audit $ARGUMENTS.
1. Collect declared dependencies and their versions.
2. Grep for actual imports to find declared-but-unused packages.
3. Flag version drift between packages.
Return only a table of findings plus a one-paragraph summary.
Write the full detail to reports/dependency-audit.md.Choosing between a skill and CLAUDE.md
Two candidate rules for a team:
- "Every exported function needs a TSDoc comment." This must hold in every session, for every change, so it belongs in
CLAUDE.md(or a.claude/rules/file) as an always-loaded standard. - "How to generate a new database migration: run the generator, hand-edit the down step, verify against the staging snapshot, update the fixture set." This is a 40-line procedure needed a few times a month. Keeping it in
CLAUDE.mdcosts context in every unrelated session; as a skill it is loaded only when invoked.
If an engineer wants a stricter personal variant of the migration skill, they create it in ~/.claude/skills/ under a different name so the team's version keeps working unchanged for everyone else.
Anti-patterns
- Storing a team workflow in
~/.claude/commands/instead of.claude/commands/because personal command directories are not version-controlled so teammates never receive the command. - Running a verbose analysis or brainstorming skill inline instead of with
context: forkbecause its intermediate output consumes the main conversation context that the real task needs. - Leaving a skill with unrestricted tool access instead of narrowing
allowed-toolsbecause a task-specific workflow then retains the ability to take destructive actions it never needs. - Pasting a long, rarely used procedure into
CLAUDE.mdinstead of packaging it as an on-demand skill because always-loaded memory pays that context cost in every single session.
How it is examined
- Any stem about a skill "flooding the conversation" or "exhausting context with discovery output" is pointing at
context: fork, not at shortening the prompt or clearing history. - When the stem says an engineer wants a customized behavior "without affecting teammates", the answer is a personal variant in
~/.claude/skills/with a different name — not editing the shared.claude/skills/file. - For skill-vs-CLAUDE.md items, decide on load timing: "must apply to every change" points to CLAUDE.md, "needed only for this specific task" points to a skill. Distractors often propose putting the workflow in both.
Why this is true
Slash commands and Agent Skills package a repeatable workflow so a developer can invoke it on demand instead of retyping a prompt. The exam tests where you put them, which decides who gets them, and how you configure them, which decides how they behave.
Scoping: who receives it
| Location | Scope | Committed? |
|---|---|---|
.claude/commands/ |
slash commands for the whole team | Yes — reviewed like any other file |
~/.claude/commands/ |
your own slash commands, across all your projects | No |
.claude/skills/ |
the team's skills | Yes |
~/.claude/skills/ |
your personal variant — give it a different name | No |
The different name is the point of the last row: it keeps the team's version working untouched while you run your own.
Skill frontmatter
A skill lives in a SKILL.md file whose YAML frontmatter configures how it runs. Three options are tested.
| Option | What it does | Stem that points at it |
|---|---|---|
context: fork |
runs the skill in an isolated sub-agent context and returns only its result | a skill floods the conversation or exhausts context with discovery output |
allowed-tools |
restricts which tools the skill may use while it runs | a skill could take a destructive action it never needs |
argument-hint |
states the parameters expected, prompting for them when none are given | developers invoke the skill with no arguments |
Do not confuse this "fork" with Domain 1's fork_session (1.7). context: fork isolates a skill's output so it never enters the main conversation; fork_session creates branches that inherit a shared analysis baseline.
Skills vs CLAUDE.md
This is the recurring judgment call, and it turns on load timing.
CLAUDE.md |
Skill | |
|---|---|---|
| Loaded | always | on invocation |
| Holds | universal standards that must hold every session | task-specific workflows needed when that task comes up |
| Context cost | paid in every session | paid only when you call it |
So a rarely used, verbose procedure sitting in CLAUDE.md is in the wrong place. Move it to a skill and it leaves every session's context while staying one command away.
Exam guide, verbatim — what is measured
Knowledge of
- Project-scoped commands in .claude/commands/ (shared via version control) vs user-scoped commands in ~/.claude/commands/ (personal)
- Skills in .claude/skills/ with SKILL.md files that support frontmatter configuration including context: fork, allowed-tools, and argument-hint
- The context: fork frontmatter option for running skills in an isolated sub-agent context, preventing skill outputs from polluting the main conversation
- Personal skill customization: creating personal variants in ~/.claude/skills/ with different names to avoid affecting teammates
Skills in
- Creating project-scoped slash commands in .claude/commands/ for team-wide availability via version control
- Using context: fork to isolate skills that produce verbose output (e.g., codebase analysis) or exploratory context (e.g., brainstorming alternatives) from the main session
- Configuring allowed-tools in skill frontmatter to restrict tool access during skill execution (e.g., limiting to file write operations to prevent destructive actions)
- Using argument-hint frontmatter to prompt developers for required parameters when they invoke the skill without arguments
- Choosing between skills (on-demand invocation for task-specific workflows) and CLAUDE.md (always-loaded universal standards)
Apply path-specific rules for conditional convention loading
What you need to know
- Rule files in
.claude/rules/can declare YAML frontmatterpathswith glob patterns for conditional activation. - A path-scoped rule loads only when the files being edited match its globs, cutting both irrelevant context and token usage.
- Use globs (e.g.
**/*.test.tsx) when a convention applies to a file type spread across many directories. - Use a directory-level
CLAUDE.mdonly when the convention genuinely belongs to one location in the tree. - Glob rules express a cross-cutting convention once, instead of duplicating it into a CLAUDE.md in every directory that contains such files.
Make clear that the paths glob in a rule file is evaluated against the files being edited, so only matching rules enter the session context while non-matching rules cost nothing.
Hover a rule outcome to see an example glob and the kind of edit that would trigger it.
Worked examples
Test conventions that follow the files, not the folders
Scenario 2 · Code Generation with Claude CodeA React monorepo colocates tests: components/Button/Button.test.tsx, hooks/useCart.test.tsx, packages/api/src/resolvers/order.test.tsx. The team has firm test conventions (React Testing Library only, no snapshot tests, one describe per exported symbol).
Encoding this as directory-level CLAUDE.md files would mean a copy in dozens of directories. Instead one rule file scoped with paths: ["**/*.test.tsx"] applies wherever a test file lives, and contributes nothing to sessions that touch no tests.
markdown .claude/rules/testing.md — activated only when editing test files
---
description: Frontend test conventions
paths: ["**/*.test.tsx", "**/*.test.ts"]
---
# Test conventions
- Use React Testing Library. Never add snapshot tests.
- Query by accessible role or label, never by test id.
- One top-level describe block per exported symbol.
- Shared fixtures live in tests/fixtures/; do not build ad hoc factories.
- Assert on user-visible behavior, not on internal state.Infrastructure rules that stay out of application sessions
Scenario 4 · Developer Productivity with ClaudeAn infra team maintains long Terraform conventions — module structure, required tags, no inline provider blocks, remote state layout. Application engineers touch terraform/ a few times a quarter.
Scoping the rule to paths: ["terraform/**/*"] means the conventions are present and authoritative when someone edits infrastructure, and absent the rest of the time. Compare the alternative: the same text in the root CLAUDE.md would be loaded in every frontend session forever.
yaml The frontmatter is what does the scoping
---
description: Terraform module and tagging conventions
paths:
- "terraform/**/*"
- "**/*.tf"
---
# body: the actual conventions follow as markdownChoosing between the two mechanisms
Ask "is this rule about a place or about a kind of file?"
| Convention | Right mechanism |
|---|---|
Everything in services/billing/ must use the ledger client |
Directory-level services/billing/CLAUDE.md |
| All test files, wherever they live, follow these conventions | .claude/rules/testing.md with paths: ["**/*.test.tsx"] |
| SQL migrations in every service must be reversible | .claude/rules/migrations.md with paths: ["**/migrations/*.sql"] |
| Project build and run instructions | Root CLAUDE.md (always loaded) |
The failure mode of getting this wrong is not a broken build — it is silent drift: duplicated directory files fall out of sync, or a monolithic always-loaded file quietly eats the context budget.
Anti-patterns
- Duplicating the same test or migration conventions into a directory-level
CLAUDE.mdin every folder that contains such files, instead of one glob-scoped rule because the copies inevitably drift apart. - Putting cross-cutting file-type conventions in the always-loaded root
CLAUDE.mdinstead of a path-scoped rule because every unrelated session then pays the token cost for context it cannot use. - Writing an overly broad glob such as
**/*in apathsfield because the rule is then effectively always loaded and you have lost the benefit of conditional activation.
How it is examined
- The give-away phrase is "spread throughout the codebase" or "regardless of directory" — that always points to glob-based
pathsscoping over directory-levelCLAUDE.md. - When a stem complains about token usage or irrelevant instructions, prefer the answer that makes rules conditional, not the one that deletes or shortens them.
- A tempting distractor is "add a CLAUDE.md to each directory containing tests" — it works today and is a maintenance trap tomorrow; the exam wants the single glob-scoped rule.
Why this is true
Path-specific rules solve a targeting problem. Directory-level CLAUDE.md files scope conventions by location; path-specific rules scope them by file pattern. Many real conventions are file-type conventions, and those files are scattered across the tree.
A rule file in .claude/rules/ can carry YAML frontmatter with a paths field containing glob patterns. The rule is then activated conditionally: it loads only when the files being edited match one of those globs. A Terraform rule with paths: ["terraform/**/*"] is invisible while you work on the React frontend, and appears the moment you touch infrastructure code.
Why conditional loading matters
Two effects, and the exam cares about both:
- Less irrelevant context. Claude is not reading Terraform naming conventions while fixing a CSS bug, so the instructions it does see are all relevant to the task.
- Lower token usage. Always-loaded memory is paid for in every session. Path-scoped rules are paid for only in the sessions that need them, which is what lets a large team keep a genuinely detailed rule set without bloating every conversation.
Globs vs directory-level CLAUDE.md
This is the discrimination the exam tests. Use a directory-level CLAUDE.md when the convention really is about a place: everything under services/billing/ must go through the ledger client. Use a path-scoped rule when the convention is about a kind of file that spans multiple directories:
**/*.test.tsx— test conventions, when tests sit next to the code they test all over the repo.**/migrations/*.sql— migration safety rules, one folder per service.terraform/**/*— infrastructure conventions.
With directory-level files you would have to duplicate the same test conventions into a CLAUDE.md in every directory that happens to contain tests, and then keep those copies in sync forever. A single glob-scoped rule file expresses the intent once, applies it by file type regardless of directory location, and stays out of context when it does not apply.
Path-scoped rule or skill?
Migrations show up on both sides of this line, so fix the discriminator now. A procedure you invoke — the steps for generating a migration — belongs in a skill (3.2). A convention that should apply whenever you edit matching files — migrations must be reversible — belongs in a path-scoped rule. Same subject, different trigger: one is called on demand, the other activates from the files being edited.
The mental model: paths turns a rule from "always on" into "on when relevant", and the glob is how you express relevance.
Exam guide, verbatim — what is measured
Knowledge of
- .claude/rules/ files with YAML frontmatter paths fields containing glob patterns for conditional rule activation
- How path-scoped rules load only when editing matching files, reducing irrelevant context and token usage
- The advantage of glob-pattern rules over directory-level CLAUDE.md files for conventions that span multiple directories (e.g., test files spread throughout a codebase)
Skills in
- Creating .claude/rules/ files with YAML frontmatter path scoping (e.g., paths: ["terraform/**/*"]) so rules load only when editing matching files
- Using glob patterns in path-specific rules to apply conventions to files by type regardless of directory location (e.g., **/*.test.tsx for all test files)
- Choosing path-specific rules over subdirectory CLAUDE.md files when conventions must apply to files spread across the codebase
Determine when to use plan mode vs direct execution
What you need to know
- Reach for plan mode when a wrong approach is expensive to undo — not merely when the task is long.
- Direct execution is for simple, well-scoped, already-understood changes such as a single-file fix with a clear stack trace.
- Plan mode allows safe exploration and design before any edit, which is how it prevents costly rework.
- Explore keeps discovery output out of the main context; only its summary comes back.
- The two combine naturally: plan mode for investigation, then direct execution for the agreed implementation.
Give the learner a repeatable decision path from a task description to plan mode, direct execution, or the combined plan-then-execute pattern, including where the Explore subagent fits.
Click a decision node to highlight its outgoing branches and the labels already shown on them.
Worked examples
Library migration across 45+ files: plan first, then execute
Scenario 2 · Code Generation with Claude CodeA team must replace a date library used in 45+ files. There are real decisions: migrate module by module behind a thin adapter, or do a single mechanical sweep; keep the old formatting semantics or adopt the new library's; how to handle the three files that rely on a deprecated parsing quirk.
This is textbook plan mode — multi-file, multiple valid approaches, architectural consequences. Claude explores the call sites, produces a sequenced plan with the adapter decision made explicit, and the team approves or amends it before a single file changes. Only then does the work switch to direct execution, applying the approved plan module by module. Discovering the parsing quirk after 30 files were already converted would have been the costly rework plan mode exists to prevent.
A one-line validation fix does not need a plan
Scenario 2 · Code Generation with Claude CodeA bug report includes a stack trace pointing at parseBookingDate(): an end date before the start date is accepted and blows up downstream. The change is a single conditional in a single function, with an obvious test.
Direct execution. The scope is clear, the blast radius is one function, and there is no design choice to make. Requesting a plan here produces a document nobody needs. The exam likes this pair — the same scenario offers a 45-file migration (plan) and a single validation conditional (direct) to check that you are reading scope, not reaching for the "safer-sounding" option every time.
Explore subagent for the discovery phase of a multi-phase task
Scenario 4 · Developer Productivity with ClaudeAn engineer must add tenant isolation to a legacy service they have never seen. Phase 1 is discovery: where are requests authenticated, which queries touch tenant-scoped tables, what middleware exists. Reading that inline would fill the context with file dumps and leave no room for phases 2 and 3.
Delegating discovery to the Explore subagent keeps the verbose reading in an isolated context and returns a summary — the list of entry points and the tables involved. The main conversation then plans the change against that summary and implements it with context to spare.
text Three phases, three tools
Phase 1 Discovery -> Explore subagent (verbose reads, returns a summary)
Phase 2 Design -> plan mode (multiple approaches, architectural choice)
Phase 3 Implementation -> direct execution (apply the approved plan, file by file)
Anti-pattern: doing all three inline in one conversation and running out of
context during phase 3, after the expensive thinking is already done.Anti-patterns
- Using plan mode for a single-file fix with a clear stack trace instead of direct execution because you pay planning overhead for work whose scope was never in question.
- Jumping straight to direct execution on a multi-file architectural change instead of planning it because approaches that turn out to be wrong are discovered only after edits exist, forcing costly rework.
- Running verbose codebase discovery inline instead of delegating it to the Explore subagent because file dumps exhaust the main context before the implementation phase begins.
- Treating plan mode and direct execution as mutually exclusive for a whole task instead of choosing per phase because the natural pattern is planning the investigation and then executing the plan directly.
How it is examined
- Count the signals in the stem: number of files, presence of alternative approaches, and architectural or infrastructure consequences. Two or more signals means plan mode.
- When the stem gives a clear stack trace and a single function, the correct answer is direct execution — "use plan mode to be safe" is the designed distractor.
- Any mention of context exhaustion during exploration of an unfamiliar codebase is an Explore subagent item, not a plan-mode item; watch for options that confuse the two.
Why this is true
Plan mode and direct execution are two ways to spend Claude Code's effort, and choosing wrongly is expensive in both directions. The exam gives you a task description and asks which one fits, so read it for signals.
Signal to choice
| Signal in the task description | Correct choice | Why |
|---|---|---|
| A complex task: large-scale change, multiple valid approaches, architectural decisions, multi-file modifications — microservice restructuring, a library migration affecting 45+ files, integration approaches with different infrastructure requirements | Plan mode | it lets Claude explore the codebase and design a solution before committing to changes, so a bad approach is rejected on paper rather than discovered halfway through a 45-file edit — this is what prevents costly rework |
| A simple, well-scoped change whose work is already understood — one validation check added to a function, a date-validation conditional, a single-file bug fix with a clear stack trace | Direct execution | nothing is left to decide, so a plan costs tokens and wall-clock time and settles nothing |
| An unfamiliar codebase where discovery alone means reading dozens of files | Explore subagent | it isolates the verbose discovery output and returns summaries, preserving the main conversation's context |
| A multi-phase task — investigate, then build | Plan mode for investigation, direct execution for implementation | the guide's own combination; the decision is per phase of work, not per task |
Why discovery gets its own row
Discovery is the phase that quietly exhausts a context window. Tracing how authentication flows through an unfamiliar service can mean reading dozens of files, and every one of them lands in the main conversation. Delegating that reading is what leaves room for the planning and the implementation that come after it.
Why the combination is not a compromise
Plan mode and direct execution are not exclusive, and the guide says so explicitly. Plan the library migration — inventory the call sites, decide the sequencing, choose the compatibility shim — then execute the agreed approach directly, step by step, without re-planning each file.
The exam's framing: complexity and irreversibility push toward planning; clarity and small blast radius push toward direct execution.
Exam guide, verbatim — what is measured
Knowledge of
- Plan mode is designed for complex tasks involving large-scale changes, multiple valid approaches, architectural decisions, and multi-file modifications
- Direct execution is appropriate for simple, well-scoped changes (e.g., adding a single validation check to one function)
- Plan mode enables safe codebase exploration and design before committing to changes, preventing costly rework
- The Explore subagent for isolating verbose discovery output and returning summaries to preserve main conversation context
Skills in
- Selecting plan mode for tasks with architectural implications (e.g., microservice restructuring, library migrations affecting 45+ files, choosing between integration approaches with different infrastructure requirements)
- Selecting direct execution for well-understood changes with clear scope (e.g., a single-file bug fix with a clear stack trace, adding a date validation conditional)
- Using the Explore subagent for verbose discovery phases to prevent context window exhaustion during multi-phase tasks
- Combining plan mode for investigation with direct execution for implementation (e.g., planning a library migration, then executing the planned approach)
Apply iterative refinement techniques for progressive improvement
What you need to know
- Concrete input/output examples are the most effective fix when prose descriptions are interpreted inconsistently — 2 to 3 pairs is the sweet spot (distinct from the 2 to 4 few-shot examples of Domain 4 task statement 4.2).
- Test-driven iteration means writing tests for behavior, edge cases and performance first, then iterating by sharing the actual failures.
- The interview pattern has Claude ask questions before implementing, surfacing considerations the developer never thought to specify.
- Interacting problems go in one detailed message; independent problems are better fixed sequentially.
- To fix a stubborn edge case, supply the exact offending input and the exact expected output rather than describing the rule again.
Map the symptom you are seeing to the refinement technique the guide prescribes, and show test-driven iteration as a closed loop with an objective stopping condition.
Make the batching decision concrete: interacting fixes must be described together, independent fixes are more reliably handled one at a time.
Worked examples
Two examples beat three paragraphs of prose
Scenario 2 · Code Generation with Claude CodeA migration script must normalize legacy customer records. Prose instructions ("clean up the phone numbers, keep the country code if present, drop extensions") produce a different interpretation on every run.
Replacing the prose with concrete pairs ends the ambiguity, and deliberately including a null and an empty-extension case fixes the edge-case handling that prose kept getting wrong.
text 2-3 worked pairs, including the edge cases that keep failing
Transform each record's phone field. Examples:
in: { phone: "+34 91 555 0123 ext. 22" }
out: { phone: "+34915550123", extension: "22" }
in: { phone: "915550123" }
out: { phone: "+34915550123", extension: null }
in: { phone: null }
out: { phone: null, extension: null } # do not throw, do not default
Anything not matching these shapes: leave the record untouched and add its
id to the skipped list.Test-driven iteration on a rate limiter
Scenario 4 · Developer Productivity with ClaudeRather than describing a token-bucket rate limiter in prose, the engineer writes the suite first: normal traffic passes, burst above capacity is rejected, the bucket refills over time, concurrent callers are accounted correctly, and 10k checks complete inside the performance budget.
Claude implements against the suite; the engineer runs it and pastes the failures verbatim. Round one fails the refill test, round two fails the concurrency test, round three passes. Each iteration is driven by unambiguous evidence instead of a judgment call, and "done" is defined before the work starts.
python The suite is written first — expected behavior, edge cases, performance
def test_allows_traffic_within_capacity(): ...
def test_rejects_burst_above_capacity(): ...
def test_refills_tokens_over_time(): ... # edge case
def test_concurrent_callers_share_one_bucket(): # edge case
...
def test_10k_checks_under_50ms(): # performance requirement
...
# Then: implement, run, and paste the failing output back verbatim
# as the next iteration's input.Interview first, then batch the interacting fixes
Scenario 4 · Developer Productivity with ClaudeAn engineer must add a caching layer to a service in a domain they do not know well. Before any code, they ask Claude to interview them. The questions surface invalidation strategy, behavior on cache unavailability, and whether stale reads are acceptable during a write — none of which were in the original request.
After implementation, review finds four issues. Three are independent (a misleading log message, a missing metric, a typo in a config key) and are handled one at a time. The other two — the TTL and the invalidation-on-write path — interact: changing one without the other produces incoherent behavior, so they go into a single detailed message describing both, together with the intended combined semantics.
Anti-patterns
- Rewriting the prose description a third time instead of supplying 2-3 concrete input/output examples because prose is exactly what was being interpreted inconsistently.
- Implementing first and writing tests afterwards instead of test-driven iteration because you lose the objective failure signal that drives progressive improvement.
- Fixing interacting issues one at a time instead of in a single detailed message because each isolated fix invalidates the assumptions of the previous one.
- Dumping every unrelated independent issue into one giant message because the changes become hard to verify and a failure in one obscures the others.
How it is examined
- If the stem says results are "inconsistent" or "interpreted differently each time", the answer is concrete input/output examples — not a longer or more emphatic description.
- Watch the interaction test: options will offer both "send all issues at once" and "fix them one by one". Decide by whether the fixes affect each other, and re-read the stem for that hint.
- The interview pattern shows up whenever the developer is in an unfamiliar domain; the distractor is asking Claude to "explain its approach" afterwards, which surfaces nothing new before the code exists.
Why this is true
Iterative refinement is the craft of turning a mediocre first result into a correct one with the fewest, best-targeted follow-up messages. The exam tests four specific techniques and, crucially, when each one applies.
Concrete input/output examples
When prose descriptions are interpreted inconsistently, concrete input/output examples are the most effective way to communicate the expected transformation. "Normalize the address field" can mean five things; two or three worked pairs — this input becomes exactly this output — pin the semantics down in a way no adjective can. The guide's guidance is 2–3 examples: enough to show the pattern and its edge, not so many that you are writing the test suite by hand. Keep that figure attached to its scope — 2–3 is the count for input/output pairs used in iterative refinement, and it is a different statement from Domain 4 §4.2's 2–4 targeted few-shot examples for ambiguous-case prompting. A stem asking "how many examples?" is answered by which of the two techniques it describes. This is also the fix for a specific edge-case failure: supply a concrete input containing the problem value (a null, an empty string, a date at a boundary) alongside the exact expected output.
Test-driven iteration
Write the test suite first, covering expected behavior, edge cases and performance requirements, then let Claude implement against it and iterate by sharing the failures. Each failure is unambiguous, machine-generated feedback: no interpretation gap, no argument about whether the behavior is correct. Progressive improvement is then just a loop — run tests, paste failures, repeat — and the loop has an objective stopping condition.
The interview pattern
In an unfamiliar domain, you do not know what you failed to specify. The interview pattern inverts the flow: ask Claude to ask you questions before implementing. Prompting for questions about a caching layer surfaces invalidation strategy, stampede behavior, and what happens when the cache is unavailable — considerations the developer may not have anticipated. It converts unknown unknowns into an answerable list, before code exists that assumes the wrong answers.
Batch or sequential?
The judgment call the exam likes most. Give all issues in a single detailed message when the problems interact — if fixing the retry logic changes how the timeout should behave, fixing them one at a time makes each fix invalidate the last. Fix sequentially when the problems are independent, because smaller focused messages produce more reliable, easier-to-verify changes and you can stop early if one fix reveals something new.
The unifying principle: reduce ambiguity per round trip. Examples, tests, and questions are all ways of making the next iteration's feedback specific.
Exam guide, verbatim — what is measured
Knowledge of
- Concrete input/output examples as the most effective way to communicate expected transformations when prose descriptions are interpreted inconsistently
- Test-driven iteration: writing test suites first, then iterating by sharing test failures to guide progressive improvement
- The interview pattern: having Claude ask questions to surface considerations the developer may not have anticipated before implementing
- When to provide all issues in a single message (interacting problems) versus fixing them sequentially (independent problems)
Skills in
- Providing 2-3 concrete input/output examples to clarify transformation requirements when natural language descriptions produce inconsistent results
- Writing test suites covering expected behavior, edge cases, and performance requirements before implementation, then iterating by sharing test failures
- Using the interview pattern to surface design considerations (e.g., cache invalidation strategies, failure modes) before implementing solutions in unfamiliar domains
- Providing specific test cases with example input and expected output to fix edge case handling (e.g., null values in migration scripts)
- Addressing multiple interacting issues in a single detailed message when fixes interact, versus sequential iteration for independent issues
Integrate Claude Code into CI/CD pipelines
What you need to know
- Use
-p(--print) so Claude Code runs non-interactively and the CI job never hangs waiting for input. -
--output-format jsonplus--json-schemaproduce machine-parseable findings a pipeline can post as inline PR comments. - CLAUDE.md is how a CI-invoked run gets testing standards, fixture conventions and review criteria.
- An independent review instance beats the session that wrote the code, which is biased toward its own assumptions.
- Feed prior review findings back in and ask for only new or still-unaddressed issues, so re-runs do not duplicate comments.
- Provide the existing test files so generated tests do not duplicate scenarios already covered.
Show the full non-interactive review loop: what context goes in (CLAUDE.md, diff, existing tests, prior findings), which flags shape the output, and how structured findings become inline PR comments without duplicates.
Click a context input to see what noise problem it prevents.
Explain why the session that generated the code is a weaker reviewer than a fresh instance that sees only the diff and the project standards.
Worked examples
Automated PR review step in CI
Scenario 5 · Claude Code for Continuous IntegrationThe review job runs Claude Code with -p so it cannot block on input, and with --output-format json --json-schema so the result is validated structured data. A following step iterates the findings array and posts each one as an inline comment on the exact file and line.
Note what is deliberately not in this job: it is a separate invocation from anything that generated code, so the reviewer has no stake in the implementation. And the review criteria are not inlined in the prompt — they live in CLAUDE.md, where the team maintains them under review.
yaml .github/workflows/claude-review.yml — illustrative excerpt, not a quoted CLI specification
- name: Claude review
run: |
git diff origin/${{ github.base_ref }}...HEAD > /tmp/diff.patch
claude -p "Review the diff in /tmp/diff.patch against the review criteria \
in CLAUDE.md. Report only actionable defects with file and line." \
--output-format json \
--json-schema .claude/schemas/review-findings.json \
> findings.json
- name: Post inline comments
run: node scripts/post-inline-comments.js findings.jsonA schema that makes findings postable
Scenario 5 · Claude Code for Continuous IntegrationWithout a schema, one run returns { "issues": [...] } and the next returns markdown prose, and the posting script breaks. --json-schema fixes the shape so the pipeline can rely on it, and constraining severity to an enum lets the job fail the build only on high-severity findings — a direct lever on false-positive noise.
json An example findings schema — the file name and path are arbitrary
{
"type": "object",
"required": ["findings"],
"properties": {
"findings": {
"type": "array",
"items": {
"type": "object",
"required": ["file", "line", "severity", "message"],
"properties": {
"file": { "type": "string" },
"line": { "type": "integer", "minimum": 1 },
"severity": { "enum": ["high", "medium", "low"] },
"message": { "type": "string" },
"isNew": { "type": "boolean" }
},
"additionalProperties": false
}
}
}
}Re-running the review after new commits, and generating tests that add value
Scenario 5 · Claude Code for Continuous IntegrationTwo noise problems, two context fixes.
Duplicate comments. On the second push the job passes the previous findings.json back in and instructs Claude to report only issues that are new or still unaddressed. Resolved findings disappear from the thread instead of being restated.
Low-value tests. The test-generation job supplies the existing test files so Claude can see which scenarios are already covered, and relies on CLAUDE.md for what the team considers a valuable test and which fixtures exist. Without this, the job reliably produces getter tests and hand-rolled fixture objects that duplicate tests/fixtures/.
bash Both jobs are non-interactive and context-fed — illustrative invocations
# Re-review: pass prior findings so nothing is reported twice
claude -p "Prior findings are in prior-findings.json. Review the current diff \
and report ONLY new or still-unaddressed issues." \
--output-format json --json-schema .claude/schemas/review-findings.json \
> findings.json
# Test generation: existing tests in context, standards from CLAUDE.md
claude -p "Generate tests for the changed files. Existing suites are in tests/. \
Do not duplicate covered scenarios. Follow the testing standards and use the \
fixtures documented in CLAUDE.md." \
--output-format json --json-schema .claude/schemas/test-plan.jsonAnti-patterns
- Invoking Claude Code in CI without
-p/--printbecause the interactive session waits for input the runner can never provide and the job hangs until it times out. - Parsing free-form prose output with regular expressions instead of using
--output-format jsonwith--json-schemabecause the shape drifts between runs and the posting step breaks silently. - Asking the same session that generated the code to review it instead of using an independent review instance because it shares the assumptions that produced the defects.
- Re-running a review on each push without supplying prior findings because every unchanged issue is reported again and the duplicate comments train the team to ignore the bot.
How it is examined
- Any stem describing a CI job that "hangs" or "waits for input" is a
-p/--printitem — pick the flag, not a timeout increase or a retry. - When the requirement is inline PR comments at specific lines, the answer combines
--output-format jsonwith--json-schema; an option offering only one of the two is usually incomplete. - Low-value or duplicate generated tests point at context fixes — CLAUDE.md standards and fixtures, plus the existing test files — not at a different model or a longer prompt.
- If the stem sets up "the session that wrote the code should also review it", that is the distractor: session context isolation says use an independent instance.
Why this is true
Running Claude Code in a pipeline changes three things: there is no human to answer prompts, the output must be parsed by a machine, and the session has no accumulated project knowledge unless you give it some.
Surface by surface
| What the pipeline is missing | The mechanism | What it produces |
|---|---|---|
| Nobody is there to answer a prompt | the -p (or --print) flag |
a non-interactive run that takes the prompt, produces output and exits — the flag that prevents a CI job from hanging, and the single most-tested fact in this task statement |
| A machine, not a reader, consumes the findings | --output-format json with --json-schema |
structured output under an enforced schema — file, line, severity, message — that a pipeline step loops over and posts as inline pull-request comments at the right locations, instead of one generic paragraph |
| The run knows nothing about the project | CLAUDE.md, read straight from the checked-out repository |
testing standards, fixture conventions and review criteria on every invocation |
| Generated tests are trivial, or re-cover ground the suite already holds | the existing test files in context, plus CLAUDE.md on what makes a test valuable and which fixtures already exist |
tests that add coverage and reuse the team's fixtures, rather than getter tests and hand-rolled fixture objects |
| The reviewer helped write what it is reviewing | a separate invocation, never a continuation of the generating session | an independent review instance that sees only the diff and the standards |
| A re-run re-reports everything | the prior review findings in context, with an instruction to report only new or still-unaddressed issues | a PR thread that stays readable across ten pushes |
What matters for the exam is that the two output flags exist and are used together. The way a schema is handed to --json-schema in the snippets below — a path to a schema file — is written as an illustration, not as a quoted argument specification.
This is the CLI/CI layer. At the API layer the equivalent mechanism is tool use with a JSON input_schema (Domain 4, task statement 4.3), which is described there as the most reliable way to guarantee schema-compliant output. Same goal — a shape the caller can rely on — enforced at two different layers, so read the stem for which one it is asking about.
Session context isolation
A subtle but heavily tested point: the same session that generated code is less effective at reviewing its own changes than an independent review instance. The generating session carries the assumptions and justifications that produced the code, so it is primed to consider them correct. A fresh instance judges the diff on its merits, which is why the review step is its own job in the pipeline.
Noise is a context problem, not a model problem
Two of those rows are the same move made twice: hand the run the context that lets it stay quiet. Undocumented fixtures produce hand-rolled objects and trivial assertions. Missing prior findings produce a thread of repeats. Either way the team learns to ignore the bot, and that is the real cost.
Exam guide, verbatim — what is measured
Knowledge of
- The -p (or --print) flag for running Claude Code in non-interactive mode in automated pipelines
- --output-format json and --json-schema CLI flags for enforcing structured output in CI contexts
- CLAUDE.md as the mechanism for providing project context (testing standards, fixture conventions, review criteria) to CI-invoked Claude Code
- Session context isolation: why the same Claude session that generated code is less effective at reviewing its own changes compared to an independent review instance
Skills in
- Running Claude Code in CI with the -p flag to prevent interactive input hangs
- Using --output-format json with --json-schema to produce machine-parseable structured findings for automated posting as inline PR comments
- Including prior review findings in context when re-running reviews after new commits, instructing Claude to report only new or still-unaddressed issues to avoid duplicate comments
- Providing existing test files in context so test generation avoids suggesting duplicate scenarios already covered by the test suite
- Documenting testing standards, valuable test criteria, and available fixtures in CLAUDE.md to improve test generation quality and reduce low-value test output