Domains
D2 · Claude Code Configuration and Workflows
The CLAUDE.md hierarchy, settings.json scopes and permissions, hooks, Skills, slash commands, subagents, plan mode, headless/CI usage, multi-pass review, team conventions, and MCP configuration.
This domain is worth roughly 12 of 60 items and maps to the Code-Generation and CI/CD scenarios. It tests whether you can configure Claude Code correctly for an individual and, crucially, for a team: where context lives, how settings and permissions resolve, when to enforce with hooks versus guide with prompts, and how to run Claude Code headlessly in CI. The recurring theme is precedence and the right mechanism for the right job.
Learning objectives
By the end of this page you should be able to:
- Order the CLAUDE.md hierarchy and decide what belongs in each level.
- Resolve settings.json scopes and permissions (allow / deny / ask) precedence.
- Configure hooks for every event, use exit code 2 to block, and read/write JSON on stdin/stdout.
- Choose among Skill, CLAUDE.md, slash command, subagent and MCP for a given need.
- Write custom slash commands with
$ARGUMENTSand define subagents with tool allowlists and per-agent models. - Decide plan mode vs direct execution and run Claude Code headlessly in CI with the right flags and exit-code handling.
- Design team-scale conventions: checked-in project settings, managed policies, MCP config scopes, and cost control.
2.1 The CLAUDE.md hierarchy
CLAUDE.md files inject persistent project context into every session. They compose from broad to narrow, with more specific files layering on top.
Managed policy (enterprise, admin-controlled) ← highest authority, cannot be overridden ▼User ~/.claude/CLAUDE.md ← your personal defaults across all projects ▼Project ./CLAUDE.md (checked into git) ← shared team context for this repo ▼Subdirectory ./packages/x/CLAUDE.md ← context specific to a part of the repoCLAUDE.local.md is a git-ignored personal file for project-specific notes you do not want to share. Use @path/to/file to import other files (e.g., @docs/architecture.md) so context stays modular and DRY.
| Level | Scope | Put here | Do NOT put |
|---|---|---|---|
| Managed policy | Whole org | Mandatory standards, forbidden actions | Personal preferences |
User ~/.claude/CLAUDE.md | All your projects | Your coding style, shell preferences | Team conventions |
Project ./CLAUDE.md | This repo (shared) | Build/test commands, architecture, conventions | Secrets, personal notes |
| Subdirectory | A package/module | Module-specific commands and quirks | Repo-wide rules |
CLAUDE.local.md | You, this repo | Scratch notes, local paths | Anything the team needs |
Keep it concise
CLAUDE.md is loaded into context every session – it costs tokens on every turn. Keep it tight and high-signal; move long reference material into @imported files that are pulled in only when relevant. Never put secrets in CLAUDE.md (it is often checked in). Bloated CLAUDE.md files degrade both cost and instruction-following.
Exam signal
“A rule every team member must follow” → project CLAUDE.md (checked in) or a managed policy if it is mandatory. “My personal preference” → user or CLAUDE.local.md. “It must not be shared / must not be committed” → CLAUDE.local.md.
2.2 settings.json scopes and precedence
settings.json configures permissions, hooks, environment and the model. Scopes resolve from most to least authoritative:
Managed policy settings (admin, cannot be overridden) ▼ overrides.claude/settings.local.json (personal, git-ignored) ▼ overrides.claude/settings.json (project, checked in) ▼ overrides~/.claude/settings.json (user, global default){ "model": "claude-opus-5", "permissions": { "allow": ["Read", "Edit", "Bash(npm test:*)", "Bash(git status)"], "deny": ["Bash(rm -rf:*)", "Read(./.env)", "Read(./secrets/**)"], "ask": ["Bash(git push:*)", "WebFetch"] }, "env": { "NODE_ENV": "test" }}Exam signal
Team-wide settings that must apply to everyone go in checked-in .claude/settings.json; mandatory, non-overridable rules go in managed policy. Personal overrides go in settings.local.json (git-ignored).
2.3 Permissions: allow / deny / ask
| Rule | Effect | Example |
|---|---|---|
allow | Auto-approved, no prompt | Bash(npm test:*), Read, Edit |
deny | Always blocked | Bash(rm -rf:*), Read(./.env) |
ask | Prompt the user each time | Bash(git push:*), WebFetch |
deny wins over allow. Patterns match tool name and arguments (e.g., Bash(git commit:*)). Prefer a narrow allowlist plus explicit denies for dangerous operations; use ask for actions that are usually fine but occasionally consequential.
2.4 Hooks
Hooks are deterministic shell (or HTTP) handlers that fire on lifecycle events. They receive event JSON on stdin and can emit JSON on stdout; exit code 2 blocks the action (and returns stderr to Claude), while exit code 0 allows it.
Events: PreToolUse, PostToolUse, UserPromptSubmit, Stop, SessionStart, Notification, SubagentStop, PreCompact.
{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [{ "type": "command", "command": "./.claude/hooks/guard.sh" }] } ] }}#!/usr/bin/env bash# .claude/hooks/guard.sh — reads tool call JSON on stdin, blocks destructive commands.input=$(cat)cmd=$(echo "$input" | jq -r '.tool_input.command // ""')if echo "$cmd" | grep -qE 'rm -rf|:(){ :|:& };:'; then echo "Blocked destructive command: $cmd" >&2 exit 2 # exit code 2 blocks the tool callfiexit 0#!/usr/bin/env bash# Block a git commit if the test suite fails. Deterministic — not a prompt instruction.input=$(cat)cmd=$(echo "$input" | jq -r '.tool_input.command // ""')if echo "$cmd" | grep -q 'git commit'; then if ! npm test --silent; then echo "Tests failing — commit blocked." >&2 exit 2 fifiexit 0#!/usr/bin/env bash# After Claude edits a file, auto-lint it and surface issues back to Claude.input=$(cat)file=$(echo "$input" | jq -r '.tool_input.file_path // ""')if [[ "$file" == *.ts || "$file" == *.tsx ]]; then npx eslint --fix "$file" 2>&1 || echo "Lint issues remain in $file" >&2fiexit 0Hooks, not prompts, for critical rules
This is anti-pattern 3 again. “Tell Claude in CLAUDE.md to always run tests” is probabilistic. A PreToolUse hook that exits 2 when tests fail is deterministic and unbypassable. Use hooks whenever the rule must always hold.
2.5 Skills, CLAUDE.md, slash commands, subagents, MCP – which one?
These five mechanisms overlap, and choosing correctly is heavily tested.
| Mechanism | What it is | Choose when |
|---|---|---|
| CLAUDE.md | Always-loaded project context | Facts/conventions every turn should know |
| Skill | SKILL.md loaded progressively on demand | Reusable capability with instructions/scripts, loaded only when relevant |
| Slash command | .claude/commands/*.md prompt template | A repeatable prompt you invoke explicitly (/review $ARGUMENTS) |
| Subagent | .claude/agents/*.md with isolated context | Delegating a sub-task to a separate context with its own tools/model |
| MCP | External server exposing tools/resources | Integrating an external system or shared capability across clients |
Skills and progressive disclosure
A Skill lives in .claude/skills/<name>/SKILL.md with frontmatter (name, description) and optional bundled scripts. Claude reads the description to decide when the skill is relevant and loads the full body only then – progressive disclosure keeps context lean.
---name: pdf-invoice-extractordescription: Extract structured fields from PDF invoices. Use when the user asks to pull totals, dates, or line items from an invoice PDF.---
# PDF Invoice Extractor1. Read the PDF text layer.2. Extract fields into the JSON schema in ./schema.json.3. Validate and report any missing required fields.Exam signal
“Reusable capability, only needed sometimes, may bundle scripts” → Skill. “Must always be in context” → CLAUDE.md. “A prompt I trigger by name” → slash command. “Separate context/tools/model for a sub-task” → subagent. “External system or cross-client capability” → MCP.
2.6 Custom slash commands
A file .claude/commands/review.md becomes /review. $ARGUMENTS is substituted with whatever follows the command.
---description: Review a pull request for security and style issues.---Review the changes in PR #$ARGUMENTS. Check for injection risks, missing inputvalidation, and deviations from ./CLAUDE.md conventions. Output a table offindings with severity.Invoke as /review 482. Commands can be project (.claude/commands/) or user (~/.claude/commands/) scoped.
2.7 Subagents
A subagent is defined in .claude/agents/<name>.md with its own system prompt, tool allowlist and model. It runs in an isolated context window, protecting the main conversation from noise.
---name: security-reviewerdescription: Reviews diffs for security vulnerabilities. Use proactively before merges.tools: Read, Grep, Bash(git diff:*)model: claude-opus-5---You are a security reviewer. Examine the diff for injection, authz gaps, secretleakage and unsafe deserialisation. Report findings with severity and file:line.Do not modify code.Key design points: give each subagent a narrow tool allowlist (least privilege), pick a model per agent (a cheap Haiku classifier, an Opus reviewer), and remember its context is isolated – the parent must pass context explicitly (same rule as Domain 1).
2.8 Plan mode vs direct execution
Plan mode (Shift+Tab) makes Claude explore read-only and produce a plan before touching anything. Direct execution lets it edit and run immediately.
| Choose plan mode when | Choose direct execution when |
|---|---|
| Large or unfamiliar codebase change | Small, well-scoped, reversible edit |
| High-risk / irreversible operations | Routine local iteration |
| You want to review the approach first | You trust the change and want speed |
| Multi-file refactors | Single-file fix |
Exam signal
“Large PR”, “unfamiliar codebase”, “want to approve the approach first” → plan mode. A stem that has Claude editing production-adjacent code without review is usually the wrong answer.
2.9 Headless and CI usage
Run Claude Code non-interactively with claude -p (print mode). This is the CI/CD scenario.
# Headless review in CI, machine-readable output, tight tool allowlist, no prompts.claude -p "Review the diff in this PR for security issues and output JSON findings." \ --output-format json \ --allowedTools "Read,Grep,Bash(git diff:*)" \ --permission-mode acceptEdits
echo "exit code: $?" # 0 success; non-zero for failures — gate the pipeline on it| Flag | Purpose |
|---|---|
-p "…" | Print (headless) mode with a prompt |
--output-format json | Single JSON result object (parse in CI) |
--output-format stream-json | Streaming JSON events (long tasks, progress) |
--allowedTools | Restrict tools for the run (least privilege in CI) |
--permission-mode | e.g. acceptEdits, plan, bypassPermissions – control prompting |
Gate the pipeline on the exit code; parse the JSON for structured findings. Keep the tool allowlist minimal in CI so an injected instruction cannot run arbitrary commands.
2.10 Multi-pass code review for large PRs
Large PRs overflow a single review pass. Split the work:
-
Partition the diff by file or module so each pass fits comfortably in context.
-
Review each partition in its own pass (or subagent) with a focused prompt, emitting structured findings.
-
Aggregate findings, deduplicate, and rank by severity in a final synthesis pass.
This mirrors orchestrator-workers: independent partitions reviewed in isolated contexts, then aggregated. It also keeps each context small enough that quality does not degrade.
2.11 Team-scale conventions
| Concern | Team-scale answer |
|---|---|
| Shared context | ./CLAUDE.md checked into git |
| Shared permissions/hooks | .claude/settings.json checked in |
| Mandatory, non-overridable rules | Managed policy settings/CLAUDE.md |
| Shared MCP servers | .mcp.json at project root (checked in) |
| Personal overrides | settings.local.json, CLAUDE.local.md (git-ignored) |
| Cost control | Model per subagent, /cost monitoring, cheaper models for simple agents |
MCP configuration scopes
| Scope | File / command | Visible to |
|---|---|---|
| Project | .mcp.json (checked in) | The whole team, this repo |
| User | claude mcp add --scope user … | All your projects |
| Local | claude mcp add (default local) | Only you, this project |
Agent teams, dynamic workflows, routines
Claude Code supports agent teams (multiple coordinated subagents), dynamic workflows (runtime-composed steps) and routines (saved multi-step procedures). Position them as higher-level orchestration built on the primitives above; on the exam, prefer the simplest one that solves the stated problem.
Cost control
Use /cost to inspect spend, choose a cheaper model per subagent where quality allows (Haiku for classification, Sonnet for balanced work, Opus for hard coding), and keep CLAUDE.md concise to reduce per-turn tokens. Prompt caching applies to the stable CLAUDE.md/tools prefix.
2.12 A complete, worked team configuration
The exam rewards knowing exactly which file holds which setting. Here is a coherent, checked-in project layout for the Code-Generation scenario, followed by the reasoning for each placement.
repo/├── CLAUDE.md # shared: build/test cmds, architecture, conventions (+ @imports)├── CLAUDE.local.md # git-ignored: personal scratch notes, local paths├── .mcp.json # shared: project-scope MCP servers└── .claude/ ├── settings.json # shared: permissions, hooks, model, env ├── settings.local.json # git-ignored: personal overrides ├── agents/ │ └── security-reviewer.md # subagent: isolated context, tool allowlist, model ├── commands/ │ └── review.md # /review $ARGUMENTS ├── skills/ │ └── release-notes/SKILL.md # progressive-disclosure capability └── hooks/ └── guard.sh # PreToolUse guard (exit 2 blocks)Worked CLAUDE.md (concise, imports for bulk):
# Payments ServiceBuild: `pnpm build` · Test: `pnpm test` · Lint: `pnpm lint`Never touch `migrations/` without a reviewed plan.Architecture and coding conventions: @docs/architecture.mdNever put secrets here; use the secret manager. See @docs/security.mdWorked .claude/settings.json:
{ "model": "claude-sonnet-5", "permissions": { "allow": ["Read", "Edit", "Bash(pnpm test:*)", "Bash(pnpm lint:*)", "Bash(git status)"], "deny": ["Bash(rm -rf:*)", "Read(./.env)", "Read(./secrets/**)"], "ask": ["Bash(git push:*)", "WebFetch"] }, "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [{ "type": "command", "command": "./.claude/hooks/guard.sh" }] } ], "PostToolUse": [ { "matcher": "Edit", "hooks": [{ "type": "command", "command": "./.claude/hooks/lint.sh" }] } ] }, "env": { "NODE_ENV": "test" }}| Requirement | Correct home | Why not elsewhere |
|---|---|---|
| Build/test commands everyone needs | Project CLAUDE.md | User file is per-person; local file is git-ignored |
| Mandatory, non-overridable org rule | Managed policy | Project settings can be overridden locally |
| Block a destructive command deterministically | PreToolUse hook (exit 2) | CLAUDE.md prose is probabilistic (#3) |
| Personal machine paths | CLAUDE.local.md | Must not be shared/committed |
| Shared MCP server | Project .mcp.json | User scope is per-person |
| Secrets | Secret manager / env | CLAUDE.md and settings are checked in |
Exam signal
When a stem asks “where should X live”, map X to two axes: shared vs personal (checked-in vs git-ignored) and advisory vs mandatory (CLAUDE.md/prompt vs hook/managed policy). The intersection is the answer.
2.13 Hook events in depth and exit-code semantics
Every hook receives event JSON on stdin; exit code 2 blocks (stderr is returned to Claude), exit 0 allows, and other non-zero codes surface an error without necessarily blocking. Matching the event to the goal is tested directly.
| Event | Fires | Use it to |
|---|---|---|
PreToolUse | Before a tool runs | Block (exit 2) dangerous/unauthorised actions before they happen |
PostToolUse | After a tool runs | React: lint an edited file, run a formatter, log |
UserPromptSubmit | When the user submits a prompt | Inject context, redact secrets, add guardrails to the prompt |
SessionStart | Session begins | Seed context, print environment info |
Stop | Main agent finishes | Final checks, cleanup, notifications |
SubagentStop | A subagent finishes | Validate/aggregate a subagent’s result |
PreCompact | Before compaction | Persist anything that must survive to durable state |
Notification | Claude Code sends a notification | Route to Slack/desk alerts |
#!/usr/bin/env bash# PreCompact hook: persist the running decision log before the window is compacted.input=$(cat)echo "$input" | jq -r '.transcript_summary // ""' >> ./.claude/decision-log.mdexit 0Block before, react after
To prevent an action you must use PreToolUse with exit 2 — a PostToolUse hook fires only after the action already happened. Swapping these is a classic distractor.
2.14 Headless output formats and exit-code gating in CI
claude -p supports two machine-readable output formats. Choosing correctly matters for CI design.
--output-format | Shape | Use when |
|---|---|---|
json | One result object at the end | Short tasks; parse a single findings object and gate on exit code |
stream-json | A stream of JSON events | Long tasks; show progress, consume incrementally |
text (default) | Prose | Human reading only — not for CI gating |
set -euo pipefailresult=$(claude -p "Review the diff for security issues; output JSON {findings:[{severity,file,line,note}]}." \ --output-format json \ --allowedTools "Read,Grep,Bash(git diff:*)")# Fail the build if any high-severity finding exists.echo "$result" | jq -e '.findings | map(select(.severity=="high")) | length == 0' >/dev/null \ || { echo "High-severity findings — failing build."; exit 1; }Gate the pipeline on both the process exit code and the parsed structured findings; never grep prose.
Common misconceptions
| Misconception | Reality | Why it matters on the exam |
|---|---|---|
| “CLAUDE.md can enforce a rule.” | CLAUDE.md is advisory context; enforcement needs a hook or managed policy. | Hooks-vs-prompt (#3) is tested repeatedly. |
| “Project settings always win.” | Managed policy overrides everything and cannot be overridden. | Precedence items hinge on managed policy being top. |
“allow and deny are symmetric.” | deny always beats allow. | Conflict-resolution items. |
| “A PostToolUse hook can block an action.” | Only PreToolUse (exit 2) blocks before the action; PostToolUse reacts after. | Event-selection distractor. |
| “Skills are always loaded.” | Skills load progressively via their description; only always-on context belongs in CLAUDE.md. | Mechanism-choice items. |
| “Bigger CLAUDE.md = more capable.” | CLAUDE.md costs tokens every turn; bloat raises cost and hurts instruction-following. | Cost-control items. |
“bypassPermissions is fine in CI if the repo is trusted.” | It removes safety; a minimal --allowedTools allowlist is the correct CI posture. | CI least-privilege items. |
| “A slash command and a subagent are interchangeable.” | A slash command is an invoked prompt template; a subagent is an isolated context with its own tools/model. | Mechanism-choice distractor. |
Scenario walkthrough — standardising a team on Claude Code safely
Situation. A 40-engineer org adopts Claude Code. Security mandates that production secret files are never readable and that rm -rf is never run — for everyone, with no local override. The platform team wants shared build/test commands and architecture conventions available to all, a way to block commits when tests fail, a repeatable PR-review command, and a diff-review helper that can never edit or push. One engineer wants personal notes that stay off the shared repo. CI must review PRs headlessly and fail builds on high-severity issues without being hijacked by malicious diff content.
Expert reasoning trace.
-
Non-overridable security rules → managed policy. “For everyone, no override” is the definition of managed policy; put
denyrules forRead(./secrets/**)andBash(rm -rf:*)there (and back the destructive-command block with a managed PreToolUse hook exiting 2). Rejectsettings.local.json(per-user, overridable) and CLAUDE.md prose (#3). -
Shared conventions → checked-in project
CLAUDE.md, kept concise with@importfor bulk. Reject the user file (per-person) andCLAUDE.local.md(git-ignored). -
Tests-before-commit → PreToolUse hook on the commit that runs tests and exits 2. Reject a CLAUDE.md instruction (probabilistic) and a slash command (opt-in).
-
Repeatable review → slash command
.claude/commands/review.mdwith$ARGUMENTS. Reject a subagent (that is for isolated delegated contexts, not an on-demand named prompt). -
Diff-reviewer that cannot edit/push → subagent with a least-privilege allowlist (
Read, Grep, Bash(git diff:*)). Reject “tell it in the prompt” (#3-style, bypassable). -
Personal notes → git-ignored
CLAUDE.local.md. -
Headless CI →
claude -p --output-format jsonwith a minimal--allowedTools, gate on exit code + parsed findings, neverbypassPermissions, so an injected instruction in the diff cannot run arbitrary shell.
Exam-correct decision: managed policy + checked-in CLAUDE.md/settings + PreToolUse hooks + slash command + least-privilege subagent + local file for personal notes + headless JSON with a tight allowlist. Every rejected option is a mechanism used for the wrong job — the exact shape of D2 distractors.
Exam traps in this domain
| Trap | Why it is wrong |
|---|---|
Put a team-wide rule in CLAUDE.local.md | It is git-ignored and personal; use project CLAUDE.md or managed policy |
| Enforce “run tests before commit” via CLAUDE.md text | Probabilistic; use a PreToolUse hook that exits 2 |
| Put secrets in CLAUDE.md | It is usually checked in; use env/secret manager |
| Give a subagent every tool | Violates least privilege; scope the allowlist |
| Use direct execution for a large, unfamiliar refactor | Use plan mode to review the approach first |
| Rely on exit code 0 always in CI | Gate the pipeline on the real exit code; non-zero must fail |
Use bypassPermissions broadly in CI | Removes safety; use a minimal --allowedTools allowlist |
| Make a Skill for something needed every turn | Always-needed context belongs in CLAUDE.md |
| Configure a shared MCP server at user scope for a team repo | Team-shared servers go in project .mcp.json |
| Review a huge PR in one pass | Overflows context; partition and aggregate (multi-pass) |
| Use a PostToolUse hook to block an action | Only PreToolUse (exit 2) blocks before the action |
Use --output-format text and grep it in CI | Use json/stream-json and gate on exit code + parsed findings |
| Put a mandatory rule in checked-in project settings | Project settings are locally overridable; use managed policy |
| Use a subagent when you wanted an invoked-by-name prompt | That is a slash command with $ARGUMENTS |
Store credentials in .claude/settings.json | It is checked in; use env/secret manager |
Practice questions
Q1 · A team wants every engineer working in a repo to know the build and test commands and the architecture conventions. Where should this live? (Select one)
A. Each engineer’s ~/.claude/CLAUDE.md.
B. The project ./CLAUDE.md, checked into git.
C. CLAUDE.local.md.
D. The system prompt of every session, typed manually.
Answer: B. Shared, repo-specific context belongs in the checked-in project CLAUDE.md. User files (A) are per-person, CLAUDE.local.md (C) is git-ignored and personal, and manual entry (D) does not scale.
Q2 · A policy states production database credentials must never be readable by Claude Code, for everyone, with no override. What is the correct mechanism? (Select one)
A. A note in project CLAUDE.md asking Claude not to read them.
B. A managed-policy settings deny rule (e.g. Read(./secrets/**)), since managed policy cannot be overridden.
C. A settings.local.json deny rule.
D. An ask permission so the user confirms each read.
Answer: B. Mandatory, non-overridable rules belong in managed policy, and deny wins over allow. A CLAUDE.md note (A) is probabilistic. settings.local.json (C) is per-user and overridable. ask (D) still permits reads.
Q3 · Which mechanism guarantees a git commit is blocked when the test suite fails? (Select one)
A. A CLAUDE.md instruction to always run tests first. B. A PreToolUse hook matching the commit command that runs the tests and exits 2 on failure. C. A slash command that runs tests. D. Asking Claude to remember to test.
Answer: B. Exit code 2 from a PreToolUse hook deterministically blocks the action. All prompt-based options (A, D) are probabilistic; a slash command (C) is opt-in and does not block commits.
Q4 · A capability is only needed occasionally, bundles a helper script, and should not bloat every session's context. Which mechanism fits BEST? (Select one)
A. Add it to project CLAUDE.md.
B. A Skill (SKILL.md) loaded via progressive disclosure when its description matches.
C. A managed policy.
D. A deny permission rule.
Answer: B. Skills load progressively based on their description, keeping context lean and allowing bundled scripts. CLAUDE.md (A) is always loaded. Managed policy (C) and deny rules (D) are unrelated to capabilities.
Q5 · A subagent that reviews diffs should never be able to edit files or push. How do you enforce this? (Select one)
A. Tell it in its system prompt not to edit.
B. Define the subagent with a tool allowlist that excludes Edit and any push command (e.g. tools: Read, Grep, Bash(git diff:*)).
C. Give it all tools and rely on it behaving.
D. Run it in plan mode manually each time.
Answer: B. Least privilege via the subagent’s tool allowlist is deterministic. A prompt (A) is bypassable, all-tools (C) violates least privilege, and manual plan mode (D) is not enforcement.
Q6 · An engineer must make a large, multi-file refactor in an unfamiliar service. What is the BEST first step in Claude Code? (Select one)
A. Direct execution to move fast. B. Plan mode: read-only exploration and a reviewable plan before any edits. C. Delete the tests to avoid blockers. D. Increase max_tokens.
Answer: B. Large, unfamiliar, multi-file work is exactly when plan mode’s read-only exploration and up-front plan reduce risk. Direct execution (A) skips review; C is destructive; D is irrelevant.
Q7 · A CI job runs Claude Code to review PRs and must fail the build on problems and produce machine-readable output. Which invocation is correct? (Select one)
A. claude interactive, then copy the result manually.
B. claude -p "…" --output-format json --allowedTools "Read,Grep,Bash(git diff:*)" and gate the pipeline on the exit code, parsing the JSON.
C. claude -p "…" --permission-mode bypassPermissions with all tools enabled.
D. claude -p "…" with no output format and grep the prose.
Answer: B. Headless print mode with JSON output, a minimal tool allowlist, and exit-code gating is the CI-correct pattern. Interactive (A) does not automate; bypassing permissions with all tools (C) is unsafe; grepping prose (D) is unreliable.
Q8 · Which TWO settings correctly implement least privilege for a headless CI review that only needs to read code and diffs? (Select two)
A. --allowedTools "Read,Grep,Bash(git diff:*)".
B. --permission-mode bypassPermissions.
C. A deny rule for Bash(rm -rf:*) and writes to protected paths.
D. Allow all Bash commands for flexibility.
E. Grant WebFetch and Edit just in case.
Answer: A and C. A narrow allowlist plus explicit denies on dangerous operations enforces least privilege. Bypassing permissions (B), allowing all Bash (D) and granting unneeded tools (E) all widen the blast radius.
Q9 · A 4,000-line PR must be reviewed but does not fit well in a single context. What is the BEST approach? (Select one)
A. Truncate the diff to the first 500 lines. B. Multi-pass review: partition by file/module, review each partition in its own pass or subagent, then aggregate and rank findings. C. Use one giant prompt with the whole diff and hope for the best. D. Skip review for large PRs.
Answer: B. Partition-review-aggregate keeps each context small and preserves quality. Truncation (A) misses code, one giant prompt (C) degrades quality, and skipping (D) is unacceptable.
Q10 · A team wants an MCP server available to everyone who clones the repo. Where should it be configured? (Select one)
A. Each user’s user-scope MCP config.
B. A checked-in project .mcp.json at the repo root.
C. settings.local.json.
D. Hard-coded in CLAUDE.md prose.
Answer: B. Project-scope .mcp.json checked into the repo makes the server available to the whole team. User scope (A) is per-person, local (C) is git-ignored, and CLAUDE.md prose (D) does not configure servers.
Q11 · To reduce cost in a multi-subagent Claude Code workflow without hurting quality, which TWO actions are appropriate? (Select two)
A. Assign Haiku 4.5 to a simple classification subagent and reserve Opus 5 for hard coding.
B. Put the entire company wiki into CLAUDE.md.
C. Keep CLAUDE.md concise and use @import for reference material loaded only when relevant.
D. Disable prompt caching.
E. Use Opus 5 for every subagent regardless of task.
Answer: A and C. Model-per-subagent and a concise, cache-friendly CLAUDE.md cut cost without hurting quality. Bloating CLAUDE.md (B) raises per-turn cost, disabling caching (D) raises cost, and Opus-everywhere (E) is wasteful.
Q13 · A team needs a linter to run automatically after Claude edits a file, and separately needs commits blocked when tests fail. Which hook events are correct for each? (Select one)
A. PostToolUse to block the commit; PreToolUse to lint. B. PreToolUse on the commit (run tests, exit 2 on failure) to block, and PostToolUse on Edit to lint the edited file. C. UserPromptSubmit for both. D. SessionStart to lint and Stop to run tests.
Answer: B. Blocking must happen before the action (PreToolUse, exit 2); linting reacts after the edit (PostToolUse). A swaps the events; C is a prompt-submit event unsuited to tool gating; D fires at session boundaries, not per-commit/per-edit.
Q14 · Managed policy sets the default model to Sonnet 5; a project `.claude/settings.json` sets Opus 5; a user file sets Haiku 4.5. Which wins? (Select one)
A. User (Haiku 4.5), because it is the most personal. B. Managed policy (Sonnet 5), because managed policy cannot be overridden. C. Project (Opus 5), because it is closest to the code. D. Whichever file was edited most recently.
Answer: B. Managed policy is the highest authority and overrides local, project and user. A and C invert the precedence; D is not how resolution works.
Q15 · A CI reviewer must emit machine-readable findings for a short task and fail the build on high-severity issues. Which output format and gating is correct? (Select one)
A. --output-format text, then grep for ‘HIGH’.
B. --output-format json, parse the findings, and fail on both a non-zero exit code and any high-severity finding.
C. --output-format stream-json and ignore the exit code.
D. Interactive mode with a human reading the output.
Answer: B. A single JSON result plus exit-code-and-findings gating is the CI-correct pattern for a short task. Grepping prose (A) is unreliable, ignoring the exit code (C) misses failures, and interactive mode (D) does not automate.
Q16 · Before compaction on a long Claude Code session, a running decision log must be preserved to durable storage. Which hook event fits BEST? (Select one)
A. PostToolUse. B. PreCompact — it fires before compaction, so the log can be written to durable state first. C. Notification. D. SessionStart.
Answer: B. PreCompact is exactly the hook for persisting anything that must survive compaction. PostToolUse (A) is per-tool, Notification (C) is for alerts, and SessionStart (D) fires at the wrong time.
Q17 · A team wants a shared internal-docs MCP server for everyone who clones the repo, while one engineer uses a personal MCP server only on their machine. Which configuration is correct for BOTH? (Select two)
A. The shared server in a checked-in project .mcp.json.
B. The shared server in each user’s user-scope config.
C. The personal server added at local scope (claude mcp add, default local).
D. The personal server in the checked-in .mcp.json.
E. Both hard-coded in CLAUDE.md prose.
Answer: A and C. Project .mcp.json shares with the team; local scope keeps a personal server to one machine. B makes the shared server per-person, D shares the personal one with everyone, and E (prose) does not configure servers.
Q18 · A stem proposes storing production database credentials in the checked-in `.claude/settings.json` `env` block so Claude Code can connect. What is the correct critique? (Select one)
A. It is fine because settings.json is local.
B. .claude/settings.json is checked into git, so it must never hold secrets; use the secret manager / environment injection and add a deny on reading secret paths.
C. Move the credentials to project CLAUDE.md instead.
D. Encrypt the credentials with base64 in settings.json.
Answer: B. Checked-in files must never carry secrets; use a secret manager and deny reads of secret paths. A is false (it is shared), CLAUDE.md (C) is also checked in, and base64 (D) is encoding, not protection.
Key takeaways
- CLAUDE.md composes managed policy → user → project → subdirectory; keep it concise, never store secrets, and use
@importfor modularity. - settings.json resolves managed policy → local → project → user;
denybeatsallow; useaskfor occasionally-consequential actions. - Hooks are deterministic: exit code 2 blocks, JSON on stdin/stdout, events cover the whole lifecycle. Use hooks (not prompts) for critical rules, and PreToolUse (not PostToolUse) to block.
- Choose the mechanism deliberately: CLAUDE.md (always-on context), Skill (progressive on-demand capability), slash command (invoked prompt), subagent (isolated context/tools/model), MCP (external integration).
- Subagents get least-privilege tool allowlists and a model per agent; plan mode for large/unfamiliar/risky work.
- Headless CI:
claude -pwith--output-format json(short) orstream-json(long), a minimal--allowedTools, and pipeline gating on the exit code and parsed findings — never grep prose. - Team scale: checked-in project settings and
.mcp.json, managed policy for mandatory rules,/costand per-subagent models for cost control, multi-pass review for large PRs. - Map every “where should X live” question to two axes — shared vs personal, advisory vs mandatory — to pick the correct file/mechanism.
- Never store secrets in any checked-in file (CLAUDE.md or settings.json); use a secret manager plus
denyrules on secret paths.
Last updated Sep 18, 2026