Skip to content
claude-certified-architect

Domain 3 · 20% of the exam

Claude Code Configuration & Workflows

Covers CLAUDE.md hierarchy and loading, custom commands and skills, path-specific rules, plan mode vs direct execution, iterative refinement, and CI/CD integration.


3.0 Surfaces: Where Claude Code Runs

Claude Code is no longer just a CLI. Every surface connects to the same engine, so CLAUDE.md files, settings, skills, and MCP servers work identically across all of them — which is the architecturally relevant point: configuration is portable, and so is a session.

Surface What it is Install / entry point
Terminal Full-featured CLI curl -fsSL https://claude.ai/install.sh | bash, then claude
VS Code / Cursor Extension with inline diffs, @-mentions, plan review Extensions marketplace
JetBrains Plugin for IntelliJ, PyCharm, WebStorm (requires the CLI) JetBrains Marketplace
Desktop app Standalone app: visual diffs, parallel sessions, scheduled tasks, cloud sessions macOS / Windows download
Web Browser sessions with no local setup; long-running tasks on repos you don't have locally claude.ai/code
Mobile iOS / Android app for the same cloud sessions Claude app

Session Portability

Goal Mechanism
Start locally, finish in the cloud claude --cloud "<task>" (--remote is a deprecated alias)
Pull a web/cloud session into the terminal claude --teleport
Run a task as a local background session claude --bg "<task>", then claude agents / claude attach <id> / logs / stop / respawn / rm
Copy the current session into a background session /fork [prompt] (a forked subagent that reports back is /subtask; /branch switches you into a copy)
Hand the current terminal session to the desktop app /desktop
Drive a running local session from a phone or another browser — or fork it from the Claude app into a local background session (v2.1.273+) Remote Control
Push external events (Telegram, Discord, iMessage, webhooks) into a session Channels
Route work from team chat @Claude in Slack

Scheduling

Three distinct mechanisms — the exam-relevant distinction is where they run:

Mechanism Runs Use for
Routines (/schedule, web, or desktop) In the cloud — keeps running with your machine off; can also trigger on API calls or GitHub events Morning PR reviews, overnight CI failure analysis, weekly dependency audits
Desktop scheduled tasks On your machine, with local file and tool access Anything that needs the local filesystem or private network
/loop Inside the current CLI session Quick polling within one sitting — omit the interval and Claude self-paces between iterations

3.1 CLAUDE.md Hierarchy

What is CLAUDE.md?

CLAUDE.md files are instruction files that tell Claude Code how to behave in a specific context. They're like .editorconfig or .eslintrc but for an AI agent — defining coding standards, project conventions, tool restrictions, and workflow rules.

Loading Order (Broader → More Specific)

Claude Code loads CLAUDE.md files in a hierarchy. Every file it finds is concatenated into context, not overridden: content runs from the filesystem root down to the working directory, so instructions closer to where you launched Claude are read last, and CLAUDE.local.md follows CLAUDE.md within each directory. Two files that contradict each other leave Claude to pick one, so resolve conflicts rather than relying on precedence:

CLAUDE.md loading order from broader to more specific: managed policy, user, project, local project, directory.

Managed policy lives at /etc/claude-code/CLAUDE.md (Linux, WSL), /Library/Application Support/ClaudeCode/CLAUDE.md (macOS), or C:\Program Files\ClaudeCode\CLAUDE.md (Windows). A directory-level file such as ./src/api/CLAUDE.md or ./tests/CLAUDE.md loads when Claude reads, writes, or edits a file in that directory.

Key distinction: Project-level CLAUDE.md is committed to git and shared with the team. User-level is personal and local. CLAUDE.local.md is personal per project (gitignore it). Directory-level loads dynamically when Claude works in that directory — since v2.1.288 on Write and Edit as well as Read, and since v2.1.293 also when Claude views a single file there with a Bash read such as cat or head.

AGENTS.md Interop

Since v2.1.277, a project with no CLAUDE.md falls back to reading AGENTS.md (on every provider since v2.1.281). A CLAUDE.md, .claude/CLAUDE.md, or CLAUDE.local.md in the working directory or above it counts as having one — so adding a personal CLAUDE.local.md silently stops AGENTS.md loading; ~/.claude/CLAUDE.md, managed policy, and .claude/rules/ don't count. The "Project instructions" setting in /config takes four values: claude-md-or-agents-md (the default), claude-md-and-agents-md (both, each directory's CLAUDE.md first), claude-md, and managed-only. In a settings file it lives under pluginConfigs → cc-plugin-agents-md@builtin (renamed from agents-md@builtin in v2.1.285), read from user, --settings, or managed settings only. /init still reads AGENTS.md when scaffolding. If your repo already uses AGENTS.md for other coding agents and you also need Claude-specific rules, keep one source of truth by importing it:

