🤖

🤖 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

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.

Q1easy

A team is about to commit a hook to its shared settings file. What does the documentation say to weigh first?

A.

That the hook will be reported in the run log of anyone who executes it, so a teammate can see what ran before they trust the folder

B.

That a committed hook cannot later be overridden by a teammate

C.

That command hooks execute shell commands with the full permissions of the user who runs them

D.

That the hook will only run for teammates who have write access

Show answer & explanation

Correct Answer: C

That the hook will be reported in the run log of anyone who executes it, so a teammate can see what ran before they trust the folder — Incorrect: Hook execution is recorded in the debug log, which is per session and local, so nothing about the hook reaches a teammate as a report.

That a committed hook cannot later be overridden by a teammate — Incorrect: Hook entries merge across levels rather than replacing each other, so a teammate can add without removing.

That command hooks execute shell commands with the full permissions of the user who runs them — Correct: This is the documented warning: such a hook can modify, delete or access any file that user account can, which is why the documentation asks you to review and test one before adding it.

That the hook will only run for teammates who have write access — Incorrect: Repository write access governs who can change the file, not who runs the hook.

Answer: C

Q2hard

A team wants a check to run on each file edit and to be able to stop that edit when the check fails. Which documented choice does that?

A.

An asynchronous hook, so the session is not delayed

B.

A per-turn hook on prompt submission

C.

A synchronous hook on the pre-tool-call event, which is documented as blocking the tool call

D.

A hook on the post-tool-call event, which reports the failure once the edit has already been made

Show answer & explanation

Correct Answer: C

An asynchronous hook, so the session is not delayed — Incorrect: An asynchronous hook cannot block or control behaviour, because the action it would have controlled has already completed.

A per-turn hook on prompt submission — Incorrect: A prompt-submission hook fires once per turn rather than once per edit.

A synchronous hook on the pre-tool-call event, which is documented as blocking the tool call — Correct: This is the documented effect of exit 2 on that event: it blocks the tool call, which is the only per-tool-call event that can.

A hook on the post-tool-call event, which reports the failure once the edit has already been made — Incorrect: The post-tool-call event is documented as unable to block, because the tool already ran; exiting 2 there shows the failure to Claude rather than preventing it.

Answer: C

Q3medium

Discovery has to establish what data the assistant may touch. Which documented criterion turns that into something a release can be judged on?

A.

A record of which teams were consulted during discovery

B.

A statement of the retention period that will be applied to the conversation logs the assistant produces, together with who is permitted to read them

C.

A privacy criterion: how the model handles personal or sensitive information, and whether it follows instructions not to use or share certain details

D.

A list of the systems the assistant is permitted to call

Show answer & explanation

Correct Answer: C

A record of which teams were consulted during discovery — Incorrect: Consultation records who was asked; it states no boundary the system can cross.

A statement of the retention period that will be applied to the conversation logs the assistant produces, together with who is permitted to read them — Incorrect: Retention is a policy about stored data, and the criterion asks about behaviour.

A privacy criterion: how the model handles personal or sensitive information, and whether it follows instructions not to use or share certain details — Correct: This is the documented privacy criterion, and it is the one that makes a data boundary measurable rather than declared.

A list of the systems the assistant is permitted to call — Incorrect: An allowlist is an implementation of a boundary, and the boundary itself still has to be stated as a criterion.

Answer: C

Q4medium

An agent that runs on a developer machine fails to start in the deployed service. Which documented cause does the guidance name for Python?

A.

A container or service manager runs the application with a different path than the shell, so a local install is invisible to the process

B.

The model ID that works locally is simply not available at all within the particular region that the service has been deployed into

C.

The session store adapter is unconfigured

D.

The telemetry environment variables are unset

Show answer & explanation

Correct Answer: A

A container or service manager runs the application with a different path than the shell, so a local install is invisible to the process — Correct: This is the documented cause, and it is the handoff gap the troubleshooting section exists for.

The model ID that works locally is simply not available at all within the particular region that the service has been deployed into — Incorrect: A region problem fails the request rather than the start.

The session store adapter is unconfigured — Incorrect: Store configuration affects durability, not start-up.

The telemetry environment variables are unset — Incorrect: Telemetry changes what you can see, not whether the process starts.

Answer: A

Q5easy

A team wants an unattended workflow to run a Skill it keeps in the repository. What does the documentation require?

A.

Check the repository out before the action step, so the skill files are on the runner, and pass the skill name as the prompt

B.

