🤖

🤖 Anthropic

Free Claude Certified Architect - Professional (CCAR-P) Study Resources

Architect production-grade Claude solutions the way the exam tests them — solution design, models and prompt/context engineering, integration (RAG, MCP), evaluation and optimization, governance and safety, stakeholder communication, and developer enablement, mapped 1:1 to the official CCAR-P exam guide.

442
Practice Questions
23
Study Notes
275
Flashcards
Start Studying — Free1 learners studying this hive

Claude Certified Architect - Professional (CCAR-P) Study Notes & Guides

23 AI-generated study notes covering the full Claude Certified Architect - Professional (CCAR-P) curriculum. Showing 10 complete guides below.

Study Guide951 words

Architecture decisions — patterns, boundaries and acceptance

Read full article

Architecture decisions — patterns, boundaries and acceptance

Use this reference after attempting the lectures and quizzes. It organizes the six Solution Architecture objectives into decisions you can defend from a task's requirements. The worked cases and criteria are house-authored.

Choose capabilities and control separately

ConceptDesign questionSynthetic example
Augmented LLMWhich evidence or capabilities does a model need?Retrieve a policy passage before answering
Fixed workflowWhich known stages and gates must always occur?Extract → validate → compare → decide
RoutingWhich input category selects specialized processing?Send a billing question to its policy path
Parallel workWhich branches can proceed without each other's unfinished output?Two checks after a shared validated record
Agentic planningWhich next steps become clear only during execution?Follow newly discovered product relationships
Multi-agent delegationWhich bounded tasks benefit from separate contexts or independent execution?Investigate disjoint entities and return sources to a lead

Retrieval, tools and memory can augment calls inside a workflow or agent. Adding a tool does not by itself choose the control structure. Retained instructions provide context; they do not automatically enforce an action boundary.

Worked choice: a manual-backed FAQ already meets its criteria with retrieved passages and answers. Keep that as the baseline. A new task that checks account state and proposes an allowed update adds state inspection and a consequence boundary. Evaluate a workflow with explicit checks before adopting open-ended planning. A research task whose next relevant question depends on newly discovered evidence offers a stronger reason to evaluate a planner.

Trace ownership, including failed paths

BoundaryEvidence to retainDecision enabled
Input → extractionRelevant input and extracted fieldsIs the required information available?
Model → toolRequested operation and its resultWas selection, execution or interpretation wrong?
Output → consumerResult, check outcome and failed fieldsMay the dependent action proceed?
Failed check → repairError evidence and remaining repair allowanceRepair once, revalidate or stop
Worker → leadEntity, period, sources, finding and gapsCan the lead reconcile and synthesize?
Execution → outcomeReviewed completion and operating measurementsDid the user task meet its criteria?

A log becomes feedback when an identified failure changes the next bounded action. In the project, the first invalid record receives one repair using the field errors. Revalidation uses the same remaining allowance. Another failure escalates; it does not silently begin a fresh unlimited loop. A passed local field check still has to be followed by policy and outcome checks.

Loop ownership is a separate choice: the Client SDK leaves implementation of the tool loop to your code; the Agent SDK runs a loop in your process; Managed Agents runs the agent and sandbox as a hosted product. A library can supply execution while the application retains business-rule validation.

Design a delegation contract

The house supplier investigation uses this return shape:

json
{ "entity": "Product C", "period": "current support at the exercise cutoff", "question": "Which support policy applies?", "finding": "Unresolved: sources disagree about the successor", "sources": ["synthetic-policy-C", "synthetic-transition-notice"], "unresolved": ["Whether the transition applies to this version"] }

This is an exercise schema, not a required SDK response format. Give each worker explicit scope and access. The lead aligns entity and period before combining findings. A one-word verdict cannot carry the evidence needed to resolve a scope conflict.

For the project, the lead admits no more than two active workers, twelve tool calls across the entire run and no new work after ninety seconds. A follow-up spends the same remaining budget. On exhaustion, stop new admissions, request cancellation where supported, and preserve the supported partial findings and unresolved question. In-flight work can still finish; an admission deadline is not a promise of immediate cancellation.

Replanning example: A and B turn out to be aliases, C is still unresolved and successor D is newly relevant. Merge A/B, retain C, and add D within the remaining budget. If both remaining investigations cannot fit, disclose the shortfall. Replacing C with D without a scope decision would hide missing coverage.

Apply the joint acceptance gate

For a house pilot, require success ≥97%, end-to-end p95 ≤1.5 seconds and mean execution cost ≤$0.05 per task. A hybrid with 97% success, 1.4 seconds and $0.044 mean cost passes all three supplied limits. A chaining candidate with 98% success and 1.7 seconds fails the latency limit despite having better success.

If the hybrid costs $0.04 initially and 10% of tasks need one further $0.04 attempt, the mean is:

text
initial cost + retry frequency × additional-attempt cost = 0.04 + 0.10 × 0.04 = $0.044 per task

Do not claim a measured p95 from an average or from absent raw timings. State the workload, denominator and retry inclusion. A changed workload can invalidate an accepted design, so the decision record needs a reevaluation trigger.

Review record

  1. State the customer outcome and all required operating limits.
  2. List the baseline and plausible alternatives under the same cases.
  3. Draw dependencies, ownership, validation, feedback and stop paths.
  4. Specify worker scope, evidence returns and the shared work budget.
  5. Record measured results, calculation assumptions and rejected alternatives.
  6. Name who decides acceptance and who responds when a limit is missed.

Sources

Agent SDK overview, tool use overview, search results for RAG, Claude Code memory, prompting best practices, subagents, and success criteria and evaluations.

Study Guide1,491 words

Developer productivity and operational enablement — reference

Read full article

Developer productivity and operational enablement — reference

A decision-table companion. Each table names a decision, the documented input that settles it, and the claim it does not license.

1. Where a setting lands (LO1.S1)

ScopeWho it affectsUse it for
User (~/.claude/settings.json)You, in every project on this machinePersonal preferences and your own permission rules
Shared project (.claude/settings.json)Everyone working in the folder — in a git repository, commit it so teammates get itTeam permissions, hooks, plugins, project environment
Project local (.claude/settings.local.json)You, in this one project onlyPersonal overrides, and testing before you share
ManagedEveryone the organization deploys it toSecurity policy and compliance requirements

⚠ Installing Claude Code creates no settings file. Any file you find came from you, your team, or your organization.

Precedence, highest first

LevelNotes
Managed settingsNothing you set overrides them; a key passed with --settings does not either
Command line argumentsOne session
Project localYour personal file for this project
Shared projectWhat your team committed
UserYour personal file everywhere

⚠ Environment variables are not a level in this stack. When a behaviour has both a shell variable and a settings key, which one applies is decided per pair, not by level.

⚠ Two documented cases run against the stack: a handful of security-sensitive keys honour the stricter value from a lower level over a managed value, and the permissive permissions.defaultMode values do not take effect from project or local settings at all.

How values combine

Kind of keyRule
A list key, such as permissions.allowThe lists combine, so each file adds entries without removing another file's
An ordered chain, such as fallbackModelPosition carries meaning, so the whole value comes from the highest file that defines it
A tool server entryThe entire entry from the highest-precedence scope; fields are never merged across scopes

2. Sharing with a team (LO1.S2, LO1.S3)

GoalWhere it goes
The same for everyone who clonesThe committed shared project file
A personal exceptionThat developer's project local file, which needs no commit
Non-negotiableManaged settings

⚠ Hook entries merge across settings levels rather than replacing each other, and disableAllHooks cannot switch off a managed hook from outside managed settings.

⚠ Command hooks execute shell commands with your full user permissions. Review and test them before adding them.

Tool server scopes

ScopeLoads inSharedStored in
Local (the default)Current project onlyNoThe home directory configuration
ProjectCurrent project onlyYes, via version control, after each teammate approves itA file at the project root
UserAll your projectsNoThe home directory configuration

⚠ Two different things are called "local scope." A local-scoped tool server lives in the home directory configuration; general local settings live in the project directory. The documentation calls the collision out itself.

Sharing without sharing secrets: the shared server file supports environment variable expansion, offered so teams can share configurations while keeping machine-specific paths and sensitive values like API keys out of the file. Committing it is not the last step: Claude Code prompts for approval in interactive sessions before using a project-scoped server.

3. Asked for, or guaranteed (LO2.S1, LO2.S2)

MechanismWhat it gives you
Instruction filesContext, not enforced configuration. Delivered as a user message after the system prompt, with no guarantee of strict compliance
A hookA shell command at a fixed lifecycle event, which applies regardless of what Claude decides to do

⚠ When it must run at a specific point — before every commit, after each file edit — write it as a hook. Making the instruction more specific improves consistency and does not make it enforcement.

Choose the cadence

CadenceEvents
Once per sessionSessionStart, SessionEnd
Once per turnUserPromptSubmit, Stop, StopFailure
On every tool callPreToolUse, PostToolUse

⚠ An async hook cannot block or control behaviour: decision fields have no effect, because the action they would have controlled has already completed. A check that must stop something runs synchronously on an event that can block — PreToolUse blocks the tool call; PostToolUse is documented as unable to block, because the tool already ran.

4. Running it unattended (LO2.S3)

ModeWhat the repository's content does
-p without --bareIts committed hooks run and its tool servers connect — in a folder you have never trusted
-p --bareNeither is read at all

⚠ A print session shows no workspace trust dialog and no per-server approval prompt. Before scripting it over a repository you did not write: review its settings files, start with --bare, or turn hooks off for that run with disableAllHooks.

Bare mode skips auto-discovery of hooks, skills, custom commands, subagents, plugins, tool servers, auto memory and the instructions file, which is why it is documented for CI and scripts that need the same result on every machine. It also never reads OAuth credentials or the keychain, so supply an API key in the environment or an apiKeyHelper in the --settings JSON. Amazon Bedrock, Google Cloud's Agent Platform and Microsoft Foundry keep reading their own provider credentials as usual.

The GitHub Action

InputMode
No promptInteractive: Claude waits for the trigger phrase and answers in a comment
A promptAutomation: Claude runs unattended, and results appear in the workflow run log by default

The gates differ by event. Write access is checked on issue and pull request events, and events that no user authors, such as a schedule trigger, skip that check. The human-actor check applies on every event: a bot actor is rejected unless listed in allowed_bots, which keeps bots from triggering Claude in a loop.

5. Reading it back (LO3.S1, LO3.S2)

SymptomFirst reading
A setting is ignored/status, to see which settings files the session actually loaded
None of your settings applySettings files are strict JSON — a // comment or a trailing comma is a Settings Error at the next start
A standing rule is not followed/context, and the Memory files list; if a file is missing there, Claude cannot see it
A hook did nothingThe debug log: which hooks matched, their exit codes, and full stdout and stderr

⚠ The --debug flag does not print to the terminal. Write the log to a path you name with --debug-file, or read it under the home directory keyed by session. For matching detail specifically, set CLAUDE_CODE_DEBUG_LOG_LEVEL=verbose.

What a hook's exit code says, and to whom

ExitWhat reaches ClaudeWhat reaches the transcript
0Nothing from stderrNothing; stderr goes to the debug log only
2, on an event that can blockThe blocking reasonThe block, which JSON cannot override
2, on an event that cannot blockThe failure, e.g. PostToolUse shows stderr to ClaudeNothing blocked; the tool already ran
Anything else, for most events, with plain-text or empty stdoutNothingA <hook name> hook error notice with the first line of stderr

⚠ A hook that exits 0 after printing a warning has warned nobody. To surface a warning to Claude from a PostToolUse or PostToolUseFailure hook, exit 2 instead; it works even though the tool already ran.

Why it worked for the author

SessionHooks from a settings file
Interactive, folder not yet trustedHeld back, including from your own user file
Interactive, folder trustedRun
-p or SDKRun regardless; no dialog is ever shown

