CCA-F STUDY
← Domains·Domain 1· 27% of exam

Agentic Architecture & Orchestration

Agentic Architecture and Orchestration is the largest CCA-F domain (27%). It tests how you turn Claude into an autonomous agent and then compose multiple agents into reliable systems. The core mental model is the model-driven agentic loop (send request, inspect stop_reason, execute tools, feed results back) and the patterns built on top of it: coordinator-subagent (hub-and-spoke / orchestrator-worker) delegation, programmatic enforcement with Agent SDK hooks, task decomposition (prompt chaining vs dynamic decomposition), and session lifecycle management (resume / fork). The exam heavily rewards distinguishing deterministic mechanisms (stop_reason, hooks, prerequisite gates) from probabilistic ones (prompt instructions, natural-language signals).

What the exam expects
  • 01When a question asks how a loop should terminate, the answer is almost always 'inspect stop_reason' (continue on tool_use, stop on end_turn). Any option about parsing natural-language phrases, scanning assistant text, or using an iteration cap as the PRIMARY stop is a distractor.
  • 02Treat hooks and prerequisite gates as the answer whenever a scenario demands GUARANTEED compliance (refund limits, identity verification before financial ops). Prompt instructions have a non-zero failure rate and are the wrong choice for deterministic business rules.
  • 03Subagents start with a FRESH context and inherit nothing from the parent except the Agent/Task tool's prompt string. If a question says the synthesis agent 'didn't have the search results,' the fix is to pass findings explicitly in the prompt, not to assume shared memory.
  • 04Remember 'Task' was renamed to 'Agent' in Claude Code v2.1.63 but still works as an alias. The coordinator must have Agent (or Task) in allowedTools to spawn subagents, and subagents must NOT have Agent in their tools (no nested spawning).
  • 05Spawn parallel subagents by emitting MULTIPLE Agent tool calls in a SINGLE coordinator response, not across separate turns.
  • 06Match decomposition to predictability: prompt chaining (fixed sequential steps) for predictable multi-aspect work; dynamic/adaptive decomposition (orchestrator-workers) when you can't predict the subtasks. Over-narrow decomposition causes coverage gaps and duplicated subagent work.
  • 07Know the session verbs cold: --resume / -r (specific session by ID or name), --name / -n (name a session), --continue / -c (most recent), --fork-session / fork_session (branch a copy). Prefer a fresh session with an injected summary when prior tool results are stale.
Task 1.1

Design and implement agentic loops for autonomous task execution

Official objective — Knowledge & Skills
Knowledge of
  • The agentic loop lifecycle: sending requests to Claude, inspecting stop_reason ("tool_use" vs "end_turn"), executing requested tools, and returning results for the next iteration
  • How tool results are appended to conversation history so the model can reason about the next action
  • The distinction between model-driven decision-making (Claude reasons about which tool to call next based on context) and pre-configured decision trees or tool sequences
Skills in
  • Implementing agentic loop control flow that continues when stop_reason is "tool_use" and terminates when stop_reason is "end_turn"
  • Adding tool results to conversation context between iterations so the model can incorporate new information into its reasoning
  • Avoiding anti-patterns such as parsing natural language signals to determine loop termination, setting arbitrary iteration caps as the primary stopping mechanism, or checking for assistant text content as a completion indicator

An agentic loop is the control flow that lets Claude execute a task autonomously across many tool calls. The lifecycle is: (1) send a Messages API request with your tools array; (2) inspect the response's stop_reason; (3) if it is "tool_use", execute each tool_use block your code received and append the outputs back as tool_result blocks; (4) send the updated message list and repeat. The loop terminates when stop_reason becomes "end_turn" (Claude produced a final answer with no tool calls). This is the canonical while stop_reason == "tool_use" pattern.

Tool results are appended to conversation history so the model can reason over new information on the next iteration. The assistant's tool_use content block (with its id, name, input) is added as an assistant turn, and the matching tool_result (referencing the same tool_use_id) is added as a user turn. Because context accumulates, Claude can chain dozens of tool calls, adjusting based on each result.