Publish the skill to a marketplace first and install it through the plugin inputs, because only a packaged skill can be named in the prompt

C.

Inline the skill body into the prompt input, because the input takes plain text only

D.

Grant the workflow write access, because a skill invocation counts as a write

Show answer & explanation

Correct Answer: A

Check the repository out before the action step, so the skill files are on the runner, and pass the skill name as the prompt — Correct: This is the documented sequence, and the prompt input accepts a skill invocation as well as plain text.

Publish the skill to a marketplace first and install it through the plugin inputs, because only a packaged skill can be named in the prompt — Incorrect: A plugin skill is the other documented path, not the only one.

Inline the skill body into the prompt input, because the input takes plain text only — Incorrect: The documentation says the prompt input accepts a skill invocation as well as plain text.

Grant the workflow write access, because a skill invocation counts as a write — Incorrect: Write access is a check on the triggering actor, not a requirement of the prompt.

Answer: A

Q6medium

A requirement arrives as "the assistant must use the fastest available model". Which reframing turns it into something a release can be judged against?

A.

Name the fastest model explicitly in the requirement itself, so that the choice is left unambiguous for everyone who reads the document later

B.

Add a clause allowing the model to change later

C.

Record the requirement as a constraint rather than as a criterion

D.

State an acceptable response time drawn from the real-time requirements and expectations of the application, leaving the model open

Show answer & explanation

Correct Answer: D

Name the fastest model explicitly in the requirement itself, so that the choice is left unambiguous for everyone who reads the document later — Incorrect: Pinning the model preserves the solution and still states no target the system can miss.

Add a clause allowing the model to change later — Incorrect: A change clause governs revision, and it still leaves nothing to measure.

Record the requirement as a constraint rather than as a criterion — Incorrect: Relabelling does not supply a measurement.

State an acceptable response time drawn from the real-time requirements and expectations of the application, leaving the model open — Correct: This is the documented latency criterion, and it is the form that keeps the requirement about the business need.

Answer: D

Q7medium

A task requires a sourced answer, but the supplied material does not answer the question. Which prompt instruction supports an honest result?

A.

Always choose a confident answer to avoid a blank field

B.

Use an unrelated source whenever the requested one is absent from the set

C.

State the evidence gap and use the task's clarification or review path

D.

Infer an unseen policy and cite the attachment title

Show answer & explanation

Correct Answer: C

Always choose a confident answer to avoid a blank field — Incorrect: Confidence does not supply missing support.

Use an unrelated source whenever the requested one is absent from the set — Incorrect: An unrelated source cannot establish the requested claim.

State the evidence gap and use the task's clarification or review path — Correct: The documented uncertainty guidance supports acknowledging a gap.

Infer an unseen policy and cite the attachment title — Incorrect: A source title is not evidence for an invented policy.

Answer: C

Q8easy

Which four factors does a model choice weigh first?

A.

Capabilities, speed, cost and effort

B.

Context window, output limit, price and region

C.

Accuracy, uptime, support and term

D.

Vendor, platform, licence and renewal

Show answer & explanation

Correct Answer: A

Capabilities, speed, cost and effort — Correct: These are the four documented factors.

Context window, output limit, price and region — Incorrect: These are specification rows rather than decision factors.

Accuracy, uptime, support and term — Incorrect: Uptime and support are not among the documented four.

Vendor, platform, licence and renewal — Incorrect: Commercial terms are not the documented technical factors.

Answer: A

Q9medium

A read-only support assistant exposes lookup_ticket and get_ticket. A configuration audit confirms that both accept the same ticket ID, return the same fields and invoke the same backend operation under identical permissions. Selection errors occur between these aliases. Which change directly addresses the redundant capability surface?

A.

Keep both names and increase the cache lifetime

B.

Add a third alias with a broader description

C.

Expose one clearly described canonical ticket-lookup tool

D.

Split each alias into a separate agent without changing its interface

Show answer & explanation

Correct Answer: C

Keep both names and increase the cache lifetime — Incorrect: Caching changes repeat-input economics; it does not remove the documented selection ambiguity between equivalent aliases.

Add a third alias with a broader description — Incorrect: Another overlapping interface expands the choice without introducing a distinct capability.

Expose one clearly described canonical ticket-lookup tool — Correct: The scenario establishes equivalent contracts and permissions. Consolidating the aliases removes redundant choices while preserving the needed capability.

Split each alias into a separate agent without changing its interface — Incorrect: Delegation adds another boundary but leaves the duplicate interfaces unresolved.

Answer: C