# CLAUDE.md
@AGENTS.md

## Claude-specific overrides
Use plan mode for changes under `src/billing/`.

@import Syntax

CLAUDE.md files can import other files for modular configuration:

# Project Configuration

@docs/coding-standards.md
@docs/api-conventions.md
@~/.claude/my-personal-preferences.md

See @README.md for project overview.

Resolution rules:

  • Relative paths resolve relative to the file containing the import
  • @~/ resolves to the user's home directory
  • Maximum import depth: four hops (to prevent circular imports)
  • Imported files can themselves contain @imports (up to depth limit)

.claude/rules/ Directory

For topic-specific rules organized as separate files:

.claude/
  rules/
    testing.md       — Testing conventions
    api-design.md    — API endpoint patterns
    security.md      — Security requirements
    typescript.md    — TypeScript-specific rules

Without frontmatter: Rules load unconditionally at session start. With frontmatter: Rules load conditionally based on file paths — when Claude uses Read, Write, or Edit on a matching file (Write/Edit since v2.1.288), or views one with a single-file Bash read such as cat or head (v2.1.293).

Auto Memory

Claude Code maintains automatic memory at:

~/.claude/projects/<project>/memory/MEMORY.md
  • First 200 lines OR 25 KB (whichever comes first) loaded at session start
  • Machine-local (not version controlled)
  • All worktrees in the same git repo share one memory directory
  • Claude writes notes here automatically about project patterns, decisions, preferences
  • Requires Claude Code v2.1.59 or later
  • autoMemoryEnabled: false disables it; autoMemoryDirectory relocates it
  • Topic files (e.g., debugging.md, api-conventions.md) alongside MEMORY.md are loaded on demand — the 200-line cap applies only to MEMORY.md itself
  • Current layout: MEMORY.md is an index (one line per memory) and each memory is its own file with YAML frontmatter — name, description, and a type of user / feedback / project / reference; Claude Code stamps a modified timestamp on every write (v2.1.214+)
  • Subagents can maintain their own auto memory

Monorepo and Multi-Directory Controls

Setting / flag Purpose
claudeMdExcludes (in settings) Glob-list of CLAUDE.md files to skip — useful when another team's nested CLAUDE.md would otherwise load
--add-dir <path> Grant Claude access to additional working directories
CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 Also load CLAUDE.md / rules from --add-dir paths
CLAUDE_CODE_NEW_INIT=1 Interactive multi-phase /init that scaffolds CLAUDE.md, skills, and hooks
/doctor prompt-audit [path] (alias /checkup) Audit CLAUDE.md, CLAUDE.local.md, AGENTS.md, rules, skills, commands, subagents, and output styles for instructions written for older models, dead references, and contradictions; proposes edits and changes nothing until you agree (v2.1.283+)

3.2 Skills (and Legacy Slash Commands)

Major change (2026): Custom slash commands have been merged into skills. A file at .claude/commands/deploy.md and a skill at .claude/skills/deploy/SKILL.md both create /deploy and behave the same way. The old /project:name and /user:name namespacing is gone — commands are just /name, and higher-priority locations win when names collide.

Skill Locations (Priority: Enterprise > Personal > Project > Plugin)

Location Path Applies to
Enterprise Managed settings path All users in the org
Personal ~/.claude/skills/<name>/SKILL.md All your projects
Project .claude/skills/<name>/SKILL.md This project only
Plugin <plugin>/skills/<name>/SKILL.md Where the plugin is enabled (namespaced plugin-name:skill-name)