The critical distinction is model-driven decision-making vs pre-configured sequences. In a true agentic loop, Claude reasons about WHICH tool to call next from current context; you do not hardcode a decision tree. The Agent SDK wraps this same loop: it yields AssistantMessage and UserMessage objects per turn and a final ResultMessage; max_turns/maxTurns counts tool-use turns and exists as a safety cap, not the primary stop. Other stop reasons your loop must handle: max_tokens (retry with higher limit if a tool_use was truncated), pause_turn (server-tool iteration limit; resend the response as-is), refusal, and model_context_window_exceeded.

pythonCorrect patternCanonical agentic loop keyed on stop_reason
messages = [{"role": "user", "content": user_query}]
while True:
    response = client.messages.create(
        model="claude-opus-4-8", max_tokens=1024, messages=messages, tools=tools
    )
    if response.stop_reason == "tool_use":
        tool_results = execute_tools(response.content)
        messages.append({"role": "assistant", "content": response.content})
        messages.append({"role": "user", "content": tool_results})
    else:  # end_turn (or max_tokens/refusal/etc.)
        return response
pythonAnti-patternANTI-PATTERN: terminating on natural-language signals and an iteration cap
for i in range(10):  # arbitrary cap as the PRIMARY stop
    response = call_claude(messages)
    text = get_text(response)
    if "done" in text.lower() or "task complete" in text.lower():
        break  # parsing NL to decide termination is unreliable
    messages = run_tools_and_append(response, messages)
Anti-patterns & traps
TrapWhy it failsCorrect pattern
Parsing assistant natural-language text (e.g. scanning for 'done' or 'task complete') to decide when to stop the loop.Natural-language phrasing is non-deterministic; Claude may finish without saying a keyword, or say it mid-task. The API gives you an explicit, reliable signal in `stop_reason`.Branch on `stop_reason`: continue on `"tool_use"`, terminate on `"end_turn"`.
Using an arbitrary iteration cap (e.g. `for i in range(10)`) as the main stopping mechanism.A fixed cap either cuts off legitimate work before completion or runs needlessly; it doesn't reflect whether Claude is actually done.Let `stop_reason` drive termination; use `max_turns`/`max_budget_usd` only as a safety backstop.
Checking whether the response contains assistant text as the completion indicator.Claude can emit text AND tool_use in the same turn, so the presence of text does not mean the task is finished.Ignore text presence; key the loop on `stop_reason` only.
Must-know
  • Continue the loop while `stop_reason == "tool_use"`; terminate on `end_turn`.
  • Append the assistant `tool_use` block and the user `tool_result` block (matched by `tool_use_id`) so the model reasons over fresh info each iteration.
  • Decisions are model-driven: Claude picks the next tool from context, not from a hardcoded sequence or decision tree.
  • `max_turns`/`maxTurns` is a safety cap, not the primary termination signal.
  • Handle other stop reasons too: `max_tokens`, `pause_turn` (server tools), `refusal`.
Practice — 3 questions for this taskDrill Task 1.1
Task 1.2

Orchestrate multi-agent systems with coordinator-subagent patterns

Official objective — Knowledge & Skills
Knowledge of
  • Hub-and-spoke architecture where a coordinator agent manages all inter-subagent communication, error handling, and information routing
  • How subagents operate with isolated context—they do not inherit the coordinator's conversation history automatically
  • The role of the coordinator in task decomposition, delegation, result aggregation, and deciding which subagents to invoke based on query complexity
  • Risks of overly narrow task decomposition by the coordinator, leading to incomplete coverage of broad research topics
Skills in
  • Designing coordinator agents that analyze query requirements and dynamically select which subagents to invoke rather than always routing through the full pipeline
  • Partitioning research scope across subagents to minimize duplication (e.g., assigning distinct subtopics or source types to each agent)
  • Implementing iterative refinement loops where the coordinator evaluates synthesis output for gaps, re-delegates to search and analysis subagents with targeted queries, and re-invokes synthesis until coverage is sufficient
  • Routing all subagent communication through the coordinator for observability, consistent error handling, and controlled information flow

Coordinator-subagent orchestration is a hub-and-spoke (orchestrator-worker) architecture. A single coordinator (lead) agent owns task decomposition, delegation, result aggregation, and all inter-subagent communication, error handling, and information routing. Subagents are the spokes: they never talk to each other directly, and they run with isolated context windows. They do NOT automatically inherit the coordinator's conversation history, so the coordinator must hand each one a self-contained task description and output format.