⚠ Do not explain a hook with the local-file exemption. An allow rule in an untracked project local file skips the trust step the committed file requires — but that exemption covers permission allow rules, and the hooks documentation says hooks are held back from every settings file, the author's own included. The author's folder is simply trusted already, possibly through a parent directory whose trust extends to it, and the teammate's fresh clone is not.

Study Guide692 words

Developer productivity and operational enablement — study roadmap

Read full article

Developer productivity and operational enablement — study roadmap

This unit is CCARP-U7 · Developer Productivity & Operational Enablement, 7% of the blueprint and the smallest domain on the paper. It carries three official objectives in one topic, and almost every question in it is really the same question: who does this reach, and will it actually happen?

TopicObjectivesWhat you must be able to do
T1 · Team enablement and operational supportLO1, LO2, LO3Place a setting at the scope it belongs, tell an instruction from an enforcement, and read back why something did not happen

The six confusions this domain tests

  1. Two configuration systems, opposite merge rules. Settings list keys combine across files. A tool server entry is taken whole from one scope, with no field merging. Reading one rule onto the other is how a half-configured server appears.
  2. Environment variables are not a level. They are not in the precedence stack at all, and which one applies is decided per variable-and-key pair.
  3. An instruction is asked for; a hook happens. Both memory systems are context rather than enforced configuration. A step that must run at a fixed point is a hook.
  4. An unattended session loads more than you think. Without bare mode, a print-mode run executes the repository's committed hooks and connects its tool servers, in a folder nobody has ever trusted, with no trust dialog and no per-server approval.
  5. A hook that exits 0 has told nobody anything. Its standard error reaches the debug log and never the transcript, and Claude never sees it. Exit 2 is the remedy — and it blocks only on events that can block, so on the post-tool event it shows Claude the failure after the tool has already run.
  6. The local-file exemption does not explain a hook. An untracked project local file skips the workspace-trust step for its permission allow rules. Hooks are held back from every settings file, the author's own included.

Sequence

  1. LO1 first, because its vocabulary carries the other two: the four settings files, the precedence stack, and the three tool-server scopes.
  2. LO2 second. Its first half is one discrimination — instruction against hook — and its second half is what a non-interactive run still loads.
  3. LO3 last, because it is mostly LO1 and LO2 read backwards. Every symptom in it resolves to a file that did not load, a level that took the key, or an exit code nobody saw.

This is the smallest unit on the paper at 20 seats, so depth per objective matters more than breadth. Expect the scenario stems to concentrate on the seam between a developer's machine and a teammate's.

What to carry into the exam

For each objective, be able to name the mechanism, its scope, and the reading that would settle a dispute about it. This domain rewards knowing where to look. Almost every wrong answer in it is a plausible guess offered in place of a command that would have answered the question.

Sources and their limits

Every factual claim is grounded in retained documentation, quoted verbatim with a recorded retrieval date and content hash. Three cautions:

  • Behaviour here is versioned, and the documentation says so repeatedly. Several statements carry a minimum version, and a few describe what changed before one. The retained snapshots were current at their recorded retrieval date; check the current position before relying on a version-sensitive detail.
  • This unit teaches configuration, not administration. What an organization should enforce is a policy question for that organization. What is here is where a setting lands, who it reaches, and how to prove which one applied.
  • Paths and file names differ by platform. The documentation notes Windows and worktree variations for several files. Learn the scope each file carries, which is what the objective tests, rather than memorising one machine's paths.

Every command, exit code and file name used in an exercise is quoted from the documentation. Every threshold, team name and failure fixture is a house fixture, labelled where it appears.

Hands-on Lab2,629 words

Enablement project — a configuration a team could read back

Read full article

Enablement project — a configuration a team could read back

Build a local harness that answers the questions a team actually asks about its Claude Code setup: who does this setting reach, will this check really run, what does an unattended job load, and why did nothing happen. The harness uses fixed fixtures. It tests your configuration decisions; it does not run Claude Code, execute a hook, connect a tool server or call any API. Every team name, file fixture and failure report below is a house fixture; every command, exit code and file name is quoted from the documentation.

Use Python 3's standard library. No credentials or paid services are required. Complete each stage before reading its expected output, then save and run your work as unit7_project.py.

Difficulty: intermediate configuration practice. Estimated duration: 90-120 minutes. Prerequisites: the Unit 7 topic lecture.

Stage 1 - Resolve the stack

Maps to CCARP-U7.T1.LO1.S1.

Four sources set overlapping keys. Resolve each key the way the documentation says.

SourceSets
usermodel, spinnerTipsEnabled, permissions.allow
shared projectspinnerTipsEnabled, permissions.allow
project localpermissions.allow
managedspinnerTipsEnabled

Write resolve(key) returning the winning source for a scalar key, and resolve_list(key) returning the combined entries for a list key. Then record where an environment variable sits in the stack.

Expected output: spinnerTipsEnabled resolves to managed, because nothing you set overrides it. model resolves to user, because no higher source sets it. permissions.allow does not resolve to a single source: the lists combine, so all three files' entries apply. Your note says environment variables are not a level in this stack, and that which one applies is decided per variable-and-key pair.

Stage 2 - Place each requirement at a scope

Maps to CCARP-U7.T1.LO1.S2 and .S3.

Five requirements arrive from a platform team. Write place(requirement) returning the file or scope each belongs in.

RequirementHouse fixture
Everyone who clones runs the same lint hookmust not drift
One engineer prefers a different modelpersonal
Nobody may disable the audit hooknon-negotiable
The team shares a ticketing tool servershared
That server needs a per-machine API keysecret

Expected output: the lint hook goes in the committed shared project file; the personal model goes in that engineer's project local file, which needs no commit; the audit hook goes in managed settings, which nothing a developer sets overrides; the tool server goes in project scope, the one server scope shared through version control; and the key is not placed in a file at all — it is referenced by environment variable expansion, which the documentation offers so teams can share configurations while keeping sensitive values out of them.

Stage 3 - Tell an instruction from an enforcement

Maps to CCARP-U7.T1.LO2.S1 and .S2.

Write mechanism(rule) returning instruction or hook, and event(rule) returning the specific event for anything that becomes a hook. A rule that has to stop something needs the event documented as able to block.

RuleMust run at a fixed point
Prefer two-space indentationno
Run the test suite after each file edityes
Explain the repository layout to new sessionsno
Refuse a commit that touches the vendor directoryyes

Expected output: two instructions and two hooks, on two different events. The test suite reports after each edit, so it is PostToolUse. Refusing a commit has to prevent it, so it is PreToolUse, the only per-tool-call event documented as able to block; PostToolUse is documented as unable to, because the tool already ran. Your note records why the split exists: instruction files are context, not enforced configuration, delivered as a user message after the system prompt with no guarantee of strict compliance, while a hook runs at a fixed lifecycle event regardless of what Claude decides. It also records that an async hook cannot enforce anything, because the action it would have controlled has already completed.

Stage 4 - Decide what an unattended run may load

Maps to CCARP-U7.T1.LO2.S3.

Write loads(mode) over the two documented modes, and guard(repo_is_ours) returning the documented options for scripting over a repository you did not write.

JobRepository
nightly-own-repoours
triage-vendor-reponot ours

Expected output: in default print mode the repository's committed hooks run and its tool servers connect, and the session shows no trust dialog and no per-server approval prompt; in bare mode neither is read. For the job over the repository the team does not own, guard returns all three documented options: review the settings files, start with bare mode, or turn hooks off for that run. Your note records that the pipeline branches on the process exit status, 0 on success and non-zero on failure, and that a failure inside the run is printed as the result on standard output.

Stage 5 - Read back a silent failure

Maps to CCARP-U7.T1.LO3.S1, .S2 and .S3.

Three reports arrive from developers, and three more from the unattended pipeline. Write first_reading(report) returning the documented check that settles each, audience(exit_code) returning who sees a hook's standard error, and running_job(symptom) returning the documented cause of each pipeline symptom.

ReportHouse fixture
R1"my setting is ignored"
R2"none of my settings apply since I edited the file"
R3"the hook prints a warning and nothing reacts"
J1"the job exited 143 with no result"
J2"the job waited, then ended with nothing"
J3"CI never runs on the commits the action pushes"

Expected output: R1 is the status check, which separates a file that never loaded from a value a higher level took. R2 is a strict JSON syntax error reported as a Settings Error at the next start. R3 is the exit code: standard error from a hook that exits 0 reaches the debug log only, never the transcript, and Claude never sees it — so audience(0) is nobody, audience(2) is Claude, and any other code produces a non-blocking notice in the transcript. The three pipeline symptoms are somebody else stopping your run rather than your configuration: a termination signal, which leaves the in-progress turn unfinished with no result recorded and still runs the session-end hooks; the background wait ceiling of ten minutes of continuous idle waiting, after which whatever is running is stopped and its partial result dropped; and the default repository token, which the platform does not trigger workflows on. Your note records that the debug flag does not print to the terminal, and that a hook working for its author and not for a teammate is a trust difference: an interactive session holds hooks back from every settings file — the author's own user file included — until the folder is trusted, or a parent directory whose trust extends to it. The untracked local file skips that step for its permission allow rules, not for hooks, so it does not explain the symptom.

Reference solution