Legacy .claude/commands/*.md still works and supports the same frontmatter — but skills add a directory for supporting files, dynamic context injection, and subagent execution. When a skill and a command share a name, the skill wins. Claude Code skills follow the open Agent Skills standard.

Example SKILL.md

---
name: deploy
description: Deploy the application to a specified environment
context: fork
agent: Explore
allowed-tools: Bash(git *) Bash(npm run deploy *)
argument-hint: [environment]
disable-model-invocation: true
---

# Deploy Skill

Deploy the application to $ARGUMENTS.

1. Run the test suite
2. Build the application
3. Push to the deployment target
4. Verify the deployment succeeded

Frontmatter Reference (Current)

Field Purpose
name /slash-command name (defaults to directory name; lowercase, digits, hyphens, max 64 chars)
description When to use the skill — Claude uses this to decide whether to auto-load. Capped at 1,536 chars combined with when_to_use
when_to_use Additional trigger phrases / example requests, appended to description
argument-hint Hint shown in autocomplete, e.g. [issue-number]
arguments Named positional arguments for $name substitution
disable-model-invocation true → only the user can invoke via /name; Claude can't auto-trigger
user-invocable false → hidden from / menu; Claude can still invoke (background knowledge)
allowed-tools Tools pre-approved for the turn that invokes the skill — the grant clears when you send your next message, and it still goes through the normal permission flow
model Model override for this skill's turn
effort low / medium / high / xhigh / max — effort-level override
context fork runs the skill in an isolated subagent
agent Which subagent type executes when context: fork (e.g. Explore, Plan, general-purpose)
hooks Hooks scoped to this skill's lifecycle
paths Glob patterns — auto-load only when working with matching files
shell bash (default) or powershell for inline command injection

Substitution Variables

Variable Resolves To
$ARGUMENTS Full argument string passed by the user
$ARGUMENTS[N] / $N 0-indexed positional argument ($0, $1, …)
$name Named argument declared in arguments: frontmatter
${CLAUDE_SESSION_ID} Current session identifier
${CLAUDE_SKILL_DIR} Directory containing the SKILL.md file

Dynamic Context Injection

Skills can preprocess shell output and file contents before Claude sees them:

---
name: pr-summary
description: Summarize changes in a pull request
context: fork
agent: Explore
allowed-tools: Bash(gh *)
---

## PR context
- Diff: !`gh pr diff`
- Comments: !`gh pr view --comments`
- Changed files: !`gh pr diff --name-only`

## Your task
Summarize this pull request...

!`cmd` runs the command before the skill body is sent. Multi-line blocks use ```!. File inclusion with @path also works. Disable globally with "disableSkillShellExecution": true.

Context Isolation (context: fork)

  • Spawns the skill as a subagent with its own context
  • The agent: field picks the execution environment (built-in Explore, Plan, general-purpose, or a custom .claude/agents/* subagent)
  • CLAUDE.md still loads; main conversation history does not
  • Useful for noisy operations (deep research, deployments) that would pollute the main context

Skill Lifecycle and Compaction

When invoked, a skill's rendered body enters the conversation as a single message and stays there. Claude Code does not re-read the file on later turns — write standing instructions, not one-time steps. Auto-compaction re-attaches the most recently invoked skills (first 5 000 tokens of each, 25 000-token combined budget), dropping older ones if you used many.

Bundled Skills

Claude Code ships with a set of bundled skills that varies by release. Recent versions include:

  • /claude-api — Build and migrate Claude API / Anthropic SDK apps; subcommands migrate, prompt-audit, upgrade (Python SDK 0.x → 1.x), cost-optimize, preserved-thinking-migration (find and fix the history edits a harness makes), build-eval / hillclimb, managed-agents-onboard
  • /code-review — Multi-agent review of pending changes or a PR (ultra runs it in the cloud; /ultrareview is the legacy alias)
  • /diff — Review the working-tree changes, including Claude's edits, before shipping
  • /security-review — Security review of the pending changes on the branch
  • /simplify — Reuse / simplification / efficiency cleanups on changed code
  • /dataviz — Charts and dashboards with consistent design
  • /design — Multi-artboard visual design canvas
  • /init — Scaffold a CLAUDE.md for the codebase
  • /run — Launch the project's app to confirm a change works
  • /verify — Build and run the app to confirm a change does what it should, rather than trusting tests or type checks; runs only when invoked, and records its recipe as a project skill at .claude/skills/verify/
  • /run-skill-generator — Record how to build and launch the project as a per-project skill that /run and /verify then follow
  • /loop — Run a prompt or slash command on a recurring interval
  • /schedule — Create and manage cloud routines
  • /deep-research — A bundled dynamic workflow: fan out web searches, cross-check sources, synthesize a cited report
  • /workflows / /workflow-authoring — Watch running workflows; load the script-writing reference (when dynamic workflows are enabled)
  • /advisor — Consult a second model (fable, opus, sonnet) at key moments of a task
  • /fast — Toggle fast mode (Opus 5.5 / Opus 5 / Opus 4.8; premium pricing — $8 / $40 on Opus 5.5, $10 / $50 on Opus 5 and 4.8 — same model, faster output; also honored in cloud and self-hosted remote sessions)
  • /update-config — Configure settings.json, hooks, and permissions
  • /fewer-permission-prompts — Build a permission allowlist from your usage
  • /output-style [name] — List and switch output styles, including in headless and Remote Control sessions (v2.1.269+)
  • /insights — Usage report; now estimates how many recent permission prompts auto mode could have handled
  • /skill-doctor — Show what each skill costs in context and how often it is used (v2.1.252+); every listed skill costs tokens on every turn
  • /doctor (alias /checkup) — Diagnose Claude Code setup problems; /doctor prompt-audit audits your instruction files instead (§3.1); /feedback sends a report with session context

Check /help in your installed version (or the commands page in the docs) for the current list — the set changes release to release.

Pre-commit checks (v2.1.286+): when a session starts with a project, personal, or enterprise skill named verify or simplify that Claude may invoke, Claude Code's commit instructions tell Claude to run it right before each commit (docs- and tests-only changes excepted). The bundled /verify and /simplify and plugin skills don't trigger it, and turning off includeGitInstructions removes it. It is the skill-level answer to "how do we make Claude check its work before every commit without a hook?"

Inside workflows: when an agent in a dynamic workflow invokes a forked skill, that agent waits for and receives the result (v2.1.295+); earlier releases could deliver it to the main conversation instead.

Plugins

A plugin is a distributable bundle — skills and commands, subagents, hooks, MCP and LSP servers, monitors, output styles and themes, default settings, and (since v2.1.287) mods — installed from a marketplace and enabled per project. Plugin-provided items are namespaced (plugin-name:skill-name for skills, plugin:<plugin>:<server> for MCP servers) so they can't collide with your own. Plugins sit at the lowest priority in the skill resolution order (Enterprise > Personal > Project > Plugin).

Plugins are also the unit that claude plugin eval tests: you write an eval suite against the plugin's skills and run it in a sandbox or in CI, and it emits a JSON report. That is the packaging answer to "how does a team ship and regression-test its Claude Code conventions?"

Mods are plugins whose JavaScript or TypeScript handlers Claude Code calls in its own process: they can watch, rewrite, or answer tool calls, prompts, turns, and commands, and draw panes in the interface. The docs now call the settings-file kind of hook a "settings hook" to tell the two apart. The exam-style choice:

Mod Settings hook Skill MCP server
What it is Functions in a plugin, run inside Claude Code A shell command, HTTP request, or prompt run on a lifecycle event A SKILL.md of instructions An external process that gives Claude tools
What it can change Tool calls, prompts, commands, turns, and the interface Whether a call or prompt goes ahead, its arguments and result, added context What Claude knows and does Which tools Claude has
Pick it when You need a pane, a custom command, or to rewrite an event You want to block, allow, or log an event with a script You keep pasting the same instructions Claude needs to reach an external system

Mods are on by default and aren't sandboxed — they run with the user's permissions, and processes they start run outside the Bash sandbox. disableAllHooks and --safe-mode turn off installed mods (not built-in ones); admins set allowManagedModsOnly under pluginConfigs → cc-plugin-sec-default@builtin in managed settings to stop user-installed mods running, and a mod can't approve a call a deny rule refuses unless allowModsToOverrideDenyRules is set.

Recent plugin tooling: claude plugin validate also checks a plugin's .mcp.json entries (servers that would be silently dropped, undeclared ${user_config.*} references, insecure URLs); --plugin-dir can point at a folder of plugins and picks up children added while running; claude plugin install <plugin> --marketplace <source> offers to add the marketplace on the way in; and skills and plugins enabled on your claude.ai account sync into terminal sessions signed in with it (syncClaudeAiSkills / syncClaudeAiPlugins: false opt out). Since v2.1.285, claude plugin install --config <server>.<key>=<value> sets a bundled server's options from the shell (install never prompts for userConfig), and /plugin configure <plugin>@<marketplace> reopens the configuration dialog.


3.3 Path-Specific Rules

Conditional Rule Loading

Rules in .claude/rules/ can specify which files they apply to using glob patterns in YAML frontmatter:

---
paths:
  - "src/api/**/*.ts"
  - "src/api/**/*.test.ts"