The coordinator's first job is analyzing query requirements and dynamically selecting which subagents to invoke based on complexity, rather than always routing every query through the full pipeline. A simple lookup should not spin up five research agents; a broad research question should. Anthropic's own multi-agent research system embeds guidance to 'scale effort to query complexity' for exactly this reason.

To minimize duplicated work, the coordinator partitions scope: it assigns distinct subtopics or source types to each subagent (e.g., one covers historical sources, another current data). A documented failure mode from Anthropic's research system was poor division of labor, where multiple subagents redundantly investigated the same thing. The opposite risk is overly narrow decomposition, which leaves gaps in coverage for broad topics.

Mature coordinators run an iterative refinement loop: after synthesis, the coordinator evaluates the output for gaps, re-delegates targeted queries to search/analysis subagents, and re-invokes synthesis until coverage is sufficient (an evaluator-optimizer style loop). Routing all communication through the coordinator gives you observability, consistent error handling, and controlled information flow. In the SDK, SubagentStart/SubagentStop hooks let the coordinator track and aggregate parallel results.

textCorrect patternCoordinator prompt that scales effort and partitions scope
You are the coordinator. Analyze the query's complexity first.
- Simple factual query: answer directly OR use ONE search subagent.
- Broad research query: spawn 3-5 subagents, each assigned a DISTINCT
  subtopic or source type so their work does not overlap.
After synthesis, check coverage. If gaps remain, re-delegate targeted
queries to search/analysis subagents and re-run synthesis.
Anti-patterns & traps
TrapWhy it failsCorrect pattern
Always routing every query through the full subagent pipeline regardless of complexity.It wastes tokens and latency on simple queries and can over-fragment them; the coordinator should match effort to query complexity.Have the coordinator analyze requirements and dynamically select which (and how many) subagents to invoke.
Spawning multiple subagents without partitioning scope.Subagents with isolated context and no division of labor duplicate each other's research (Anthropic's documented failure: multiple agents investigating the same topic).Assign each subagent a distinct subtopic or source type so coverage is complementary, not redundant.
Letting subagents communicate or pass results peer-to-peer.It breaks observability and consistent error handling, and subagents have isolated context anyway.Route all information flow and error handling through the coordinator.
Must-know
  • Hub-and-spoke: the coordinator mediates ALL inter-subagent communication, routing, and error handling; subagents never talk directly.
  • Subagents run in isolated context and do not inherit the coordinator's history.
  • The coordinator dynamically selects subagents by query complexity instead of always running the full pipeline.
  • Partition scope (distinct subtopics/source types) to minimize duplicated work.
  • Use iterative refinement: evaluate synthesis for gaps, re-delegate targeted queries, re-synthesize.
  • Over-narrow decomposition causes coverage gaps; over-broad/undivided decomposition causes duplication.
Practice — 3 questions for this taskDrill Task 1.2
Task 1.3

Configure subagent invocation, context passing, and spawning

Official objective — Knowledge & Skills
Knowledge of
  • The Task tool as the mechanism for spawning subagents, and the requirement that allowedTools must include "Task" for a coordinator to invoke subagents
  • That subagent context must be explicitly provided in the prompt—subagents do not automatically inherit parent context or share memory between invocations
  • The AgentDefinition configuration including descriptions, system prompts, and tool restrictions for each subagent type
  • Fork-based session management for exploring divergent approaches from a shared analysis baseline
Skills in
  • Including complete findings from prior agents directly in the subagent's prompt (e.g., passing web search results and document analysis outputs to the synthesis subagent)
  • Using structured data formats to separate content from metadata (source URLs, document names, page numbers) when passing context between agents to preserve attribution
  • Spawning parallel subagents by emitting multiple Task tool calls in a single coordinator response rather than across separate turns
  • Designing coordinator prompts that specify research goals and quality criteria rather than step-by-step procedural instructions, to enable subagent adaptability

In the Claude Agent SDK, subagents are spawned through the Task tool (renamed to Agent in Claude Code v2.1.63; Task still works as an alias and still appears in the system:init tools list). A coordinator can only spawn subagents if "Agent" (or "Task") is in its allowedTools/allowed_tools; otherwise invocations fall through to the permission callback or are denied. Subagents cannot spawn their own subagents, so you must NOT put Agent in a subagent's tools array.