python
"""Unit 7 project reference solution. Standard library only; no network calls. Every team name, file fixture and failure report is a house fixture. Every command, exit code and file name is quoted from the retained documentation. """ import json # ------------------------------------------------------------------ Stage 1 # Highest precedence first. Environment variables are deliberately absent: # the documentation states they are not a level in this stack. STACK = ("managed", "command_line", "project_local", "shared_project", "user") SOURCES = { "user": {"model": "opus", "spinnerTipsEnabled": False, "permissions.allow": ["Bash(npm test)"]}, "shared_project": {"spinnerTipsEnabled": True, "permissions.allow": ["Bash(npm run lint)"]}, "project_local": {"permissions.allow": ["Bash(git status)"]}, "managed": {"spinnerTipsEnabled": True}, } LIST_KEYS = {"permissions.allow"} def resolve(key): """A scalar key comes from the highest level that sets it.""" if key in LIST_KEYS: raise ValueError(f"{key} is a list key; lists combine rather than resolving") for level in STACK: if key in SOURCES.get(level, {}): return level return None def resolve_list(key): """A list key combines across files instead of one winning.""" combined = [] for level in STACK: combined.extend(SOURCES.get(level, {}).get(key, [])) return combined stage1 = { "spinnerTipsEnabled": resolve("spinnerTipsEnabled"), "model": resolve("model"), "permissions.allow": resolve_list("permissions.allow"), "env_vars": "not a level in this stack; decided per variable-and-key pair", } # ------------------------------------------------------------------ Stage 2 REQUIREMENTS = [ {"id": "lint-hook", "shared": True, "personal": False, "non_negotiable": False, "secret": False}, {"id": "model-preference", "shared": False, "personal": True, "non_negotiable": False, "secret": False}, {"id": "audit-hook", "shared": True, "personal": False, "non_negotiable": True, "secret": False}, {"id": "ticketing-server", "shared": True, "personal": False, "non_negotiable": False, "secret": False, "is_server": True}, {"id": "server-api-key", "shared": True, "personal": False, "non_negotiable": False, "secret": True, "is_server": True}, ] def place(requirement): if requirement["secret"]: # Not a file at all: the shared server file expands it from the environment. return "environment variable expansion, referenced from the shared server file" if requirement["non_negotiable"]: return "managed settings" if requirement["personal"]: return ".claude/settings.local.json" if requirement.get("is_server"): return "project scope, the shared server file at the project root" return ".claude/settings.json, committed" stage2 = {"placed": {r["id"]: place(r) for r in REQUIREMENTS}, "why_local_needs_no_commit": "Claude Code keeps the project local file out of git when it creates it"} # ------------------------------------------------------------------ Stage 3 RULES = [ {"id": "indentation", "fixed_point": False, "per": None, "must_block": False}, {"id": "tests-after-edit", "fixed_point": True, "per": "tool_call", "must_block": False}, {"id": "explain-layout", "fixed_point": False, "per": None, "must_block": False}, {"id": "block-vendor-commit", "fixed_point": True, "per": "tool_call", "must_block": True}, ] CADENCES = {"session": ("SessionStart", "SessionEnd"), "turn": ("UserPromptSubmit", "Stop", "StopFailure"), "tool_call": ("PreToolUse", "PostToolUse")} # Documented per-event: PreToolUse blocks the tool call; PostToolUse cannot, # because the tool already ran, and exit 2 there only shows Claude the failure. CAN_BLOCK = {"PreToolUse": True, "PostToolUse": False} def mechanism(rule): """A step that must happen at a fixed point is a hook, not an instruction.""" return "hook" if rule["fixed_point"] else "instruction" def event(rule): """Naming the cadence is not enough: only one per-tool-call event can block.""" if mechanism(rule) != "hook": return None candidates = CADENCES[rule["per"]] if rule["must_block"]: blocking = [e for e in candidates if CAN_BLOCK.get(e)] if not blocking: raise ValueError(f"no event in the {rule['per']} cadence can block") return blocking[0] return candidates[-1] stage3 = { "mechanisms": {r["id"]: mechanism(r) for r in RULES}, "events": {r["id"]: event(r) for r in RULES if event(r)}, "why": "instruction files are context, not enforced configuration; a hook runs at a " "fixed lifecycle event regardless of what Claude decides", "async_note": "an async hook cannot enforce anything: the action it would have " "controlled has already completed", } # ------------------------------------------------------------------ Stage 4 def loads(mode): if mode == "bare": return {"repo_hooks": False, "repo_servers": False, "note": "bare mode never reads them"} return {"repo_hooks": True, "repo_servers": True, "note": "no workspace trust dialog and no per-server approval prompt"} def guard(repo_is_ours): if repo_is_ours: return [] return ["review the repository's settings files", "start with bare mode", "turn hooks off for that run"] stage4 = { "default_mode": loads("default"), "bare_mode": loads("bare"), "jobs": {"nightly-own-repo": guard(True), "triage-vendor-repo": guard(False)}, "pipeline_signal": "the process exit status: 0 on success, non-zero on failure", "where_failures_print": "a failure inside the run is printed as the result on stdout", } # ------------------------------------------------------------------ Stage 5 REPORTS = [ {"id": "R1", "symptom": "a setting is ignored"}, {"id": "R2", "symptom": "none of my settings apply since I edited the file"}, {"id": "R3", "symptom": "the hook prints a warning and nothing reacts"}, ] def first_reading(report): symptom = report["symptom"] if "none of my settings" in symptom: return ("strict JSON syntax error", "a comment or trailing comma is reported as a Settings Error at the next start") if "setting is ignored" in symptom: return ("the status command", "it separates a file that never loaded from a value a higher level took") return ("the hook exit code", "stderr from a hook that exits 0 reaches the debug log only; exit 2 on an " "event that can block also blocks, and on PostToolUse it only shows Claude " "the failure, because the tool already ran") def audience(exit_code): if exit_code == 0: return "nobody: stderr goes to the debug log only, never the transcript" if exit_code == 2: return ("Claude: the blocking reason on an event that can block, which JSON cannot " "override; on PostToolUse the failure is shown and nothing is blocked") return "the transcript: a hook error notice with the first line of stderr" PIPELINE = [ {"id": "J1", "symptom": "the job exited 143 with no result"}, {"id": "J2", "symptom": "the job waited, then ended with nothing"}, {"id": "J3", "symptom": "CI never runs on the commits the action pushes"}, ] def running_job(symptom): """Three failures of a job that was already running, not of its config.""" if "143" in symptom: return ("a termination signal", "the in-progress turn is left unfinished with no result recorded; " "SessionEnd hooks still run, and resuming continues that turn") if "waited" in symptom: return ("the background wait ceiling", "10 minutes of continuous idle waiting by default, then whatever is " "still running is stopped and its partial result dropped") return ("the default repository token", "the platform does not trigger workflows on commits made with it; stop " "passing it so the action authenticates as its own app") stage5 = { "readings": {r["id"]: first_reading(r) for r in REPORTS}, "pipeline": {j["id"]: running_job(j["symptom"]) for j in PIPELINE}, "audiences": {code: audience(code) for code in (0, 1, 2)}, "debug_flag": "does not print to the terminal; write the log to a path you name", "author_versus_teammate": "an interactive session holds hooks back until the folder is trusted, while an " "allow rule in the author's own untracked local file never needed that step", } # ------------------------------------------------------------- Stage checks # Each assertion restates the expected output printed under its stage above, so # running the file confirms the configuration came out the shape it claimed. CHECKS = [ ("stage 1 gives the managed value the contested key", stage1["spinnerTipsEnabled"] == "managed" and stage1["model"] == "user"), ("stage 1 combines the list key across all three files", len(stage1["permissions.allow"]) == 3), ("stage 2 keeps the secret out of every file", "environment variable expansion" in stage2["placed"]["server-api-key"] and stage2["placed"]["audit-hook"] == "managed settings"), ("stage 2 sends the shared server to project scope", "project scope" in stage2["placed"]["ticketing-server"]), ("stage 3 finds two instructions and two hooks", sorted(stage3["mechanisms"].values()) == ["hook", "hook", "instruction", "instruction"]), ("stage 3 reports after the edit and blocks before the commit", stage3["events"]["tests-after-edit"] == "PostToolUse" and stage3["events"]["block-vendor-commit"] == "PreToolUse"), ("stage 4 has the default mode running repository content", stage4["default_mode"]["repo_hooks"] and not stage4["bare_mode"]["repo_servers"]), ("stage 4 guards only the repository the team does not own", stage4["jobs"]["nightly-own-repo"] == [] and len(stage4["jobs"]["triage-vendor-repo"]) == 3), ("stage 5 routes each report to a different reading", len({r[0] for r in stage5["readings"].values()}) == 3), ("stage 5 says a hook that exits 0 reached nobody", stage5["audiences"][0].startswith("nobody")), ("stage 5 scopes exit 2 to the events that can block", "can block" in stage5["audiences"][2]), ("stage 5 separates the three running-job failures", len({p[0] for p in stage5["pipeline"].values()}) == 3 and stage5["pipeline"]["J1"][0] == "a termination signal"), ] if __name__ == "__main__": print(json.dumps({"stage1": stage1, "stage2": stage2, "stage3": stage3, "stage4": stage4, "stage5": stage5}, indent=2, default=str)) failed = [name for name, passed in CHECKS if not passed] if failed: raise SystemExit("failed: " + "; ".join(failed)) print("all stage checks passed")

What this project does not establish

The harness checks the shape of your configuration decisions, not that they are right for your organization. It cannot tell you what your administrators should enforce, whether a given hook is safe to run, or which of your repositories deserves the guarded treatment. Command hooks execute shell commands with your full user permissions, so review and test them before adding them, whatever this harness says about where they belong.

Several documented behaviours here carry a minimum version, and a few describe what changed before one. Check the current documentation before relying on a version-sensitive detail, because the retained snapshots were current at their recorded retrieval date and no later.

Hands-on Lab2,280 words

Evaluation project — a release decision you can defend

Read full article

Evaluation project — a release decision you can defend

Build a local decision harness for a support-triage assistant. The harness uses fixed fixtures and synthetic measurements. It tests your evaluation and optimisation decisions; it does not call a model, run a real evaluation, cache anything or export telemetry. Every threshold, score, latency, rate and cost below is a house fixture.

Use Python 3's standard library. No credentials or paid services are required. Complete each stage before reading its expected output, then save and run your work as unit4_project.py.

Difficulty: advanced evaluation design. Estimated duration: 120-150 minutes. Prerequisites: the three Unit 4 topic lectures.

Stage 1 - Write criteria that can be failed

Maps to CCARP-U4.T1.LO1.S1 and .S2.

The brief says the assistant must be "accurate, fast, affordable, and safe with personal data". Turn it into criteria. Each one needs a threshold, the population it is measured over, and a direction. Write is_criterion(entry) that rejects anything missing one of the three.

Include a separate criterion for the refund-dispute tickets, which the business treats as its own bar. Then list the documented common criteria you are deliberately not measuring, so silence is a recorded decision rather than an oversight.

Phrase in the briefWhat it needs to become a criterion
accurateA rate, and the set it is measured over
fastA time, and the percentile it describes
affordableA budget, and the unit it is per
safe with personal dataA leak rate, a probe count, and the detector

Expected output: five criteria, all checkable. "Safe with personal data" has become a leak rate with a threshold and a probe count. At least two documented criteria appear on the not-measured list by name.

Stage 2 - Build the set and choose the graders

Maps to CCARP-U4.T1.LO2.S1 and .S2.

Compose a 1,000-case evaluation set that mirrors the observed distribution and contains the documented edge classes, ambiguous cases included. Then map each criterion to a grading method, choosing the fastest reliable method the judgement allows.

Expected output: ordinary traffic is the majority and edge classes are roughly 30% of the set. Ambiguous cases are present rather than removed. Routing labels are graded by exact match; the leak check is a model-based binary classification, because it needs context; nothing is hand graded, and your rationale says why volume with automated grading is preferred.

Stage 3 - Run a comparison that attributes

Maps to CCARP-U4.T2.LO3.S1 and .S2.

Two arms are supplied. Write moved(a, b) returning the settings that differ, and verdict(results) applying every criterion from stage 1. Decide the release.

BaselineCandidate
Task fidelity0.9510.968
Exception fidelity0.9020.831
p95 latency, ms15201740

All figures are house fixtures. The exception floor is 0.85.

Expected output: exactly one setting differs, so the comparison attributes. The candidate scores higher on aggregate task fidelity and fails, because the separately named exception criterion drops below its floor. Your reason names that explicitly. Re-weighting the aggregate to absorb the regression is not one of your options; it changes the contract.

Stage 4 - Diagnose three failures that look alike

Maps to CCARP-U4.T2.LO4.S1 and .S2.

Three failures are supplied, each a confident wrong answer. Write diagnose(failure) returning the fault class and the first lever, using the question that actually separates them: was the supporting fact in the evidence?

CaseFact in evidenceShape validMulti-step
F1NoYesNo
F2YesNoNo
F3YesYesYes

Record the techniques you would use to localise a fault before replacing any component, and state the residual risk that survives every fix.

Expected output: the three classify as knowledge, contract and capability, in that order, each with a different lever. The residual-risk line says these techniques reduce hallucination without eliminating it, which is why the refund action keeps a check that does not depend on the model being right.

Stage 5 - Decide the optimisation on measured reuse

Maps to CCARP-U4.T3.LO5.S1 and .S2.

Traffic and synthetic rates are supplied. Measure the reuse first. Then compute spend with and without caching, splitting prefix, suffix and output, and report both cost per request and cost per successful task given a 4% failure rate.

Expected output: the input-token saving is about 64% and the total saving about 50%, because output tokens are untouched by caching. Cost per successful task is higher than cost per request, since the failures are paid for and produce nothing. Batching is rejected with a reason: this workload is interactive and carries a latency criterion.

Stage 6 - Design monitoring you are allowed to keep

Maps to CCARP-U4.T3.LO6.S1 and .S2.

Produce a monitoring plan as a dictionary with signals, content, attribution, health and alerts. For content, state what is set, what is deliberately unset, and the approval that would change it. Every alert needs an owner and a tested recovery.

Expected output: traces carry both switches, not one. No content opt-in is set. Attribution injects end-user identity, with a note that the default attributes name the service credential. The health line says a quiet collector proves nothing. Every alert has a named owner and a recovery that has been exercised.

Reference solution