---

# API Development Rules

All API endpoints must:
- Use Zod for request validation
- Return standardized error responses
- Include rate limiting middleware
- Have corresponding integration tests
---
paths:
  - "**/*.test.tsx"
  - "**/*.test.ts"
  - "**/*.spec.ts"
---

# Testing Conventions

- Use React Testing Library, not Enzyme
- Test behavior, not implementation
- Mock external APIs, not internal modules
- Each test file must have a describe block matching the component/function name

When Path-Specific Rules Beat Directory CLAUDE.md

Scenario: Testing conventions that apply to test files scattered throughout the entire codebase.

Directory CLAUDE.md approach:

src/
  components/
    CLAUDE.md  ← Would need testing rules here
    Button.test.tsx
  api/
    CLAUDE.md  ← And here
    users.test.ts
  utils/
    CLAUDE.md  ← And here
    format.test.ts

Path-specific rules approach:

.claude/
  rules/
    testing.md  ← One file with paths: ["**/*.test.*"]

The rules approach is superior because:

  • Single source of truth for testing conventions
  • Applies everywhere test files exist, even new directories
  • No need to duplicate CLAUDE.md files across directories

3.4 Plan Mode vs Direct Execution

Permission Modes (Current)

Plan mode is now one entry in a broader permission-mode system. Start in a specific mode with --permission-mode <mode> or permissions.defaultMode, or cycle modes with Shift+Tab in an interactive session.