You declare subagent types in the agents parameter, each an AgentDefinition with: description (required; tells Claude when to use it), prompt (required; its system prompt), tools (optional allowlist; omit to inherit all), and optionally model, disallowedTools, skills, mcpServers, maxTurns, and effort.

The crucial mechanic: subagent context must be provided explicitly in the prompt. A subagent starts fresh and the ONLY parent-to-child channel is the Agent tool's prompt string. It does receive its own system prompt, project CLAUDE.md (via settingSources), and tool definitions, but NOT the parent's conversation history or tool results. So to give a synthesis subagent the web-search results and document analysis from prior agents, you embed those findings directly in its prompt. Use structured data formats to keep content separate from metadata (source URLs, document names, page numbers) so attribution is preserved across the handoff.

Spawn subagents in parallel by emitting multiple Agent tool calls in a single coordinator response (not across separate turns). Write coordinator prompts that specify research goals and quality criteria rather than rigid step-by-step procedures, so subagents can adapt. For exploring divergent approaches from a shared baseline, fork-based session management (fork_session) branches a copy of the analyzed context.

pythonCorrect patternAgentDefinition with Agent in allowedTools and explicit context passing
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition

query(
  prompt=("Synthesize a report. Findings to use:\n"
          f"<search_results>{json.dumps(results)}</search_results>\n"
          f"<doc_analysis>{json.dumps(doc_findings)}</doc_analysis>"),
  options=ClaudeAgentOptions(
    allowed_tools=["Read", "Grep", "Glob", "Agent"],  # Agent enables spawning
    agents={
      "synthesizer": AgentDefinition(
        description="Synthesizes research findings into a cited report.",
        prompt="You combine provided findings; cite every claim by source URL.",
        tools=["Read"],  # note: no 'Agent' here
      )
    },
  ),
)
pythonAnti-patternANTI-PATTERN: assuming the subagent inherits parent context
# Subagent prompt omits the data it needs, assuming shared memory
agents={"synthesizer": AgentDefinition(
    description="Synthesizes findings",
    prompt="Write the final report from the research we did.",  # what research?
)}
# The subagent starts FRESH and never saw the parent's tool results.
Anti-patterns & traps
TrapWhy it failsCorrect pattern
Expecting a subagent to automatically see the coordinator's prior tool results or conversation.Subagents start with a fresh context; the only inbound channel is the Agent tool's prompt string. Missing data means the subagent works blind.Embed complete prior findings directly in the subagent's prompt, using structured fields for content and attribution metadata.
Forgetting to add `Agent` (or `Task`) to the coordinator's allowedTools.Without it, subagent invocations aren't auto-approved and the coordinator silently never delegates.Include `"Agent"` in `allowedTools`; check both `"Agent"` and `"Task"` when detecting invocations for version compatibility.
Spawning subagents sequentially across separate turns when they're independent.Sequential spawning forfeits parallelism, so total time becomes the sum rather than the slowest subagent.Emit multiple Agent tool calls in a single coordinator response to run them concurrently.
Must-know
  • The Task/Agent tool spawns subagents; `"Agent"` (or `"Task"`) MUST be in the coordinator's allowedTools.
  • Never put `Agent` in a subagent's `tools` — subagents cannot nest-spawn.
  • AgentDefinition requires `description` and `prompt`; `tools`/`model` are optional restrictions.
  • Subagents inherit nothing from the parent except the Agent tool's prompt string — pass all needed findings explicitly.
  • Use structured data to separate content from metadata (URLs, doc names, page numbers) to preserve attribution.
  • Parallelize by emitting multiple Agent tool calls in one response; write goal-and-criteria prompts, not step-by-step scripts.
Practice — 3 questions for this taskDrill Task 1.3
Task 1.4

Implement multi-step workflows with enforcement and handoff patterns

Official objective — Knowledge & Skills
Knowledge of
  • The difference between programmatic enforcement (hooks, prerequisite gates) and prompt-based guidance for workflow ordering
  • When deterministic compliance is required (e.g., identity verification before financial operations), prompt instructions alone have a non-zero failure rate
  • Structured handoff protocols for mid-process escalation that include customer details, root cause analysis, and recommended actions