python
"""Unit 4 project reference solution. Standard library only; no network calls.""" import json # ------------------------------------------------------------------ Stage 1 # A criterion is a threshold plus the population it is measured over. Anything # without both is a preference, and a preference cannot be failed. CRITERIA = { "task_fidelity": {"threshold": 0.95, "population": "1,000 replayed tickets", "direction": "at_least"}, "exception_fidelity": {"threshold": 0.85, "population": "the 120 refund-dispute tickets", "direction": "at_least"}, "latency_p95_ms": {"threshold": 1800, "population": "the same 1,000 tickets", "direction": "at_most"}, "cost_per_successful_task_usd": {"threshold": 0.030, "population": "the same 1,000 tickets", "direction": "at_most"}, "pii_leak_rate": {"threshold": 0.001, "population": "10,000 adversarial probes", "direction": "at_most"}, } UNMEASURED = ["tone and style", "context utilization"] # named, so silence is a decision def is_criterion(entry): return (isinstance(entry.get("threshold"), (int, float)) and bool(entry.get("population")) and entry.get("direction") in {"at_least", "at_most"}) def passes(name, value): entry = CRITERIA[name] return value >= entry["threshold"] if entry["direction"] == "at_least" else value <= entry["threshold"] stage1 = {"criteria": len(CRITERIA), "all_checkable": all(is_criterion(v) for v in CRITERIA.values()), "deliberately_unmeasured": UNMEASURED, "hazy_repaired": "'handles personal data safely' became pii_leak_rate: " "at most 0.1% over 10,000 adversarial probes"} # ------------------------------------------------------------------ Stage 2 # Mirror the distribution, include the named edge classes, and pick the grader # from the judgement rather than from the tooling already in place. EVAL_SET = {"ordinary": 700, "long_input": 80, "irrelevant_input": 60, "hostile_input": 40, "ambiguous": 120} GRADERS = { "task_fidelity": "code:exact_match", # categorical routing label "exception_fidelity": "code:exact_match", "latency_p95_ms": "code:measurement", "cost_per_successful_task_usd": "code:measurement", "pii_leak_rate": "model:binary", # present or absent, needs context "tone": "model:likert", # subjective, if it were measured } stage2 = { "total_cases": sum(EVAL_SET.values()), "edge_share": round(1 - EVAL_SET["ordinary"] / sum(EVAL_SET.values()), 3), "ambiguous_included": EVAL_SET["ambiguous"] > 0, "graders": GRADERS, "hand_graded": 0, "rationale": "volume with automated grading beats fewer hand-graded cases", } # ------------------------------------------------------------------ Stage 3 # Two arms, one variable. Anything else moving makes the result a statement # about the bundle. PINNED = ("evaluation_set", "scoring_rule", "prompt", "retrieval", "tool_surface") ARMS = { "baseline": {"model": "current", "effort": "medium", "evaluation_set": "S1", "scoring_rule": "R1", "prompt": "P1", "retrieval": "K5", "tool_surface": "T1"}, "candidate": {"model": "current", "effort": "high", "evaluation_set": "S1", "scoring_rule": "R1", "prompt": "P1", "retrieval": "K5", "tool_surface": "T1"}, } RESULTS = { "baseline": {"task_fidelity": 0.951, "exception_fidelity": 0.902, "latency_p95_ms": 1520, "cost_per_successful_task_usd": 0.0241, "pii_leak_rate": 0.0004}, "candidate": {"task_fidelity": 0.968, "exception_fidelity": 0.831, "latency_p95_ms": 1740, "cost_per_successful_task_usd": 0.0288, "pii_leak_rate": 0.0004}, } def moved(a, b): return sorted(k for k in a if a[k] != b[k]) def verdict(results): checks = {name: passes(name, value) for name, value in results.items()} return {"checks": checks, "release": all(checks.values()), "failed": sorted(n for n, ok in checks.items() if not ok)} changed = moved(ARMS["baseline"], ARMS["candidate"]) stage3 = { "changed": changed, "attributable": len(changed) == 1 and all(ARMS["baseline"][p] == ARMS["candidate"][p] for p in PINNED), "baseline": verdict(RESULTS["baseline"]), "candidate": verdict(RESULTS["candidate"]), } stage3["decision"] = "reject" if not stage3["candidate"]["release"] else "accept" stage3["reason"] = ("higher aggregate fidelity does not discharge the separately named exception criterion" if "exception_fidelity" in stage3["candidate"]["failed"] else "all criteria met") # ------------------------------------------------------------------ Stage 4 # Three failures that look identical from outside. The question that splits # them is whether the supporting fact was in the evidence. FAILURES = [ {"id": "F1", "fact_in_evidence": False, "shape_valid": True, "multi_step": False}, {"id": "F2", "fact_in_evidence": True, "shape_valid": False, "multi_step": False}, {"id": "F3", "fact_in_evidence": True, "shape_valid": True, "multi_step": True}, ] def diagnose(failure): if not failure["fact_in_evidence"]: return ("knowledge", "restrict the model to the provided documents, not its general knowledge") if not failure["shape_valid"]: return ("contract", "define the output format precisely, using JSON, XML or a template") if failure["multi_step"]: return ("capability", "tune effort first; upgrade only for a demonstrated capability gap") return ("unclassified", "localise further before changing any component") stage4 = { "diagnoses": {f["id"]: diagnose(f) for f in FAILURES}, "localise_before_replacing": ["step-by-step reasoning", "repeated runs compared", "supporting quote required per claim"], "residual_risk": "these techniques reduce hallucination but do not eliminate it, " "so the refund action keeps an independent check", } # ------------------------------------------------------------------ Stage 5 # Measure reuse before caching. Cost per successful task, not per request. TRAFFIC = {"requests": 10_000, "identical_prefix_share": 0.82, "prefix_tokens": 4_200, "suffix_tokens": 350, "output_tokens": 260, "failure_rate": 0.04} RATES = {"base_input_per_token": 1.0e-6, "write_multiplier": 1.25, "read_multiplier": 0.1, "output_per_token": 5.0e-6} # synthetic house rates def spend(cached): n = TRAFFIC["requests"] prefix, suffix, out = TRAFFIC["prefix_tokens"], TRAFFIC["suffix_tokens"], TRAFFIC["output_tokens"] base = RATES["base_input_per_token"] if not cached: prefix_cost = n * prefix * base else: reads = int(n * TRAFFIC["identical_prefix_share"]) writes = n - reads prefix_cost = writes * prefix * base * RATES["write_multiplier"] + reads * prefix * base * RATES["read_multiplier"] return {"prefix": round(prefix_cost, 4), "suffix": round(n * suffix * base, 4), "output": round(n * out * RATES["output_per_token"], 4)} def totals(cached): parts = spend(cached) total = sum(parts.values()) successful = TRAFFIC["requests"] * (1 - TRAFFIC["failure_rate"]) return {**parts, "total": round(total, 4), "per_request": round(total / TRAFFIC["requests"], 6), "per_successful_task": round(total / successful, 6)} uncached, cached = totals(False), totals(True) stage5 = { "reuse_measured_first": TRAFFIC["identical_prefix_share"], "uncached": uncached, "cached": cached, "input_saving_share": round(1 - (cached["prefix"] + cached["suffix"]) / (uncached["prefix"] + uncached["suffix"]), 3), "total_saving_share": round(1 - cached["total"] / uncached["total"], 3), "output_unchanged": cached["output"] == uncached["output"], "silent_failure_check": "both cache_creation_input_tokens and cache_read_input_tokens at 0 means never cached", "batching": "not applicable: this workload is interactive and has a p95 latency criterion", } # ------------------------------------------------------------------ Stage 6 monitoring = { "signals": {"metrics": True, "log_events": True, "traces": {"exporter": True, "enhanced_telemetry_beta": True}}, "intervals_shortened_for": "short-lived jobs, since metrics default to 60s and traces to 5s", "content": {"set": [], "deliberately_unset": ["user prompts", "tool details", "tool content", "raw bodies"], "approval_to_change": "pipeline approved to store ticket contents"}, "attribution": {"session_id": "groups a conversation", "injected_end_user": "names the customer", "why": "default identity attributes name the service credential"}, "health": "verify arrival at the collector; export errors are silent by default", "alerts": [{"signal": "exception_fidelity", "owner": "support-quality", "recovery_tested": True}, {"signal": "cost_per_successful_task_usd", "owner": "platform", "recovery_tested": True}], } stage6 = {"plan": monitoring, "every_alert_has_owner": all(a["owner"] for a in monitoring["alerts"]), "recovery_tested": all(a["recovery_tested"] for a in monitoring["alerts"])} # ------------------------------------------------------------------ Checks assert stage1["all_checkable"] and stage1["deliberately_unmeasured"] assert stage2["total_cases"] == 1000 and stage2["ambiguous_included"] and stage2["hand_graded"] == 0 assert stage3["changed"] == ["effort"] and stage3["attributable"] assert stage3["baseline"]["release"] is True assert stage3["candidate"]["release"] is False and stage3["candidate"]["failed"] == ["exception_fidelity"] assert stage3["decision"] == "reject" assert [stage4["diagnoses"][k][0] for k in ("F1", "F2", "F3")] == ["knowledge", "contract", "capability"] assert stage5["output_unchanged"] is True assert stage5["total_saving_share"] < stage5["input_saving_share"] assert cached["per_successful_task"] > cached["per_request"] assert stage6["every_alert_has_owner"] and stage6["recovery_tested"] print(json.dumps({"stage1": stage1, "stage2": stage2, "stage3": stage3, "stage4": stage4, "stage5": stage5, "stage6": stage6}, indent=2)) print("\nall stage checks passed")

Acceptance checklist

  • Every stage 1 criterion has a threshold, a population and a direction.
  • The not-measured list names documented criteria explicitly.
  • The evaluation set contains ambiguous cases.
  • Stage 3 changes exactly one setting, and rejects a candidate with the higher aggregate.
  • Stage 4 returns three different fault classes with three different levers.
  • Stage 5's total saving is smaller than its input saving, and per-successful-task exceeds per-request.
  • Stage 6 leaves every content opt-in unset and gives every alert an owner.

Explain the result before extending it

Three stages have an answer that is easy to produce and hard to justify. Say the justification out loud before moving on.

  • Stage 3. The candidate is better on the headline number and is rejected. That is only defensible because the exception criterion was written down in stage 1, before any result existed. Written afterwards, it would look like moving the goalposts.
  • Stage 5. Both savings are real. Only one of them is the bill. A 64% input saving reported as a 64% cost saving is not a lie, it is a category error, and it survives review because everyone in the room wants it to be true.
  • Stage 6. The plan's most important entries are the empty ones. A content opt-in left unset, recorded with the approval that would change it, is a decision. The same field simply absent is an accident waiting to be discovered by an auditor.

Cleanup

Nothing to clean up: no credentials, no network calls, no files written outside your working directory. Delete unit4_project.py when you are done, or keep it as the starting point for the Unit 5 project.

What this project does not establish

These fixtures test your decisions and interfaces. They do not measure a real model, a real cache, a real bill or a real collector. Passing every stage means your evaluation records the right decisions with the right evidence, which is what this domain's objectives assess. It does not establish production behaviour, and no figure here is a vendor measurement.

Study Guide1,082 words

Evaluation, testing and optimization — reference

Read full article

Evaluation, testing and optimization — reference

A decision-table companion. Each table names a decision, the documented input that settles it, and the claim it does not license.

1. Success criteria (LO1)

PropertyFails when
SpecificIt names no concrete outcome
MeasurableIt carries no number or consistently applied scale
AchievableNo current frontier model reaches it
RelevantIt does not align with this application's purpose and users

Quantifying a hazy criterion needs three things: a quantity, the population it is measured over, and the instrument that decides. The documented example replaces "safe outputs" with less than 0.1% of outputs out of 10,000 trials flagged for toxicity by the content filter.

The documented common criteria are task fidelity, consistency, relevance and coherence, tone and style, privacy preservation, context utilization, latency and price. The list is explicitly non-exhaustive, and most use cases need multidimensional evaluation along several of them.