Which mode a session starts in (v2.1.283+): with nothing configured, interactive terminal and VS Code sessions start in auto on every plan and provider. claude -p and the Agent SDK start in default in sessions that fetch feature flags — but on a third-party provider or with telemetry off they start in auto (v2.1.285+), so pass --permission-mode default (SDK: permissionMode: 'default') when a script must get manual approvals. HIPAA-configured organizations and any settings file with disableAutoMode: "disable" start in default. If auto mode isn't available to the session, it falls back to default.

Mode Behavior
default Shown as Manual in the CLI and apps (manual is accepted as an alias): reads run without asking; edits, shell commands, and network access prompt
acceptEdits Auto-accept file edits; still prompt for other tools
plan Exploration-only: Claude designs an approach and presents it before touching files
auto A classifier decides per-tool whether to prompt — see claude auto-mode defaults. Since v2.1.278–282 the classifier runs server-side by default on the Claude API, Bedrock, Vertex, Foundry, and gateways (no classifier overhead billed; CLAUDE_CODE_AUTO_MODE_SERVER=0 opts out; /status shows which is active), and read-only or sandboxed commands also wait for its review
dontAsk Only file reads inside the working directories and pre-approved tools run; anything that would prompt is denied — locked-down CI with an exact --allowedTools list
bypassPermissions Skip all prompts (dangerous; use only for short, contained tasks)

When to Use Plan Mode

Indicator Example
Multi-file changes Refactoring auth across 15 files
Architectural decisions Choosing between REST and GraphQL
Multiple valid approaches Several ways to implement caching
Large scope Library migration affecting 45+ files
Unclear requirements "Make the app faster" — needs investigation first

In plan mode, Claude:

  1. Explores the codebase (Glob, Grep, Read)
  2. Identifies affected files and patterns
  3. Designs an approach
  4. Presents the plan for approval
  5. Only implements after user approval

When to Use Direct Execution

Indicator Example
Single-file fix Bug fix with clear stack trace
Obvious scope Adding a null check
Clear instructions "Add a createdAt field to the User model"
Small, contained Fixing a typo, updating a constant

Built-in Subagents

Four subagents ship with Claude Code and are registered by default in interactive sessions:

Agent Purpose Tools
Explore Fast file discovery and codebase search Read-only; skips CLAUDE.md and git status
Plan Research for plan mode before proposing changes Read-only; skips CLAUDE.md and git status
general-purpose Multi-step tasks needing exploration and action All subagent tools
claude Catch-all fallback All subagent tools

The Explore agent is the canonical context-preservation move:

An Explore subagent does the noisy reading with Glob, Grep and Read and returns a concise summary, so the main conversation stays clean.

Without it, a deep codebase exploration would fill the main context window with raw file contents and search results.

Custom Subagents (.claude/agents/)

Custom subagents are markdown files with YAML frontmatter, resolved in the order: managed settings > --agents CLI JSON > project (.claude/agents/) > user (~/.claude/agents/) > plugin.

---
name: db-reader
description: Execute read-only database queries        # how Claude decides to delegate
tools: Read, Grep, Bash                                # allowlist
disallowedTools: Write, Edit                           # denylist, applied after `tools`
model: sonnet                                          # inherit | sonnet | opus | haiku | full ID
effort: low                                            # low | medium | high | xhigh | max
permissionMode: plan                                   # default | acceptEdits | auto | dontAsk | bypassPermissions | plan
maxTurns: 10
skills: [api-conventions]                              # preloaded skill content (first 32 distinct names)
mcpServers: [github]
memory: project                                        # user | project | local — persistent across sessions
isolation: worktree                                    # run in its own git worktree
background: false
omitClaudeMd: true                                     # skip user / project / local CLAUDE.md; managed policy still loads (v2.1.271+)
experimental:
  cacheTtl: 1h                                         # prompt-cache lifetime for this subagent (v2.1.248+)
hooks:
  PreToolUse:
    - matcher: "Bash"
      hooks:
        - type: command
          command: ./scripts/validate-readonly-query.sh
---

Execute SELECT queries only. Never issue writes.

Three ways to invoke: name it in natural language ("use the db-reader to…"), @-mention it to guarantee that specific agent runs, or start a whole session as it with claude --agent db-reader. Since v2.1.292 Claude can also pass a per-invocation effort to a non-fork subagent; it overrides the frontmatter effort and survives a resume, and CLAUDE_CODE_EFFORT_LEVEL still beats both.

What a fresh subagent loads: its own system prompt, the delegation prompt, the CLAUDE.md hierarchy (unless omitClaudeMd: true), a git status snapshot, preloaded skills, and environment details. What stays out: your conversation history, the main session's auto memory, and other subagents' results — which is exactly the "context does not inherit" rule from Domain 1 §1.3.

Constraints worth remembering: permission modes flow down — if the parent runs bypassPermissions, acceptEdits, or auto, the subagent inherits it and cannot override. Subagents nest 3 deep by default and 20 can run concurrently. Completed subagents can be resumed by ID or name via SendMessage, retaining their prior context; one-shot agents (Explore, Plan) cannot be resumed.