Skills in
  • Implementing programmatic prerequisites that block downstream tool calls until prerequisite steps have completed (e.g., blocking process_refund until get_customer has returned a verified customer ID)
  • Decomposing multi-concern customer requests into distinct items, then investigating each in parallel using shared context before synthesizing a unified resolution
  • Compiling structured handoff summaries (customer ID, root cause, refund amount, recommended action) when escalating to human agents who lack access to the conversation transcript

Multi-step workflows must distinguish programmatic enforcement from prompt-based guidance. Prompt instructions ('always verify the customer before refunding') guide behavior but have a non-zero failure rate — the model can skip a step. When deterministic compliance is required (identity verification before financial operations, prerequisite ordering), you enforce it in code via hooks or prerequisite gates so a downstream tool simply cannot run until its precondition is met.

A prerequisite gate is typically a PreToolUse hook that blocks a tool call until a prior step has completed. For example, block process_refund until get_customer has returned a verified customer ID. The gate inspects accumulated state and returns permissionDecision: "deny" with a reason if the precondition isn't satisfied, redirecting the model rather than letting the unsafe action through. Because deny is deterministic, the ordering is guaranteed regardless of how the model phrases its plan.

For multi-concern requests (a customer reports a billing error AND a shipping delay AND wants a discount), decompose into distinct items, investigate each in parallel using shared context, then synthesize one unified resolution rather than handling them in an ad hoc order.

Structured handoff protocols matter when escalating mid-process to a human who lacks the conversation transcript. The handoff summary must be self-contained: customer ID, root-cause analysis, the refund amount or action taken, and a recommended action. A human agent reading only that summary should be able to act without replaying the chat. The same applies to escalation triggered programmatically (e.g., a refund exceeding a policy threshold routes to human review with a compiled summary attached).

pythonCorrect patternPrerequisite gate: block process_refund until customer is verified
async def require_verified_customer(input_data, tool_use_id, context):
    if input_data["tool_name"] == "process_refund" and not state.verified_customer_id:
        return {
            "hookSpecificOutput": {
                "hookEventName": input_data["hook_event_name"],
                "permissionDecision": "deny",
                "permissionDecisionReason": (
                    "Run get_customer and verify identity before any refund."),
            }
        }
    return {}
textCorrect patternStructured handoff summary for human escalation
ESCALATION
 customer_id: C-48213 (verified)
 root_cause: duplicate charge from retry on payment gateway timeout
 refund_amount: $742.00 (exceeds $500 auto-approval threshold)
 recommended_action: approve refund + add 1-month credit for inconvenience
Anti-patterns & traps
TrapWhy it failsCorrect pattern
Relying on a system-prompt instruction ('always verify identity before issuing a refund') to enforce a mandatory ordering.Prompt-based guidance has a non-zero failure rate; the model can skip or reorder the step, which is unacceptable for financial/identity-critical operations.Gate the downstream tool with a PreToolUse hook that denies it until the prerequisite step's result is present.
Escalating to a human with only 'see conversation' or a vague note.The human agent has no access to the transcript and cannot reconstruct context, delaying or misrouting resolution.Compile a structured, self-contained handoff (customer ID, root cause, amount, recommended action).
Must-know
  • Programmatic enforcement (hooks/prerequisite gates) guarantees ordering; prompt instructions are probabilistic and can fail.
  • Use deterministic gates when correctness is mandatory: e.g., block `process_refund` until `get_customer` returns a verified ID.
  • A PreToolUse hook returning `permissionDecision: "deny"` is the mechanism for prerequisite gating.
  • Decompose multi-concern requests into distinct items, investigate in parallel with shared context, then synthesize one resolution.
  • Escalation handoffs must be self-contained: customer ID, root cause, refund amount/action, recommended action — for a human with no transcript access.
Practice — 2 questions for this taskDrill Task 1.4
Task 1.5

Apply Agent SDK hooks for tool call interception and data normalization

Official objective — Knowledge & Skills
Knowledge of
  • Hook patterns (e.g., PostToolUse) that intercept tool results for transformation before the model processes them
  • Hook patterns that intercept outgoing tool calls to enforce compliance rules (e.g., blocking refunds above a threshold)
  • The distinction between using hooks for deterministic guarantees versus relying on prompt instructions for probabilistic compliance