⚠ Metrics and methods are different things. Metrics: F1, BLEU, perplexity, accuracy, precision, recall, response time, uptime. Methods: A/B testing against a baseline, user feedback such as completion rates, and edge case analysis as the share handled without errors.

2. Evaluation design (LO2)

PrincipleWhat it means
Be task-specificMirror the real-world task distribution, edge cases included
Automate when possibleMultiple choice, string match, code-graded, model-graded
Prioritize volumeMore questions with lower-signal automated grading beats fewer hand-graded

Edge case classes named: irrelevant or nonexistent input; overly long input; poor, harmful or irrelevant user input in chat; and ambiguous cases where even humans would struggle to agree. That last is to be included, not removed.

Grading methodTrade
Code-basedFastest and most reliable; lacks nuance
HumanMost flexible and highest quality; slow and expensive, avoid if possible
Model-basedFast, flexible, scalable; test reliability before scaling

Two refinements for a model grader: a rubric detailed enough that the verdict is mechanical, and reason first, then discard the reasoning before scoring. Ask for empirical or specific output, since purely qualitative evaluations are hard to assess at scale. A use case may require several rubrics.

3. A/B testing and rollout (LO3)

PinnedFree
The evaluation setThe single variable under test
The scoring rule
Every other operating setting

A/B testing compares against a baseline model or an earlier version. If two things moved, the result describes the bundle.

Before the rollout, record: a threshold on each criterion, a rollback trigger, and the owner of the call. Criteria that arrive after the number are not criteria.

⚠ An aggregate gain does not discharge a separately named criterion. Re-weighting the aggregate afterwards is changing the contract, and that decision belongs to whoever owns it.

4. Diagnosis (LO4)

SymptomFirst lever
Fact absent from the supplied evidenceRestrict to provided documents, not general knowledge
Content right, shape wrongDefine the output format precisely (JSON, XML, template)
Fails only on multi-step reasoningTune effort; upgrade only for a demonstrated capability gap

Localise before replacing. Ask for step-by-step reasoning to expose faulty logic; repeat the same prompt and compare, since inconsistency can indicate hallucination; require a supporting quote per claim and retract where none exists.

⚠ These techniques significantly reduce hallucinations but do not eliminate them. Critical information still needs validation, especially for high-stakes decisions. If a downstream action is irreversible, the design needs a check that does not depend on the model having been right.

5. Optimization (LO5)

EventRate
Cache write, 5-minute TTL1.25× base input (1-hour TTL: 2×)
Cache read0.1× base input; 0.025× on Claude Fable 5.1 and Claude Mythos 5.1
Refresh on useNo additional cost

Rates as documented on 2026-09-05. The relationships are stable; the figures are not a quote.

The cached prefix follows tools → system → messages. A change invalidates that level and every level after it, so editing a tool definition invalidates the entire cache. Cache hits require 100% identical segments up to the breakpoint. Place the breakpoint on the last block that stays identical across requests.

⚠ The silent failure: a prompt under the minimum cacheable length is processed without caching and no error is returned. Verify with the usage fields — if both cache_creation_input_tokens and cache_read_input_tokens are 0, it was not cached.

Batching suits work with no immediate-response requirement: most batches finish within an hour, cutting cost by 50% and raising throughput (documented 2026-09-05). Large-scale evaluation is a named fit. It does not improve per-request latency.

⚠ Cost per successful task, not per request. Input-token spend excludes output tokens, which caching does not affect, and a write costs 1.25× the input it replaces — a prefix never read again is worse off cached. (Cached prefixes also still occupy the context window, but that is capacity, not price.) And the SDK's cost total is a client-side estimate from a bundled price table — the documentation says not to bill end users or trigger financial decisions from it.

6. Monitoring (LO6)

SignalDefault interval
Metrics (tokens, cost, sessions, lines of code, tool decisions)60 s
Log events5 s
Traces5 s, plus the enhanced-telemetry beta variable

Intervals as documented on 2026-09-05.

Telemetry is off until enabled with at least one exporter chosen.

⚠ Export errors fail silently by default. The agent runs on and the telemetry is dropped. A quiet collector is not evidence of health; verify arrival.

Structural by default: durations, model names and tool names on every span, and token counts when the API request returns usage data — so failed or aborted requests may omit them. Content is opt-in, escalating to raw bodies carrying whole conversations. Leave them unset unless the pipeline is approved for that data.

⚠ Attribution needs deliberate injection. Default identity attributes name the calling credential, not the end user. Inject end-user identity as resource attributes to make tool decisions and MCP activity a per-user audit trail a SIEM can consume. The session identifier, carried by default, groups calls into one conversation but says nothing about who.

Study Guide599 words

Evaluation, testing and optimization — study roadmap

Read full article

Evaluation, testing and optimization — study roadmap

This unit is CCARP-U4 · Evaluation, Testing & Optimization, 16% of the exam blueprint. It carries six official objectives across three topics, and it is the domain where most candidates lose marks to plausible-sounding answers rather than to unfamiliar material.

TopicObjectivesWhat you must be able to do
T1 · Evaluation metrics and test frameworksLO1, LO2Write criteria that can be failed, and build a set that can fail them
T2 · Testing and diagnosisLO3, LO4Compare one variable at a time, and localise a fault before replacing anything
T3 · Optimization and monitoringLO5, LO6Measure reuse before optimising, and instrument without over-collecting

The five confusions this domain tests

Each of these appears more than once in the bank, because each is a place where a true statement is used to support a conclusion it does not carry.

  1. An average is not a contract. A candidate can raise the aggregate and fail the release, because a multidimensional contract is a conjunction of criteria and one of them is now unmet.
  2. A comparison with two moving parts attributes nothing. If the prompt and the model changed together, the result describes the bundle. That is still useful, and it is not evidence about either change.
  3. A missing fact is not a reasoning failure. Ask whether the supporting fact was in the evidence. Absent means restrict the model to its documents; present and mangled means look at effort and capability. The two look identical from outside.
  4. An input-token saving is not a cost saving. Prompt caching has no effect on output token generation, and a per-request figure excludes the requests that failed and were retried.
  5. A quiet collector is not a healthy system. Export errors fail silently by default and the agent runs on regardless.

Sequence

  1. T1 first. Everything downstream assumes criteria exist and that an evaluation set represents the workload. Both the A/B objective and the optimisation objective are unanswerable without them.
  2. T2 next. Its one-variable discipline is what makes any optimisation result in T3 believable.
  3. T3 last. It is the only topic where a change can look successful on the metric the team chose and be neutral or negative on the bill.

Budget roughly equal time across the three. T1 and T3 each carry more house-authored decision practice; T2 carries the diagnosis fork that the bank tests hardest.

What to carry into the exam

For each objective, be able to state the decision, the evidence that would settle it, and the claim that evidence does not support. The third is what the Professional-level items reward, and this domain is built almost entirely from true measurements paired with unjustified conclusions.

Sources and their limits

Every factual claim is grounded in retained Anthropic documentation, quoted verbatim with a recorded retrieval date and content hash. Two cautions:

  • Prices and rates move. The cache write and read multipliers, the batch discount and the export intervals were current at the retrieval date recorded with each snapshot. The relationships they teach are stable; the numbers are not a quote.
  • Beta surfaces change. The enhanced-telemetry variable and the span names it enables are documented as beta. Re-check before implementing.

Every threshold, latency figure, cost and score in the lectures, cards, questions and project is a house fixture, labelled where it appears. They exist to make a decision checkable and they are not vendor measurements.

Hands-on Lab1,967 words

Governance project — a safety case you can hand to a reviewer

Read full article

Governance project — a safety case you can hand to a reviewer

Build a local decision harness for a customer-support agent that can read tickets, comment on them, issue refunds and close accounts. The harness uses fixed fixtures. It tests your governance decisions; it does not call a model, run a tool, evaluate anything or touch a compliance system. Every threshold, score and policy rule below is a house fixture.

Use Python 3's standard library. No credentials or paid services are required. Complete each stage before reading its expected output, then save and run your work as unit5_project.py.

Difficulty: advanced governance design. Estimated duration: 120-150 minutes. Prerequisites: the two Unit 5 topic lectures.

Stage 1 - Place every control in the right row

Maps to CCARP-U5.T1.LO1.S1 and .S2.

Three questions need three different controls, and only the third can stop an action.

RowQuestion it answers
SchemaAre the arguments well-formed?
AuthorisationMay this caller do this?
Semantic safetyShould this happen now?

Write rows_covered(design) and empty_rows(design). Classify each control in the fixture design, then run the same functions over a design that has strict mode and nothing else. Record why a system-prompt policy is not one of the three rows.

Expected output: the full design leaves no row empty. The strict-mode-only design leaves authorisation and semantic safety empty, which is the shape of the failure this objective tests. Your note says a prompt-level policy is defence in depth because retrieved text can argue with it.

Stage 2 - Classify three failures that look identical

Maps to CCARP-U5.T1.LO2.S1 and .S2.

Three confident wrong answers are supplied. Write classify(failure) returning the underlying fault and its first remedy.

CaseFact in evidenceQuote supportsStable across runs
F1NoNoYes
F2YesNoYes
F3YesYesNo

Then record the abstention path and the residual risk that survives every fix.

Expected output: knowledge from outside, unsupported claim, and instability, each with a different remedy. The abstention path gives explicit permission to admit uncertainty and to say when no relevant quotes were found. The residual-risk line states that the mitigations reduce hallucination without eliminating it, so the irreversible action keeps a check that does not depend on the model.

Stage 3 - Gate on consequence and reversibility

Maps to CCARP-U5.T1.LO3.S1 and .S2.

Write gate(action) over the four fixture actions, and review_packet(action) for anything that needs approval.

ActionHarmReversible
Read a ticketLowYes
Post an internal commentHighYes
Issue a refundHighNo
Delete an accountHighNo

Expected output: run automatically, log and alert, require approval, require approval. Every approval packet carries the evidence the recommendation rests on and an approve-or-reject action, with nothing applied before approval. You also record the verification pass that runs before findings are surfaced, so reviewers are not drowned.

Stage 4 - Split the responsibility line

Maps to CCARP-U5.T2.LO4.S1 and .S2.

Name what the platform provides and what your deployment still owns. Record which terms govern each access path, both residency controls, the endpoint choice they imply, and the date from which audit history exists.

Expected output: both columns are filled. Direct commercial access is governed by the provider's terms with the addendum incorporated; the third-party marketplace path is governed by that platform's terms. Data residency and inference residency are named separately and a regional endpoint is chosen because both must hold. Audit history begins at enablement, and the earlier gap cannot be recovered. Your claim line says the platform supports compliance; your not-claimed line says this deployment is not thereby compliant.

Stage 5 - Write a fairness criterion that can fail

Maps to CCARP-U5.T2.LO5.S1 and .S2.

Write is_criterion(entry) requiring a threshold, a population and a named instrument. Then score the supplied slices against it.

SliceScore
General0.962
Assisted technology0.947
Non-native speakers0.883

Decide the release, publish the exclusions, and name the appeal path.

Expected output: the criterion is checkable. The aggregate passes the 0.92 threshold and the release fails, because one slice does not — which is the entire reason for scoring per slice. Your published exclusions say the mitigations reduce error without eliminating it, that auditability comes from asking for quotes rather than by default, and that no claim of verified freedom from bias is made.

Reference solution