Prompt-injection note: two layers protect the main agent. Subagent output scanning (v2.1.210+) escapes tags that imitate harness markup and prepends a marker line when a report imitates a tag such as <system-reminder> or mentions permission settings like bypassPermissions; and since v2.1.277 the result also arrives under a header marking it as subagent output, stating that instructions or approval claims inside it carry no authority from the user. Both are mitigations, not a permission boundary — every tool call still goes through the session's permission checks.

Beyond Subagents: Agent Teams and Dynamic Workflows

Subagents are one worker per delegation, decided turn by turn. Two larger units exist when that isn't enough, and the exam-style question is who holds the plan:

Subagents Agent teams (experimental) Dynamic workflows
What it is A worker Claude spawns A lead session supervising peer Claude Code sessions with a shared task list and inter-agent messaging A JavaScript script Claude writes and a runtime executes in the background
Who decides what runs next Claude, turn by turn The lead agent The script (agent(), parallel(), pipeline(), phase())
Scale A few delegated tasks per turn A handful of long-running peers Dozens to hundreds of agents per run; resumable in-session
Enable Built in CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 Paid plans and API access; Pro turns it on in /config; workflowSizeGuideline sets the advisory agent count (medium is now 10 agents, Pro defaults to small); CLAUDE_CODE_WORKFLOW_MAX_CONCURRENT_AGENTS (1–256) raises the per-run concurrency cap