Skills in
  • Implementing PostToolUse hooks to normalize heterogeneous data formats (Unix timestamps, ISO 8601, numeric status codes) from different MCP tools before the agent processes them
  • Implementing tool call interception hooks that block policy-violating actions (e.g., refunds exceeding $500) and redirect to alternative workflows (e.g., human escalation)
  • Choosing hooks over prompt-based enforcement when business rules require guaranteed compliance

Agent SDK hooks are callbacks that fire at points in the agent loop, letting you intercept and transform tool activity deterministically. Two patterns matter most here. PostToolUse fires AFTER a tool returns; use it to normalize or transform results before the model processes them. PreToolUse fires BEFORE a tool executes; use it to inspect and block or modify outgoing tool calls.

For data normalization, a PostToolUse hook reconciles heterogeneous formats from different MCP tools — one tool returns Unix timestamps, another ISO 8601, another numeric status codes — into a single canonical shape so the agent reasons over consistent data. You set updatedToolOutput inside hookSpecificOutput to replace the tool's output before Claude sees it (this works for any tool in both SDKs; the older updatedMCPToolOutput is MCP-only and deprecated). You can also append with additionalContext instead of replacing.

For compliance enforcement, a PreToolUse hook intercepts the outgoing call and returns permissionDecision: "deny" with a permissionDecisionReason to block a policy-violating action (e.g., a refund exceeding $500) and redirect to an alternative workflow such as human escalation. When multiple hooks apply, deny wins over defer over ask over allow.

The exam's key conceptual point: choose hooks over prompt instructions when business rules require GUARANTEED compliance. A prompt nudge is probabilistic; a hook is a deterministic guarantee enforced in your process, outside the model's discretion. Hooks are registered under options.hooks keyed by event name, each with an optional matcher (tool-name pattern like "Write|Edit" or ^mcp__) and an array of callbacks. Hooks run in your process and don't consume context.

pythonCorrect patternPostToolUse: normalize heterogeneous timestamps before the model sees them
async def normalize_timestamps(input_data, tool_use_id, context):
    if input_data["hook_event_name"] != "PostToolUse":
        return {}
    out = canonicalize_to_iso8601(input_data["tool_response"])  # Unix/codes -> ISO
    return {"hookSpecificOutput": {
        "hookEventName": "PostToolUse",
        "updatedToolOutput": out,
    }}
pythonCorrect patternPreToolUse: block refunds over $500 and redirect to escalation
async def cap_refunds(input_data, tool_use_id, context):
    ti = input_data["tool_input"]
    if input_data["tool_name"] == "process_refund" and ti.get("amount", 0) > 500:
        return {"hookSpecificOutput": {
            "hookEventName": input_data["hook_event_name"],
            "permissionDecision": "deny",
            "permissionDecisionReason": "Refunds over $500 require human escalation.",
        }}
    return {}
Anti-patterns & traps
TrapWhy it failsCorrect pattern
Writing a system-prompt rule like 'never issue refunds above $500' and trusting the model to obey.Prompt compliance is probabilistic; for a hard business rule a single violation is a real financial/policy breach.Enforce the threshold in a PreToolUse hook that denies the call and redirects to escalation.
Asking the model to mentally reconcile mixed data formats (Unix vs ISO timestamps) from different MCP tools.It wastes tokens, invites reasoning errors, and is inconsistent across runs.Normalize deterministically in a PostToolUse hook via `updatedToolOutput` so the agent always sees one canonical format.
Must-know
  • PostToolUse intercepts results AFTER execution — ideal for normalizing heterogeneous data (Unix vs ISO 8601 timestamps, numeric codes) before the model reads them.
  • Replace tool output with `updatedToolOutput` inside `hookSpecificOutput`; append with `additionalContext`.
  • PreToolUse intercepts calls BEFORE execution — return `permissionDecision: "deny"` + reason to block policy-violating actions (e.g. refund > $500) and redirect to escalation.
  • Hooks give deterministic guarantees; prompt instructions give probabilistic compliance — choose hooks when rules must always hold.
  • Register hooks under `options.hooks` by event name with an optional tool-name `matcher`; deny beats defer beats ask beats allow.