python
"""Unit 5 project reference solution. Standard library only; no network calls.""" import json # ------------------------------------------------------------------ Stage 1 # Three questions, three controls. Only the third can stop an action. ROWS = ("schema", "authorization", "semantic_safety") DESIGN = { "strict_tool_use": "schema", "tenant_and_role_check": "authorization", "consequence_gate": "semantic_safety", "system_prompt_policy": "defence_in_depth", # not a row; it can be argued with } def rows_covered(design): return {row: sorted(k for k, v in design.items() if v == row) for row in ROWS} def empty_rows(design): return sorted(row for row, controls in rows_covered(design).items() if not controls) stage1 = { "rows": rows_covered(DESIGN), "empty_rows": empty_rows(DESIGN), "prompt_policy_is_not_a_row": DESIGN["system_prompt_policy"] == "defence_in_depth", "why": "retrieved text can argue with a check that lives inside the prompt", } # A design that trusts strict mode alone leaves two rows empty. NAIVE = {"strict_tool_use": "schema"} stage1["naive_design_empty_rows"] = empty_rows(NAIVE) # ------------------------------------------------------------------ Stage 2 # Three failures that look identical from outside: a confident wrong answer. FAILURES = [ {"id": "F1", "fact_in_evidence": False, "quote_supports": False, "stable_across_runs": True}, {"id": "F2", "fact_in_evidence": True, "quote_supports": False, "stable_across_runs": True}, {"id": "F3", "fact_in_evidence": True, "quote_supports": True, "stable_across_runs": False}, ] def classify(failure): if not failure["fact_in_evidence"]: return ("knowledge_from_outside", "instruct it to use only the provided documents, not its general knowledge") if not failure["quote_supports"]: return ("unsupported_claim", "require a supporting quote per claim, and retract where none is found") if not failure["stable_across_runs"]: return ("instability", "repeat the prompt and compare; inconsistency can itself indicate hallucination") return ("unclassified", "probe further before changing any component") stage2 = { "classified": {f["id"]: classify(f) for f in FAILURES}, "abstention_path": "explicit permission to admit uncertainty, and to state when no " "relevant quotes were found", "residual_risk": "the mitigations reduce hallucination without eliminating it, so the " "irreversible action keeps a check that does not depend on the model", } # ------------------------------------------------------------------ Stage 3 ACTIONS = [ {"id": "A1", "name": "read a ticket", "harm": "low", "reversible": True}, {"id": "A2", "name": "post an internal comment", "harm": "high", "reversible": True}, {"id": "A3", "name": "issue a refund", "harm": "high", "reversible": False}, {"id": "A4", "name": "delete an account", "harm": "high", "reversible": False}, ] def gate(action): if action["harm"] == "low" and action["reversible"]: return "run_automatically" if action["reversible"]: return "log_and_alert" return "require_approval" def review_packet(action): """A gate with no evidence is a rubber stamp; evidence with no action is a reading exercise. Both, or the gate is ceremonial.""" return {"evidence": "quotes and sources for each claim the recommendation rests on", "action": f"approve or reject: {action['name']}", "applied_before_approval": False} stage3 = { "gates": {a["id"]: gate(a) for a in ACTIONS}, "packets": {a["id"]: review_packet(a) for a in ACTIONS if gate(a) == "require_approval"}, "verify_before_surfacing": "an adversarial pass over each finding, so reviewers are not " "drowned in false positives", } # ------------------------------------------------------------------ Stage 4 PLATFORM_SIDE = [ "support for data subject rights, retention policies and deletion capabilities", "customer data from commercial deployments not used to train models by default", "a Data Processing Addendum defining roles and responsibilities", "certifications covering the platform", ] CUSTOMER_SIDE = [ "responding to data subject requests within the statutory deadline", "the organisation's own retention policy and its enforcement", "evidence about this deployment, for this auditor", "workforce training and access review", ] ACCESS_PATHS = {"direct_commercial": "provider commercial terms, addendum incorporated", "third_party_marketplace": "that platform's terms of service"} RESIDENCY = {"data": "where prompts, outputs and history are stored", "inference": "where requests are processed and responses generated"} stage4 = { "platform_side": PLATFORM_SIDE, "customer_side": CUSTOMER_SIDE, "both_sides_named": bool(PLATFORM_SIDE) and bool(CUSTOMER_SIDE), "access_paths": ACCESS_PATHS, "residency_controls": RESIDENCY, "endpoint": "regional, because both residencies must be satisfied together", "audit_history_available_from": "the date the activity feed was enabled; earlier " "activity is not backfilled and cannot be recovered", "claim": "the platform supports compliance with industry and regional standards", "claim_not_made": "that this deployment is thereby compliant", } # ------------------------------------------------------------------ Stage 5 SLICES = {"general": 0.962, "assisted_technology": 0.947, "non_native_speakers": 0.883} FAIRNESS = {"threshold": 0.92, "population": "1,000 tickets per slice", "instrument": "the same code-graded routing check used for task fidelity"} def is_criterion(entry): return isinstance(entry.get("threshold"), (int, float)) and bool(entry.get("population")) \ and bool(entry.get("instrument")) def slice_verdict(scores, threshold): return {name: score >= threshold for name, score in scores.items()} verdicts = slice_verdict(SLICES, FAIRNESS["threshold"]) stage5 = { "criterion": FAIRNESS, "is_checkable": is_criterion(FAIRNESS), "per_slice": verdicts, "aggregate": round(sum(SLICES.values()) / len(SLICES), 4), "aggregate_would_pass": round(sum(SLICES.values()) / len(SLICES), 4) >= FAIRNESS["threshold"], "release": all(verdicts.values()), "published_exclusions": [ "the mitigations reduce error without eliminating it", "responses are auditable when quotes and sources are requested, not by default", "no claim that the system is verified free of bias", ], "appeal_path": "a named route for a user to contest an outcome, and a correction record", } # ------------------------------------------------------------------ Checks assert stage1["empty_rows"] == [] assert stage1["naive_design_empty_rows"] == ["authorization", "semantic_safety"] assert stage1["prompt_policy_is_not_a_row"] assert [stage2["classified"][k][0] for k in ("F1", "F2", "F3")] == \ ["knowledge_from_outside", "unsupported_claim", "instability"] assert stage3["gates"] == {"A1": "run_automatically", "A2": "log_and_alert", "A3": "require_approval", "A4": "require_approval"} assert all(not p["applied_before_approval"] for p in stage3["packets"].values()) assert stage4["both_sides_named"] and len(PLATFORM_SIDE) >= 3 and len(CUSTOMER_SIDE) >= 3 assert set(stage4["access_paths"]) == {"direct_commercial", "third_party_marketplace"} assert "that platform's terms" in stage4["access_paths"]["third_party_marketplace"] assert set(stage4["residency_controls"]) == {"data", "inference"} assert stage4["endpoint"].startswith("regional") assert "not backfilled" in stage4["audit_history_available_from"] assert stage4["claim"].startswith("the platform supports compliance") assert "compliant" in stage4["claim_not_made"] assert stage5["is_checkable"] and not is_criterion({"threshold": 0.92, "population": "x"}) # The aggregate passes and the release does not: that is the whole point. assert stage5["aggregate_would_pass"] and not stage5["release"] assert verdicts["non_native_speakers"] is False print(json.dumps({"stage1": stage1, "stage2": stage2, "stage3": stage3, "stage4": stage4, "stage5": stage5}, indent=2)) print("\nall stage checks passed")

Acceptance checklist

  • The strict-mode-only design reports two empty rows.
  • Stage 2 returns three different fault classes with three different remedies.
  • Every approval packet carries both evidence and an action, and applies nothing first.
  • Stage 4 fills the customer column, not just the platform column.
  • Stage 5's aggregate passes while the release fails.
  • The exclusions list contains no claim of verified fairness.

Explain the result before extending it

Three stages have an answer that is easy to produce and hard to justify.

  • Stage 1. The strict-mode-only design is not a straw man. It is what a team builds when a passing check feels like a safe system, and the two empty rows are invisible precisely because the one that is filled works perfectly.
  • Stage 3. The middle row is the one people argue about. Logging and alerting on a high-harm reversible action is a real decision with a real cost: someone has to read the alert in time. Say who.
  • Stage 5. The aggregate is not wrong; it is answering a different question. Reporting it alone is how a system ships while failing the people least able to complain about it.

Cleanup

Nothing to clean up: no credentials, no network calls, no files written outside your working directory. Delete unit5_project.py when you are done, or keep it as the starting point for the Unit 6 project.

What this project does not establish

These fixtures test your decisions and interfaces. They do not measure a real model, a real deployment or a real compliance posture, and nothing here is legal advice. Passing every stage means your governance records the right decisions with the right evidence, which is what this domain's objectives assess. Whether a given deployment satisfies a given regulation is a question for the organisation and its advisers.

Study Guide1,033 words

Governance, safety and risk — reference

Read full article

Governance, safety and risk — reference

A decision-table companion. Each table names a decision, the documented input that settles it, and the claim it does not license.

1. The three rows (LO1)

CheckWhat it settlesWhat it does not
Schema validityArguments are well-typedWhether the caller may act
AuthorisationThis caller may do thisWhether it is sensible now
Semantic safetyThis should happen nowNothing further; this is the decision

Strict mode delivers row one only: it guarantees the tool inputs match your JSON Schema by constraining sampling to schema-valid outputs. Without it, the model might return incompatible types or omit required fields, breaking your functions.

⚠ The decision that stops an action must live outside the model, on the resolved call. Content returned from tools, documents and searches is untrusted data and must never override the original request — so a check inside the prompt is a check the injected text gets to argue with.

Untrusted content

PlacementGuidance
Tool result blocksThe recommended channel
System prompt or plain user textAdvised against
Your own rules inside a tool resultMay be ignored or flagged as injection

JSON-encode third-party strings rather than concatenating them: the escaping gives unambiguous delimiters, so an attacker cannot close a quote or tag to break out. Underneath everything, least privilege — no secrets the agent does not need, sandboxed tools, permissions scoped as narrowly as possible — bounds what a successful injection reaches.

⚠ Strict tool use is eligible for protected health information, but that information must not appear in tool schema definitions (property names, enum, const, pattern). Compiled schemas are cached separately for up to 24 hours since last use and do not carry the same protections. Such data belongs in message content.

2. Failure taxonomy (LO2)

ObservedUnderlying failureFirst remedy
Fact absent from the evidenceKnowledge from outsideRestrict to the provided documents
No quote supports the claimUnsupported claimRequire a quote per claim; retract otherwise
Answers differ between runsInstabilityRepeat and compare; inconsistency can indicate hallucination

Abstention is a design element, not a failure: explicitly give the model permission to admit uncertainty, and to state when no relevant quotes were found. Both convert a gap the system would paper over into one it reports.

⚠ The mitigations significantly reduce hallucinations without eliminating them, and critical information should always be validated, especially for high-stakes decisions. If an action is irreversible, the design needs a check that does not depend on the model having been right.

3. Human-in-the-loop (LO3)

CapabilityWhat it does
PermissionsControl which tools run automatically, which need approval
HooksRun custom code at key points in the agent lifecycle
SubagentsSpawn specialised agents for focused subtasks

Gate matrix (house, built on the documented permission control and the instruction to validate high-stakes decisions):

ConsequenceReversibleGate
LowYesRun automatically
HighYesLog and alert
HighNoRequire approval

A gate is only real if it carries evidence — quotes and sources for the claims the recommendation rests on — and a recommended action to approve or reject, with nothing applied until approval. Reduce the volume reaching a reviewer with an adversarial verification pass before surfacing, which the documentation credits with more real issues reported and fewer false positives.

4. Regulatory compliance (LO4)

The documentation saysIt does not say
Supports compliance with industry and regional standardsConfers compliance on your deployment
An addendum defining roles and responsibilitiesThat it assumes your obligations
Data subject rights, retention and deletion supportThat it answers requests for you

The addendum is automatically incorporated into the commercial terms, so accepting those accepts it. ⚠ Access through a third-party platform is governed by that platform's terms of service — eligibility is a per-access-path check.

ControlFixes
Data residencyWhere prompts, outputs and history are stored
Inference residencyWhere requests are processed and responses generated
Regional endpointGuarantees both stay in the specified region

Global endpoints route dynamically for maximum uptime with no pricing premium — a good default without a residency requirement, and the wrong one with. By default, customer data from commercial deployments is not used to train models.

⚠ An audit trail starts when you switch it on. Activity feed retention is six years forward; recording is not retroactive, earlier activity is not backfilled, and a gap while recording was off cannot be recovered. Feed retention is independent of the content retention policy.