A workflow only runs when the user opts in — the ultracode keyword in a prompt, an explicit "use a workflow", a bundled workflow skill such as /deep-research, or the ultracode toggle. Since v2.1.284 ultracode is a session setting, not an effort level: /effort ultracode [on|off] or the ultracode settings key has Claude plan a workflow for every substantive task at whatever effort the session runs; only claude --effort ultracode (and the Agent SDK's effortLevel: "ultracode") also sets xhigh. /workflows watches, pauses, resumes, or saves a run. Codifying the orchestration is the point: the plan becomes a reviewable, rerunnable script instead of a coordinator's memory (Domain 1 §1.2).

Combining Modes

Plan mode for investigation → Direct execution for implementation:

1. Enter plan mode
2. Explore the codebase
3. Design the approach
4. Present plan to user
5. User approves
6. Exit plan mode
7. Implement directly, file by file

3.5 Iterative Refinement Techniques

1. Concrete Examples

When prose instructions produce inconsistent results, provide 2-3 input/output examples:

Instead of: "Format dates consistently"

Use: "Format dates as YYYY-MM-DD. Examples:
  Input: 'January 5th, 2024' → Output: '2024-01-05'
  Input: '12/31/23' → Output: '2023-12-31'
  Input: 'Mar 2024' → Output: '2024-03-01'"

2. TDD Iteration

Write tests first, then iterate by sharing test failures:

1. Write the test: expect(validateEmail("bad")).toBe(false)
2. Run tests → FAIL
3. Share failure with Claude
4. Claude fixes the implementation
5. Run tests → PASS or new failures
6. Repeat until green

3. Interview Pattern

Claude asks clarifying questions before implementing:

User: "Add authentication to the app"
Claude: "Before I implement, a few questions:
  - JWT or session-based?
  - Do you need refresh tokens?
  - What's the session duration?
  - Should I add role-based access control?"

4. Multiple vs Independent Issues

Multiple interacting issues: Address in a single message because fixes may conflict.

"The auth middleware has two issues:
1. It doesn't check token expiry
2. It returns 500 instead of 401 for invalid tokens
Fix both together."

Independent issues: Fix sequentially to keep each change clean and reviewable.


3.6 CI/CD Integration

CLI Flags for CI

Flag Purpose Critical?
-p / --print Non-interactive mode MUST use in CI or the process hangs waiting for input
--output-format text, json, or stream-json for machine-parseable output Needed for downstream processing
--input-format stream-json Stream input events back into the agent For pipeline composition
--json-schema '{...}' Validate final output against a JSON Schema (print mode only) Enforces CI output shape
--max-turns N Hard cap on agentic turns; exits with error if hit Guardrail
--max-budget-usd X Stop once API spend hits $X (print mode only) Cost guardrail
--bare Skip auto-discovery (hooks, skills, custom commands, subagents, plugins, MCP, auto memory, CLAUDE.md) — fast, reproducible scripted starts. Since v2.1.286 it also connects only MCP servers given on the command line, sends no system reminders, and runs no background tasks; it never reads OAuth or the keychain, so set ANTHROPIC_API_KEY. Recommended for scripts and slated to become the -p default Low-overhead scripted calls
--no-session-persistence Don't save the session to disk Ephemeral CI runs
--fallback-model sonnet Auto-fall back when the primary model is overloaded Reliability
--include-hook-events Emit all hook lifecycle events into the stream Observability
--include-partial-messages Emit partial streaming events Debugging
--permission-mode <mode> Start in default / acceptEdits / plan / auto / dontAsk / bypassPermissions See §3.4
--permission-prompt-tool <mcp> Delegate permission prompts to an MCP tool in headless mode Non-interactive approvals
--permission-prompts none Deny anything that would prompt when nobody can answer (v2.1.259+); the active mode still decides everything else Unattended runners
--restricted Remove command/code-running tools and WebFetch, confine file tools to the working directories, load only managed settings, refuse bypassPermissions (v2.1.248+) Eval harnesses on shared machines
--safe-mode Start with every customization disabled (CLAUDE.md, skills, hooks, MCP, plugins, workflows, auto memory) — unlike --bare, permissions still apply Troubleshooting a broken config
--session-id, --resume, --continue, --fork-session Session lifecycle control Multi-step pipelines
--setting-sources user,project,local Restrict which settings layers are loaded Reproducible runs
--effort <level> low / medium / high / xhigh / max; ultracode turns the ultracode toggle on and sets xhigh Tune cost vs quality per run
--agent <name> / --agents '<json>' Run the session as a named subagent, or define subagents inline Specialized CI jobs
--append-subagent-system-prompt / -file Append text (or a file, v2.1.261+) to every subagent's prompt except forks (non-interactive only) Consistent citation/format rules
--forward-subagent-text Emit subagent messages into the stream Observability across delegated work
--system-prompt / --system-prompt-file / --append-system-prompt Replace or extend the system prompt (use the -file forms for large prompts — self-hosted runners now pass prompts as files; since v2.1.283 a flag can be combined with its own -file form; --system-prompt-snapshot off re-renders it every request while you iterate on the text) Purpose-built CI personas
--exclude-dynamic-system-prompt-sections Move per-machine sections out of the system prompt Prompt-cache reuse across runners
--strict-mcp-config Use only the servers from --mcp-config Hermetic MCP surface
--init / --init-only Run Setup / SessionStart hooks (and exit) Warm a CI workspace before the real run
--bg / --background + --exec Start as a background agent; run a shell command as a background job Long tasks that shouldn't block
--environment ccpool_* / --ref Target a self-hosted environment; check out a named ref Fleet / remote execution
--betas Send beta headers with API requests Opt into preview features

Unattended sessions (-p, SDK, CI, cloud) also get a time limit on background shell commands — 30 minutes by default, up to 2 hours when Claude passes a timeout — while interactive sessions keep none. Env vars added in this range for locked-down runners: CLAUDE_CODE_DISABLE_WEB_FETCH (v2.1.285), CLAUDE_CODE_DISABLE_STRUCTURED_OUTPUTS (for gateways that reject output_config.format), CLAUDE_CODE_DISABLE_FILE_MENTIONS, and CLAUDE_CODE_OVERLOADED_RETRY_BASE_DELAY_MS / _MAX_DELAY_MS for 529 backoff. claude project purge is now claude purge, and claude --desktop opens the desktop app on the current directory.

Example CI Usage

# GitHub Actions example
- name: Code Review
  run: |
    claude -p "Review this PR for bugs and security issues" \
      --output-format json \
      --json-schema '{"type":"object","properties":{"issues":{"type":"array"}}}'

Managed CI Integrations

You don't always wire the CLI up by hand:

Integration What it does
GitHub Actions Run Claude Code in a workflow — PR review, issue triage, @claude mentions
GitLab CI/CD Same model on GitLab pipelines
GitHub Code Review Automatic review on every PR, no workflow file to maintain
Routines Cloud-scheduled runs that can also fire on GitHub events or API calls

The -p + --output-format json pattern below is still the right primitive when you need full control; these integrations are the managed path.

Cost, Cache, and Fleet Controls (Settings)

A few settings that turn up in "how does the platform team keep 200 developers' sessions cheap and consistent" scenarios:

Setting Purpose
promptCacheTtl / subagentPromptCacheTtl Choose the 5-minute or 1-hour prompt-cache lifetime for the session and for subagents (per-agent override: experimental.cacheTtl in frontmatter)
modelPicker / modelPricing (managed) Curate the /model list; supply custom per-token rates so /cost is accurate behind a gateway (a multiplier up to 10 marks up internal chargeback rates)
managedMcpServers (managed) Org-provided MCP servers every session gets
bashOutputMaxChars Cap inline Bash output (up to 128K chars) before it floods the context. taskOutputMaxChars no longer does anything — the TaskOutput tool was removed in v2.1.277 and Claude reads a background task's output file with Read
permissions.blockReadsOutsideWorkingDirectories Keep file reads inside the working directories
workflowSizeGuideline Advisory agent-count ceiling for dynamic workflows
effortLevel / maxEffortLevel Effort is now per model: a level saved for one model doesn't carry to a newly released one (a new model starts at its own default until you pick one with /effort), and maxEffortLevel (top-level or per model under modelSettings) caps it on every provider. On the Anthropic API the aliases resolve to Opus 5.5, Sonnet 5.5 (sonnet, v2.1.284+), and Haiku 5.5 (haiku, v2.1.293+) — all three default to medium effort in Claude Code — and Pro / Team Standard plans default to Opus rather than Sonnet. Bedrock, Google Cloud, and Foundry still resolve sonnet / haiku to older versions
availableModels + availableModelsMatch: "exact" / deniedModels / allowedProviders (managed) Restrict the model list: by default an availableModels entry such as claude-opus-5 also permits later versions (Opus 5.5); "exact" holds each entry to the version it names (v2.1.283+), deniedModels blocks specific models even when allowed, and allowedProviders refuses sessions on an unlisted API provider or gateway
autoCompactWindow / idleCompaction /autocompact now saves the window per model under modelSettings (v2.1.288+). Idle compaction (v2.1.299) compacts an interactive conversation on the 1-hour cache that is past CLAUDE_CODE_IDLE_COMPACT_MIN_TOKENS (default 200K) shortly before the cache expires, so your next message sends a summary instead of the whole conversation; "idleCompaction": false turns it off
"attribution": false Hide all commit and PR attribution (v2.1.281+; older CLIs skip a settings file that holds it, so keep the object form in files shared across versions)
syncClaudeAiSkills / syncClaudeAiPlugins Opt out of syncing claude.ai-enabled skills and plugins into terminal sessions

/cost now reports per-session prompt-cache statistics and cache-miss diagnostics — the Claude Code view of the same prefix-stability problem described in Domain 4 §4.8.

Message Batches API

For non-blocking, cost-optimized batch operations:

Feature Detail
Cost savings 50% compared to synchronous API
Processing window Up to 24 hours, no latency SLA
Correlation custom_id per request for matching responses — results arrive in any order, so key by custom_id, never by position
Multi-turn NOT supported within a single batch request
Extended output Up to 300k output tokens on Opus 5.5 / 5 / 4.8 / 4.7 / 4.6, Sonnet 5.5 / 5 / 4.6, and Haiku 5.5 (not Fable 5.1) with beta header output-300k-2026-03-24 (vs 128k synchronous)

Good for:

  • Overnight code analysis reports
  • Weekly audit summaries
  • Nightly test generation
  • Batch document processing

NOT good for:

  • Pre-merge checks (blocking, needs immediate response)
  • Real-time user interactions
  • Anything requiring tool calling loops within a single request

Handling Batch Failures

# Process batch results
for result in batch_results:
    if result.status == "failed":
        failed_ids.append(result.custom_id)

# Resubmit only failures
resubmit_batch = [r for r in original_requests if r.custom_id in failed_ids]

Session Context Isolation for Reviews

Problem: The same Claude session that wrote code is less effective at reviewing it because it retains the reasoning context (it already "knows" why it made each decision, making it less likely to question them).

Solution: Use independent review instances that don't have the generation context.

Independent review: the code goes from the generation session to a fresh review session that shares none of its context.

Domain 3 Practice Questions

Q1: A team wants testing conventions to apply to all *.test.ts files throughout their codebase, which has tests scattered across many directories. What is the most maintainable approach?

  • A) Add a CLAUDE.md in every directory that contains test files
  • B) Create a single rule file in .claude/rules/ with paths: ["**/*.test.ts"] frontmatter
  • C) Add testing rules to the project-level CLAUDE.md
  • D) Create a tests/ directory and put all tests there with a CLAUDE.md
Show answer

Answer: B — Path-specific rules in .claude/rules/ are superior to directory-level CLAUDE.md when conventions span multiple directories. A single rule file with glob patterns covers all matching files without duplication.

Q2: When should Claude Code use plan mode instead of direct execution?

  • A) When fixing a single bug with a clear stack trace
  • B) When migrating a library that affects 45+ files across the project
  • C) When adding a null check to a function
  • D) When updating a configuration constant
Show answer

Answer: B — Plan mode is for multi-file changes with architectural implications and multiple valid approaches. A library migration affecting 45+ files clearly fits. The other options are small, obvious-scope changes suited for direct execution.

Q3: A CI pipeline needs to run Claude Code for automated code review. Which flag is essential?

  • A) --verbose
  • B) -p / --print
  • C) --force
  • D) --no-cache
Show answer

Answer: B — The -p/--print flag enables non-interactive mode, which is mandatory in CI. Without it, Claude Code hangs waiting for user input. Pair it with --output-format json (or stream-json), --max-turns / --max-budget-usd for production-grade guardrails, and --permission-prompts none when no host can answer a permission prompt.