Practice — 2 questions for this taskDrill Task 1.5
Task 1.6

Design task decomposition strategies for complex workflows

Official objective — Knowledge & Skills
Knowledge of
  • When to use fixed sequential pipelines (prompt chaining) versus dynamic adaptive decomposition based on intermediate findings
  • Prompt chaining patterns that break reviews into sequential steps (e.g., analyze each file individually, then run a cross-file integration pass)
  • The value of adaptive investigation plans that generate subtasks based on what is discovered at each step
Skills in
  • Selecting task decomposition patterns appropriate to the workflow: prompt chaining for predictable multi-aspect reviews, dynamic decomposition for open-ended investigation tasks
  • Splitting large code reviews into per-file local analysis passes plus a separate cross-file integration pass to avoid attention dilution
  • Decomposing open-ended tasks (e.g., "add comprehensive tests to a legacy codebase") by first mapping structure, identifying high-impact areas, then creating a prioritized plan that adapts as dependencies are discovered

Task decomposition strategy is about choosing the right structure for breaking a complex job into subtasks. The primary axis is predictability. When the steps are known in advance, use a fixed sequential pipeline — prompt chaining — where each step's output feeds the next, with programmatic checkpoints between steps to keep the process on track. When you cannot predict the subtasks until you see intermediate findings, use dynamic adaptive decomposition (the orchestrator-workers pattern), where a central agent generates subtasks based on what it discovers at each step.

Prompt chaining shines for predictable multi-aspect work. A large code review is a strong example: decompose it into per-file local analysis passes (analyze each file individually), then run a separate cross-file integration pass. Splitting per-file work avoids attention dilution — a single mega-prompt covering many files spreads the model's focus thin and degrades quality on each file. The cross-file pass then catches interactions a per-file pass cannot see.

Dynamic decomposition fits open-ended investigation. For a task like 'add comprehensive tests to a legacy codebase,' you can't enumerate subtasks upfront. The adaptive approach first maps the structure, identifies high-impact areas, then creates a prioritized plan that adapts as dependencies are discovered — generating new subtasks from each step's findings rather than following a fixed list.

The exam wants you to match pattern to workflow: prompt chaining (predictable, sequential, multi-aspect reviews) versus dynamic decomposition (open-ended, exploratory tasks). Using a rigid fixed pipeline for an unpredictable task causes missed work; using fully dynamic decomposition for a simple predictable task adds needless overhead.

textCorrect patternPrompt chaining for a predictable code review
Step 1 (parallel, per file): analyze file A, file B, file C locally for
        bugs/style — isolated context per file (no attention dilution).
Step 2 (chained): take Step 1 outputs as input -> cross-file integration
        pass to catch interface mismatches and shared-state issues.
textCorrect patternDynamic decomposition for an open-ended task
Goal: add comprehensive tests to a legacy codebase.
 1. Map structure (modules, entry points, dependency graph).
 2. Identify high-impact, low-coverage areas.
 3. Build a prioritized plan; spawn test-writing subtasks.
 4. Adapt the plan as new dependencies are discovered each step.
Anti-patterns & traps
TrapWhy it failsCorrect pattern
Reviewing a large multi-file codebase in one giant single-pass prompt.Cramming many files into one pass dilutes the model's attention, degrading per-file quality and missing both local and cross-file issues.Chain per-file local analysis passes, then a dedicated cross-file integration pass.
Forcing a rigid fixed pipeline onto an open-ended investigation (e.g., 'add tests to a legacy codebase').You can't predict the subtasks upfront, so a predetermined sequence misses work the codebase reveals only as you explore.Use dynamic decomposition: map structure, prioritize, and generate subtasks adaptively from intermediate findings.
Must-know
  • Fixed sequential pipeline (prompt chaining) for predictable, multi-aspect work; dynamic adaptive decomposition for open-ended/unpredictable work.
  • Prompt chaining feeds each step's output into the next with programmatic checkpoints between steps.
  • Split large code reviews into per-file local analysis passes PLUS a separate cross-file integration pass to avoid attention dilution.
  • For open-ended tasks, map structure first, identify high-impact areas, then build a prioritized plan that adapts as dependencies surface.
  • Dynamic decomposition generates subtasks from intermediate findings rather than a predetermined list.