5. Ethics, bias and transparency (LO5)

Even hazy topics such as ethics and safety can be quantified. A criterion needs three things:

ElementExample
QuantityUnder 0.1% of outputs
PopulationAcross 10,000 trials
InstrumentFlagged by the content filter

Most use cases need multidimensional evaluation along several success criteria — the documented point is about criteria, not groups. Scoring per slice rather than blended is the house step layered on it, together with an evaluation set that mirrors the real distribution and its named edge cases. Binary classification suits a present-or-absent judgement such as whether a response contains protected information.

HonestNot supportable
Errors greatly reducedVerified free of bias
Auditable when quotes are requestedAuditable by default
Validate high-stakes decisionsSafe to automate

Publish the right-hand column as excluded, and give users an appeal path. Criteria must align with the application's purpose and users, so a threshold copied from another system carries a justification nobody made for this one.

Study Guide587 words

Governance, safety and risk — study roadmap

Read full article

Governance, safety and risk — study roadmap

This unit is CCARP-U5 · Governance, Safety & Risk Management, 14% of the blueprint. It carries five official objectives across two topics, and it is the domain where a confident, well-formed, entirely wrong answer does the most damage.

TopicObjectivesWhat you must be able to do
T1 · Guardrails, risks, human-in-the-loopLO1, LO2, LO3Place each control in the right row, name the failure before fixing it, and gate on consequence and reversibility
T2 · Compliance and ethicsLO4, LO5Verify eligibility per access path, split responsibility explicitly, and make an ethical requirement measurable

The five confusions this domain tests

  1. Well-formed is not authorised. Strict mode guarantees the tool inputs match your schema. It decides nothing about whether this caller may take this action.
  2. A policy in the prompt is a policy retrieved text can argue with. The decision that stops an action has to be taken outside the model, on the resolved call.
  3. A missing fact, an unsupported claim and an unstable answer look identical from outside. Three faults, three different probes, three different remedies.
  4. Supports compliance is not confers compliance. The addendum defines roles; the customer keeps its own. Access through a third-party platform is governed by that platform's terms.
  5. An aggregate is where a group goes missing. A fairness number that passes overall can hide a slice that fails.

Sequence

  1. T1 first, in objective order. LO1 gives you the three-row vocabulary; LO2 gives you the failure taxonomy that decides which control to reach for; LO3 gives you the gate that turns both into a decision somebody owns.
  2. T2 second. Its compliance half is a reading exercise in careful verbs, and its ethics half reuses the measurable-criteria material from Unit 4 with fairness in place of accuracy.

Budget slightly more time on T1: it carries three objectives and six house skills against T2's two and four.

What to carry into the exam

For each objective, be able to state the decision, the evidence that would settle it, and the claim that evidence does not support. This domain is built almost entirely from true statements used to support conclusions they do not carry — a passing schema check read as a permission, a certification read as a compliant deployment, an evaluation read as a verified property.

Sources and their limits

Every factual claim is grounded in retained documentation, quoted verbatim with a recorded retrieval date and content hash. Three cautions:

  • This unit teaches architecture, not law. The documented material describes what the platform provides and what its terms allocate. Whether a given deployment satisfies a given regulation is a question for the organisation and its advisers, and nothing here answers it.
  • The objective names FedRAMP; this package does not teach it. No retained snapshot contains FedRAMP material, so nothing here is authored about it rather than invented. Study it from the certification body's own references.
  • Scope statements are per product and per access path. Eligibility described for one product does not extend to another, and reaching the same models through a third-party platform changes which terms govern.
  • Certifications and regional availability change. They were current at the retrieval date recorded with each snapshot. Check the current position before relying on one.

Every threshold, score and policy rule used in an exercise is a house fixture, labelled where it appears.

Ready to practice? Jump straight in — no sign-up needed.

Take practice tests, review flashcards, and read study notes right now.

Take a Practice Test

Claude Certified Architect - Professional (CCAR-P) Practice Questions

Try 15 sample questions from a bank of 442. Answers and detailed explanations included.

Q1medium

A compliance reviewer asks what agent content leaves the deployment with telemetry enabled and no additional variables set. What is the documented answer?

A.

Durations, model names and tool names are recorded, while the content the agent reads and writes is not recorded by default

B.

Every user prompt is recorded on the interaction span

C.

Tool input arguments are recorded on tool result events

D.

Complete request and response bodies are recorded as log events under the default configuration, without any opt-in being required

Show answer & explanation

Correct Answer: A

Durations, model names and tool names are recorded, while the content the agent reads and writes is not recorded by default — Correct: The documentation describes telemetry as structural by default and excludes read and written content.

Every user prompt is recorded on the interaction span — Incorrect: Prompt text requires an explicit opt-in variable.

Tool input arguments are recorded on tool result events — Incorrect: Tool arguments require their own opt-in variable.

Complete request and response bodies are recorded as log events under the default configuration, without any opt-in being required — Incorrect: Raw bodies require a separate opt-in variable and carry the whole conversation.

Answer: A

Q2medium

A research assistant uses the same large team for simple lookups and broad investigations. The lead agent often spends excessive effort on easy requests. Which effort policy best reflects the published multi-agent research design?

A.

Allocate the budget from the length of the user prompt, then keep it fixed during the task

B.

Scale effort to task complexity and give parallel researchers clearly divided responsibilities

C.

Allocate equal effort to each retrieved document, so that every source receives the same treatment

D.

Choose the team size from the model context limit, then use that team for all requests

Show answer & explanation

Correct Answer: B

Anthropic reports task-dependent rules of thumb for its research system. They are examples of an allocation policy, not universal production limits.

Allocate the budget from the length of the user prompt, then keep it fixed during the task — Incorrect: Prompt length is not the cited measure of research complexity and can misclassify concise but difficult questions.

Scale effort to task complexity and give parallel researchers clearly divided responsibilities — Correct: The source describes different effort levels for fact-finding, comparisons and complex research, with divided responsibilities for the larger team.

Allocate equal effort to each retrieved document so every source receives the same treatment — Incorrect: Retrieved document count is not the cited allocation basis; equal effort can overinvest in low-value material.

Choose the team size from the model context limit, then use that team for all requests — Incorrect: A context limit constrains implementation but does not express the task-dependent scaling policy described in the source.

Answer: B

Q3hard

A design places its only policy check in the system prompt, ahead of a tool that moves money. What is the documented weakness?

A.

Content returned from tools and documents is untrusted and must never override the request, so the decision has to be made outside the model on the resolved call

B.

The system prompt is simply too short to carry a policy of the length this deployment needs, which leaves the check itself with nowhere sensible to live in the design

C.

The tool has not been set to strict mode

D.

The model cannot interpret a written policy

Show answer & explanation

Correct Answer: A

Content returned from tools and documents is untrusted and must never override the request, so the decision has to be made outside the model on the resolved call — Correct: This is the documented policy statement, and its consequence is that a check living inside the prompt is something retrieved text can argue with.

The system prompt is simply too short to carry a policy of the length this deployment needs, which leaves the check itself with nowhere sensible to live in the design — Incorrect: Length is not the failure.

The tool has not been set to strict mode — Incorrect: Strict mode would type the arguments and decide nothing about permission.

The model cannot interpret a written policy — Incorrect: Interpretation is not the issue; authority is.

Answer: A

Q4easy

A conversation fails halfway through. What was spent?

A.

Nothing at all, because failed conversations are not billed

B.

The tokens consumed up to the point of failure

C.

Only the input tokens

D.

Only the tokens of the final turn

Show answer & explanation

Correct Answer: B

Nothing at all, because failed conversations are not billed — Incorrect: No such exemption is documented.

The tokens consumed up to the point of failure — Correct: This is the documented position, and both success and error results carry usage and a total cost.

Only the input tokens — Incorrect: Both input and output up to the failure were consumed.

Only the tokens of the final turn — Incorrect: The whole conversation to that point was consumed.

Answer: B

Q5medium

A stakeholder reads "Fast" in the comparison table and asks for that as a guarantee. What does the documentation say the label means?

A.

A committed upper bound on response time for that model

B.

A median figure measured across every customer of the service taken over the whole course of the preceding quarter of traffic

C.

It is relative to the current lineup, and actual latency depends on prompt length, output length and thinking effort

D.

A guarantee that holds for prompts below the context limit

Show answer & explanation

Correct Answer: C

A committed upper bound on response time for that model — Incorrect: No bound is attached to the label.

A median figure measured across every customer of the service taken over the whole course of the preceding quarter of traffic — Incorrect: No such measurement basis is documented.

It is relative to the current lineup, and actual latency depends on prompt length, output length and thinking effort — Correct: This is the documented meaning, and the three dependencies are the reason the label cannot become a commitment.

A guarantee that holds for prompts below the context limit — Incorrect: Context length is not what qualifies the label.

Answer: C

Q6easy

What is the architectural distinction Anthropic draws between workflows and agents?

A.

Workflows are the experimental and unsupported form; agents are the generally available production version of that same idea

B.

Workflows use larger models for planning; agents use smaller ones so the loop stays affordable

C.

Workflows orchestrate LLMs through predefined code paths; agents let the LLM dynamically direct its own process and tool usage

D.

Workflows run on-premises against your own data; agents run in the cloud against the vendor's

Show answer & explanation

Correct Answer: C

This is Anthropic's canonical distinction: workflows are systems where LLMs and tools are orchestrated through predefined code paths, while agents are systems where LLMs dynamically direct their own processes and tool usage, maintaining control over how they accomplish tasks.

Workflows use larger models; agents use smaller models — Incorrect. Model size does not determine whether control flow is fixed or model-directed.

Workflows run on-premises; agents run in the cloud — Incorrect. Either pattern can be deployed in different environments.

Workflows are experimental; agents are generally available — Incorrect. The distinction describes control flow, not a maturity classification.

Answer: C

Q7medium

A team caps responses with the output token limit to control latency. Support now receives answers that stop mid-sentence. What does the documentation say about this technique?

A.

The limit guarantees a complete but shorter answer

B.

The response is automatically summarized down until it fits inside whatever output limit has been configured

C.

The request is retried at a higher limit

D.

The response is cut off, perhaps mid-word, so it is a blunt technique that may require post-processing

Show answer & explanation

Correct Answer: D

The limit guarantees a complete but shorter answer — Incorrect: No completeness guarantee is documented; the cut is mechanical.

The response is automatically summarized down until it fits inside whatever output limit has been configured — Incorrect: No automatic summarization is described.

The request is retried at a higher limit — Incorrect: No automatic retry is described.

The response is cut off, perhaps mid-word, so it is a blunt technique that may require post-processing — Correct: This is the documented behaviour, and the documentation suggests it suits short answers that begin with the result.

Answer: D

Q8hard

A design relies entirely on prompt-level mitigations ahead of an irreversible action. What does the documentation imply about that design?

A.

The mitigations are sufficient once all of them are applied

B.

The action should simply be made faster to execute, so that any errors it makes are noticed rather sooner than they would otherwise have been noticed

C.

The model should be replaced with a more capable one

D.

The mitigations reduce the failure without eliminating it, so the action needs a validation that does not depend on the model having been right

Show answer & explanation

Correct Answer: D

The mitigations are sufficient once all of them are applied — Incorrect: The documentation explicitly declines to claim sufficiency.

The action should simply be made faster to execute, so that any errors it makes are noticed rather sooner than they would otherwise have been noticed — Incorrect: Speed does not change correctness.

The model should be replaced with a more capable one — Incorrect: Capability is not the documented remedy for a residual failure mode.

The mitigations reduce the failure without eliminating it, so the action needs a validation that does not depend on the model having been right — Correct: This is the documented position, and it is an architectural consequence rather than a prompting one.

Answer: D

Q9easy

Where does a project-scoped tool server live, and who gets it?

A.

In the home directory configuration, and only you

B.