Q10medium

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

Q11medium

A regulator will ask how a given answer was reached. Which documented practice makes the response auditable?

A.

Recording the model version with each answer

B.

Writing a longer and more explicit system prompt

C.

Raising the effort setting for the more consequential of the requests

D.

Having the model cite quotes and sources for each of its claims

Show answer & explanation

Correct Answer: D

Recording the model version with each answer — Incorrect: Provenance of the model is not provenance of the claim.

Writing a longer and more explicit system prompt — Incorrect: Prompt length does not create an audit trail.

Raising the effort setting for the more consequential of the requests — Incorrect: Effort changes how the answer is produced, not what supports it.

Having the model cite quotes and sources for each of its claims — Correct: This is the documented technique, stated in those terms.

Answer: D

Q12medium

A support workflow's task-success rate drops after a catalog reduction. The latency target is still met. Which release decision is justified by the pilot's stated goal of preserving both quality and responsiveness?

A.

Roll out because lower catalog size proves higher quality

B.

Roll out because latency is the only relevant outcome

C.

Restore every old result block regardless of its relevance

D.

Investigate the failed tasks and repair discovery before broad rollout

Show answer & explanation

Correct Answer: D

Roll out because lower catalog size proves higher quality — Incorrect: Catalog size measures an input reduction, not whether the required capabilities remain usable.

Roll out because latency is the only relevant outcome — Incorrect: The stated acceptance goal includes task success as well as responsiveness.

Restore every old result block regardless of its relevance — Incorrect: No evidence identifies result history as the cause of the regression.

Investigate the failed tasks and repair discovery before broad rollout — Correct: The observed quality regression means the candidate has not met its stated goal. Inspect which capabilities the failed tasks could not discover or use.

Answer: D

Q13medium

A reusable support prompt mixes permanent instructions with a different customer message on every request. Which structure makes the distinction explicit?

A.

Put both into one undelimited paragraph

B.

Wrap instructions and customer input in separate descriptive sections

C.

Remove the instructions after the first request

D.

Treat every imperative in the customer message as a new system instruction

Show answer & explanation

Correct Answer: B

Put both into one undelimited paragraph — Incorrect: The mixed paragraph obscures the intended roles of the text.

Wrap instructions and customer input in separate descriptive sections — Correct: Documented tags or equivalent sections make the input categories clear; the application must still enforce authority.

Remove the instructions after the first request — Incorrect: A standalone request still needs its applicable instructions.

Treat every imperative in the customer message as a new system instruction — Incorrect: Task data does not acquire system authority because it contains an imperative.

Answer: B

Q14hard

The same tool server is defined in two scopes with different fields. What does the documentation say happens?

A.

The fields are merged together, with the higher-precedence scope winning on each individual field

B.

The connection is refused until the duplicate is removed

C.

The entire entry from the highest-precedence scope is used, and fields are not merged

D.

Both definitions connect, as two servers

Show answer & explanation

Correct Answer: C

The fields are merged together, with the higher-precedence scope winning on each individual field — Incorrect: This is the settings rule for list keys, and it is not the rule here.

The connection is refused until the duplicate is removed — Incorrect: Claude Code connects once rather than refusing, using one scope's definition.

The entire entry from the highest-precedence scope is used, and fields are not merged — Correct: This is the documented behaviour, and it is the opposite of how settings lists combine.

Both definitions connect, as two servers — Incorrect: Claude Code connects to it once.

Answer: C

Q15medium

An analyst agent keeps firing hyper-specific queries (“2026 Q2 lithium carbonate spot price Shenzhen”) and returning nothing. What decomposition strategy does Anthropic prescribe for search-style problems?

A.

Spawn 50 subagents to try random queries

B.

Make each query even more specific, on the assumption that the ambiguity lies in the wording itself

C.

Start wide with short, broad queries, evaluate what is available, then progressively narrow focus

D.

Disable search and rely on parametric knowledge

Show answer & explanation

Correct Answer: C

Anthropic's 'start wide, then narrow down' principle mirrors expert human research: explore the landscape before drilling into specifics, because agents default to overly long specific queries that return few results. The fix is prompting agents to start short and broad, evaluate, then narrow.

Make the queries even more specific to disambiguate — Incorrect. More specificity can exclude the relevant sources when the search space is not yet known.

Disable search and rely on parametric knowledge — Incorrect. Model memory does not establish current external evidence.

Spawn 50 subagents to try random queries — Incorrect. Random fan-out increases cost without a search strategy.

Answer: C

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