Practice — 2 questions for this taskDrill Task 1.6
Task 1.7

Manage session state, resumption, and forking

Official objective — Knowledge & Skills
Knowledge of
  • Named session resumption using --resume <session-name> to continue a specific prior conversation
  • fork_session for creating independent branches from a shared analysis baseline to explore divergent approaches
  • The importance of informing the agent about changes to previously analyzed files when resuming sessions after code modifications
  • Why starting a new session with a structured summary is more reliable than resuming with stale tool results
Skills in
  • Using --resume with session names to continue named investigation sessions across work sessions
  • Using fork_session to create parallel exploration branches (e.g., comparing two testing strategies or refactoring approaches from a shared codebase analysis)
  • Choosing between session resumption (when prior context is mostly valid) and starting fresh with injected summaries (when prior tool results are stale)
  • Informing a resumed session about specific file changes for targeted re-analysis rather than requiring full re-exploration

A session is the persisted conversation history (your prompt, every tool call, every tool result, every response) the SDK writes to disk so you can return to it. Managing session state across work sessions relies on three verbs: continue, resume, and fork.

Resume returns to a SPECIFIC session by ID or by name. In the CLI, claude --resume <name> (or -r) resumes a named session; you name a session with claude --name <name> (or -n), and --resume with no argument shows an interactive picker. --continue (-c) instead grabs the most recent session in the directory. In the SDK you capture session_id from the ResultMessage and pass resume=<id> on the next query(). Resuming restores full prior context — files already read, analysis already done.

Fork creates a new session that starts with a COPY of the original's history but diverges from that point; the original's ID and history stay unchanged. Use fork_session=True/forkSession: true (or CLI --fork-session) to explore divergent approaches from a shared analysis baseline — for example, comparing two refactoring or testing strategies that both build on the same codebase analysis.

The key judgment: choose resumption when prior context is mostly still valid; start fresh with an injected structured summary when prior tool results are stale (e.g., files were modified since). Resuming with stale tool results is less reliable than a clean session seeded with a current summary, because the model may reason over outdated file contents. When you do resume after code changes, inform the agent about the specific files that changed so it does targeted re-analysis instead of trusting cached results — or re-exploring everything.

bashCorrect patternNamed-session resumption and forking in the CLI
claude -n "auth-refactor" "Investigate the auth module"   # name the session
claude -r "auth-refactor" "Finish this PR"                # resume by name
claude --resume auth-refactor --fork-session             # branch a copy
pythonCorrect patternFork from a shared baseline to compare two strategies
# session_id holds the shared codebase-analysis baseline
async for m in query(prompt="Try the OAuth2 approach",
        options=ClaudeAgentOptions(resume=session_id, fork_session=True)):
    ...  # forked session: its own id; original stays on the JWT path
Anti-patterns & traps
TrapWhy it failsCorrect pattern
Resuming a session after the underlying files were modified, without telling the agent what changed.The resumed session carries stale tool results; the model reasons over outdated file contents and produces wrong conclusions.Either start a fresh session seeded with a structured summary, or resume and explicitly inform the agent which files changed for targeted re-analysis.
Using fork when you actually want to abandon the old direction, or resume when you want to keep both branches.Fork keeps the original intact and creates a parallel branch; plain resume mutates the single session — picking the wrong one loses a branch you needed or clutters one you didn't.Fork to keep divergent approaches side by side from a shared baseline; resume to continue a single line of work.
Must-know
  • `--resume`/`-r` resumes a specific session by ID or name; `--name`/`-n` names a session; `--continue`/`-c` resumes the most recent.
  • In the SDK, capture `session_id` from the ResultMessage and pass `resume=<id>`; resuming restores full prior context.
  • Fork (`fork_session`/`forkSession`/`--fork-session`) branches a copy from a shared baseline to explore divergent approaches; the original is untouched.
  • Resume when prior context is mostly valid; start fresh with an injected summary when prior tool results are stale.
  • After resuming post-modification, tell the agent which files changed so it re-analyzes those targets instead of trusting stale results.
Practice — 3 questions for this taskDrill Task 1.7
Ready to test it?

Drill Agentic Architecture & Orchestration

20 scenario-based questions, timed, with full explanations.

Start the Agentic drill →