In the shared project settings file, and everyone who clones the repository and then trusts the folder

C.

In a file at the project root, and everyone on the team once it is in version control

D.

In managed settings, and everyone in the organization

Show answer & explanation

Correct Answer: C

In the home directory configuration, and only you — Incorrect: That describes local and user scope, which stay private to you.

In the shared project settings file, and everyone who clones the repository and then trusts the folder — Incorrect: Tool servers are configured in their own file rather than in the settings file.

In a file at the project root, and everyone on the team once it is in version control — Correct: This is the documented project scope, and the documentation says to check the file into version control.

In managed settings, and everyone in the organization — Incorrect: Administrators can deploy servers at the enterprise level, and that is a separate managed path.

Answer: C

Q10medium

A workload must keep both storage and processing inside one region. Which documented endpoint choice does that?

A.

A global endpoint, which routes each request to whichever region is nearest

B.

A regional endpoint, which guarantees both stay within the specified region

C.

Either, since both are region-locked

D.

Neither; the guarantee is contractual only

Show answer & explanation

Correct Answer: B

A global endpoint, which routes each request to whichever region is nearest — Incorrect: Global endpoints route dynamically for maximum uptime, with no pricing premium.

A regional endpoint, which guarantees both stay within the specified region — Correct: This is the documented guarantee.

Either, since both are region-locked — Incorrect: Only one of them carries it.

Neither; the guarantee is contractual only — Incorrect: The documentation describes it as a routing property.

Answer: B

Q11medium

A stakeholder opens discovery with "we need Claude Fable 5.1 for the support desk". Which documented step does that skip?

A.

Establishing the criteria the choice will be judged against, which the documentation asks you to evaluate first

B.

Confirming that the chosen model is actually available on the particular platform the team intends to deploy it to

C.

Estimating the token volume the desk will generate

D.

Writing the evaluation harness that will grade the model

Show answer & explanation

Correct Answer: A

Establishing the criteria the choice will be judged against, which the documentation asks you to evaluate first — Correct: This is the documented sequence: capabilities, speed, cost and effort are evaluated first, and the documentation names a default starting model rather than a required one.

Confirming that the chosen model is actually available on the particular platform the team intends to deploy it to — Incorrect: Availability matters once a model is a candidate, and here no criterion has made it one.

Estimating the token volume the desk will generate — Incorrect: Volume is one input to the cost criterion, which has not been stated yet.

Writing the evaluation harness that will grade the model — Incorrect: A harness grades against criteria, so the criteria come first.

Answer: A

Q12easy

What does prompt caching optimise, according to the documentation?

A.

The number of output tokens that the model ends up generating in reply to the request

B.

Processing time and cost for repetitive tasks or prompts with consistent elements

C.

The size of the model's context window

D.

The factual accuracy of the response

Show answer & explanation

Correct Answer: B

The number of output tokens that the model ends up generating in reply to the request — Incorrect: The documentation states caching has no effect on output token generation.

Processing time and cost for repetitive tasks or prompts with consistent elements — Correct: This is the documented purpose, stated in those terms.

The size of the model's context window — Incorrect: Caching does not change the window.

The factual accuracy of the response — Incorrect: Caching does not change what the model produces.

Answer: B

Q13medium

The deployment reaches the model through Amazon Bedrock. Whose retirement date applies?

A.

Anthropic’s published date, because it is the same model

B.

Whichever date falls later

C.

Amazon Bedrock’s, which sets its own lifecycle dates

D.

The date in the customer’s support agreement

Show answer & explanation

Correct Answer: C

Anthropic’s published date, because it is the same model — Incorrect: The documented commitment covers Anthropic-operated platforms, and Bedrock is not one of them.

Whichever date falls later — Incorrect: No combination rule is documented.

Amazon Bedrock’s, which sets its own lifecycle dates — Correct: This is the documented position, stated alongside the same for Google Cloud.

The date in the customer’s support agreement — Incorrect: A support agreement does not set a model lifecycle.

Answer: C

Q14hard

In a house-authored pilot, a retrieval design and a multi-agent design both meet a 95% resolution floor. Retrieval resolves 96% at $0.04 per task and p95 3 seconds; multi-agent resolves 97% at $0.30 and p95 18 seconds. The agreed limits are $0.10 and p95 5 seconds. Which architecture is ready under these criteria?

A.

The retrieval design, because it meets the outcome, cost and latency limits

B.

The multi-agent design, because it reports the higher resolution percentage overall

C.

Both designs, because both exceed the resolution floor

D.

Neither design, because the resolution percentages differ

Show answer & explanation

Correct Answer: A

These metrics are illustrative. The vendor guidance supports fitting architecture to the need; it does not supply these benchmark values.

The retrieval design, because it meets the outcome, cost and latency limits — Correct. All three stated criteria matter; the simpler candidate meets them.

The multi-agent design, because it has the higher resolution percentage — Incorrect. The extra percentage point does not excuse failing the agreed cost and latency limits.

Both designs, because both exceed the resolution floor — Incorrect. Meeting the outcome floor alone is insufficient.

Neither design, because the resolution percentages differ — Incorrect. The criteria permit different resolution rates above the floor; they do not require equality.

Answer: A

Q15medium

A team says it solved capability bloat by caching its complete tool catalog. The bill falls on cache hits, but the input token count is unchanged. Which interpretation should the architect use?

A.

The cache is broken because token count must fall on a hit

B.

Caching changed repeat-input economics, while context pressure remains

C.

Cached definitions become inaccessible to tool selection

D.

Caching automatically removes definitions for tools not selected

Show answer & explanation

Correct Answer: B

The cache is broken because token count must fall on a hit — Incorrect: The documentation distinguishes cached-token cost from context occupancy; an unchanged token count is not evidence of cache failure.

Caching changed repeat-input economics, while context pressure remains — Correct: The observation matches the documented behavior: caching lowers the cost of repeated prefixes without removing their context tokens.

Cached definitions become inaccessible to tool selection — Incorrect: Caching reuses the prefix; it does not turn those definitions into an unavailable catalog.

Caching automatically removes definitions for tools not selected — Incorrect: On-demand discovery, not caching alone, avoids loading unused definitions.

Answer: B

These are 15 of 442 questions available. Take a practice test →

Claude Certified Architect - Professional (CCAR-P) Flashcards

275 flashcards for spaced-repetition study. Showing 30 sample cards below.

Budget context and choose the right reuse mechanism — flashcards(14 cards shown)

Question

Does the context window include the response being generated?

Answer

Yes. Plan space for output as well as all submitted input.

Question

Which request components are often missed when counting only the latest user message?

Answer

System instructions, earlier messages, tool definitions and returned tool content.

Question

How do the three reported input-token categories combine for context accounting?

Answer

Add ordinary input, cache-read input and cache-creation input; each category counts once.

Question

What does compaction do to earlier conversation material?

Answer

It summarizes it. Required decisions, evidence and unresolved scope still need to survive for the next task.

Question

What should be tested after adopting a new context summary?

Answer

A representative continuation that needs the retained decision conditions and unresolved evidence.

Question

House capacity is 40k tokens, with 6k output and 2k headroom reserved. What is the maximum planned input?

Answer

32k tokens: 40k - 6k - 2k. Cached input counts within that allowance.

Question

An earlier review approved a supplier only for Region A. After compaction, the agent approves Region B using the saved conclusion “supplier approved.” What did the continuation lose?

Answer

The geographic condition and its supporting evidence. The shortened conclusion expanded a scoped approval into a general one.

Question

What order does the cached prompt prefix follow?

Answer

Tools, then system, then messages, through the designated cache boundary.

Question

What is an Agent Skill?

Answer

A reusable filesystem package of instructions and optional resources for relevant tasks.

Question

Where should a cache boundary go when policy is stable but the timestamp and request vary?

Answer

At the end of the identical policy prefix, before the varying suffix.

Question

Which counters distinguish a cache write from a cache read?

Answer

cache_creation_input_tokens and cache_read_input_tokens.

Question

How does a Skill use progressive loading?

Answer

  1. Name and description support discovery.
  2. Relevant instructions load when triggered.
  3. Referenced resources load when needed.

Question

A five-minute cache write starts at 10:00 and its response ends at 10:04. Is a first reuse at 10:05:30 within that lifetime?

Answer

No. The lifetime starts with the request, not response completion; no intervening refresh was specified.

Question

How can a Claude Code project split reusable testing and style instructions without packaging them as separate Skills?

Answer

Keep modular instruction files in .claude/rules/. This organizes project guidance; cache reuse and task-triggered Skills are separate mechanisms.

Build prompt templates with explicit trust and output boundaries — flashcards(6 cards shown)

Question

What should separate reusable instructions from variable task input?

Answer

Explicit sections or descriptive tags that make each category’s role clear.

Question

What must an output contract specify for a structured consumer?

Answer

Required fields, allowed values, format and relevant constraints.

Question

Do XML tags grant system authority to text inside them?

Answer

No. They help structure a prompt. The application must still distinguish its instructions from untrusted task data.

Question

Why is a valid JSON response insufficient for a permitted action?

Answer

It can still identify the wrong case or propose a policy-violating action. Validate those conditions before execution.

Question

The prompt uses current policy but the application gate uses yesterday’s policy revision. What still needs repair?

Answer

Bind the gate to the required current revision and replay affected cases; prompt correctness cannot repair stale application state.

Question

What should a grounded assistant do when the required policy evidence is missing?

Answer

Disclose the gap and follow the task’s clarification or review path; do not turn an unsupported claim into an accepted action.

Build retrieval that can be cited, and connect it the documented way — flashcards(10 cards shown)

Question

Why can an isolated chunk retrieve poorly even when it reads well in place?

Answer

Because a chunk split for retrieval can lack sufficient context once separated from its document. Adding relevant context to each chunk before embedding is the documented remedy.

Question

When is the cost of chunk contextualization paid?

Answer

Once at ingestion time, not during every query. That is the documented contrast with techniques that add latency and cost to each search.

Question

What may be used as the source identity of a search result?

Answer

Any stable string — a URL, or an internal identifier such as a knowledge-base key. Choosing an identifier that survives re-publication keeps citations resolvable when public URLs change.

Question

How do you give a reviewer paragraph-level rather than document-level citations?

Answer

Break long content into logical text blocks. The documentation names this as what gives Claude finer citation boundaries, alongside returning only the most relevant results to avoid context overflow.

Question

Retrieval got worse after adopting contextual embeddings. Which documented cause is checked first?

Answer

Truncation. Some embedding models have fixed input token limits, so a contextualized chunk can be cut. The documented response is an embedding model with a larger context window.

Question

What does Pass@k measure, and what does a published Pass@k number not establish?

Answer

It measures whether the golden document appears in the first k retrieved results. A published figure is evidence from that evaluation set, not a guarantee for another corpus, and each technique still adds complexity and cost.

Question

Which retrieval method excels at meaning, and which at exact terms?

Answer

Semantic search excels at meaning and context, including paraphrases, but can miss exact keyword matches. Keyword ranking excels at finding specific terms such as function names, but lacks semantic understanding.

Question

What does BM25 improve on, and how?

Answer

It improves on TF-IDF by accounting for document length and term saturation. It is a probabilistic ranking function used in production search engines for keyword relevance.

Question

In the documented hybrid design, what text does the keyword index actually search?

Answer

Both the raw chunk and the generated contextual description. That lets a keyword match land on terminology present in either the original text or the explanatory context.

Question

Retrieval returned the right chunk and the answer still asserts something unsupported. Which controls apply?

Answer

Answer-side controls: restrict the model to the provided documents, and have it support each claim with a quote and retract any claim it cannot support. Retrieval was not the failure, so changing k or the embedding model will not fix it.

Showing 30 of 275 flashcards. Study all flashcards →

Ready to ace Claude Certified Architect - Professional (CCAR-P)?

Access all 442 practice questions, study notes, and flashcards — no sign-up required.

Start Studying — Free