Claude Certified Developer · Foundations

CCDV-F Field Notes

What the practice bank actually tests, distilled to the transferable rule behind each question. Read the traps first — the exam reuses a small set of wrong-answer shapes.

Questions53
To pass75%
Domains8
Practice runs158 / 159
00

The distractor playbook

Nearly every question is a scenario with one correct architectural move and three plausible-sounding wrong ones. The wrong ones are drawn from a fixed repertoire:

  • "Just tell the model to…" — a system-prompt rule, a stronger instruction, a politeness tweak, a "think carefully" line. Wrong whenever a structural or in-code enforcement point exists. The model is never the security boundary, the validator, the gatekeeper, or the calculator.
  • "Scale the blunt lever" — bigger budget, more subagent clones, more retries, tighter retry interval, a second API key, a bigger context window. Adds cost or load; never fixes the design.
  • "Stack another layer" — a custom retry loop wrapping the SDK's own retries, a second judge model reviewing the first judge, a self-assessment step. Compounds cost and inherits the same blind spot.
  • Temperature as a cure-all — offered for pricing, arithmetic, format stability, or reproducibility. It does none of those, and temperature: 0 does not even guarantee identical outputs.
  • "Anthropic will retain / replay / restore it" — the platform does not warehouse your conversation content or batch results for you. You persist everything.
  • Detection dressed as prevention — a nightly audit, alerting, logging "for review" offered when the question asks how to prevent or limit exposure now.
  • The heuristic instead of the measurement — "pick the newest model", "use what peers use", "upgrade when users complain" instead of an eval on your own data.
  • Encoding / formatting ≠ protection or control — base64, splitting a secret across two fields, "unreadable in transit" when TLS already exists, re-encoding an image to change how it's parsed.

The correct answer is almost always the one that moves enforcement out of the model and into code, configuration, the platform's own feature, or the tool implementation — or, when ground truth exists (code compiles, tests pass), gates on that deterministic signal instead of a model's judgment.

01

Hard facts to memorise

TopicFact
Batch results retentionRetrievable for 29 days after completion — download & store them yourself.
Batch pricing / SLA50% discount; turnaround guaranteed only within 24h. Stacks with prompt caching. Not for tight deadlines.
Batch controlsA completed batch holds a mix: succeeded, errored, canceled, expired — inspect each, requeue only failures. Batches can be canceled mid-run; already-finished requests still return.
Deadline-bound throughputWhen a batch's 24h SLA is too slow: async SDK client + bounded concurrency up to your rate limits. Not a bigger model, not compression.
Prompt cache — min length1024 tokens (Sonnet / Opus), 2048 (Haiku). Below the threshold the cache breakpoint is silently ignored — no error, no cache activity.
Prompt cache — TTL & scopeDefault lifetime 5 minutes, resets on each reuse; 1-hour lifetime is opt-in. Entries are scoped to the organization, not per API key.
Prompt cache — economicsCache writes cost more than normal input tokens; savings only accrue on repeated reads of the same prefix within the TTL.
Rate-limit bucketsIndependent: RPM, ITPM, OTPM. Large payloads exhaust ITPM long before RPM. Enforced at organization level — extra keys in the same workspace share the limits.
Raising limitsAdvance the org's usage tier — has lead time (spend thresholds / sales). Plan before launch, not launch week.
Error codes400 = invalid request (don't retry). 429 = rate limit (back off). 529 = overloaded / service load (design a degraded mode).
Support ticketsQuote the request-id from the response headers — it's the only thing that pinpoints one call in Anthropic's logs.
Connection limitA single request's connection lives ~10 minutes. SDKs error at request time if a non-streaming call's max_tokens makes it likely to exceed that — the fix is to stream. Messages streaming is SSE over HTTP, not websockets.
Stop reasonsend_turn, max_tokens, stop_sequence, tool_use, pause_turn, refusal. refusal is terminal — surface it, never retry the identical request.
stop_sequencesHalts generation the instant the string is produced; stop_reason: "stop_sequence"; the sequence itself is not in the output. The reliable way to cut generation at a marker — a prompt instruction is not.
tool_choiceauto / any / {type:"tool", name} / none. A named tool is the only way to guarantee invocation.
Message input typesText, image, document (PDF) content blocks. No audio — a summariser for calls needs a speech-to-text stage first.
Tool result contentAccepts a list of content blocks, including image blocks — only an image block routes bytes through vision. Base64 in a text field is just characters.
Extended thinking — billingReasoning tokens bill at the output rate. One generation pass, no premium schedule.
Extended thinking — max_tokensThinking tokens count toward max_tokens; the request 400s if the thinking budget meets or exceeds it. max_tokens must be strictly greater.
Extended thinking — prefillIncompatible. Thinking must open the assistant turn, so you cannot prefill assistant content. Use a schema-enforced tool instead.
Adaptive thinkingNewest models allocate reasoning depth per request themselves; an effort setting is the coarse dial. Hand-tuned per-request budget tables are obsolete.
Context windowExtended (~1M-token) context is a beta — the move for cross-document reasoning that must happen in one request.
StatelessnessThe Messages API keeps no server-side conversation state. Every request sends the full history. "Edit a turn" = truncate, substitute, resend.
Per-request cost capOutput tokens are the unbounded cost component — max_tokens is the only hard per-reply ceiling. A brevity instruction is not.
Per-feature costEvery response carries a usage object (input / output tokens) — tag it with the calling feature. The Admin usage & cost API is for warehouse-wide reporting by workspace / model.
Request metadataCarries an abuse-tracking id (e.g. user_id). Never shown to the model — not a channel for per-session context.
Priority TierCapacity + SLA treatment for latency-sensitive production traffic during peaks. Opposite of the batch tier.
Fine-tuningNot offered on the Claude API. Brand voice = system prompt + few-shot examples + eval against a style rubric.
temperature / top_pOn the newest model generation, non-default sampling params are deprecated — a request setting them 400s naming the exact fields. Omit them; they are not a variety, format, or cost lever. (Historically you also can't set both at once.)
Tokenizer driftA newer model generation can ship a new tokenizer — the same prompt text bills more tokens. Re-measure token counts and cost projections after any model migration; don't reuse the old model's numbers.
Output-token billingYou pay for tokens actually generated, never the max_tokens ceiling. Lowering the ceiling on already-brief replies saves nothing.
Image token costScales with pixel dimensions (≈ width × height ÷ 750). Downsample large photos to cut cost; file format is irrelevant. A media_type that disagrees with the actual bytes → 400.
Parallel tool callstool_choice: {disable_parallel_tool_use: true} caps a turn at one tool call — the fix when concurrent calls race on shared state. Merging tools or lowering max_tokens doesn't.
Message role ordermessages must alternate user / assistant. Two assistant turns in a row → 400 before the model runs.
MCP tool annotationsreadOnlyHint, destructiveHint (and idempotentHint) let a server declare each tool's behaviour so any client can prompt for confirmation — without clients hardcoding tool names or a name prefix convention.
Built-in web toolsWeb fetch retrieves a given URL's content, PDFs included. Web search returns ranked results for a query. Don't hand-roll a downloader/parser.
Skill vs MCP serverA Skill is packaged instructions/context — no live or authenticated access, no code execution across clients. Shared authenticated tool access from several clients = build an MCP server.
Claude Code — headless output--output-format stream-json emits event-by-event machine-readable output for wrapping a non-interactive run; plain text is for humans tailing a log.
Claude Code — plugin depsA plugin's manifest declares required plugins and versions, so installing it pulls the companions automatically. A README note or a post-install setup command doesn't.
02

The API surface

mechanics the exam probes

Streaming

Use the SDK's streaming helper; never hand-roll an SSE parser.

It handles encoding across chunk boundaries, tolerates new event types, and returns both incremental text and the fully assembled final message. Regex over a structured event protocol is the same brittleness in a new form.

Know where each value lives in the event stream.

message_start opens the stream and carries input-side usage only. content_block_delta events carry incremental content, each tagged with the index of the block it extends — accumulate per index, and treat text and tool_use as separate blocks. message_delta near the end carries the stop_reason and cumulative output usage. Then message_stop.

Streaming tool arguments arrive as input_json_delta fragments.

Each event holds a fragment of the JSON string — rarely parseable alone. Concatenate the fragments and parse once the content block's stop event fires. The final delta is just the last fragment, not the whole object.

Match delivery mode to the consumer.

Humans benefit from token-by-token rendering; a downstream parser needs a complete, validated response. Stream the chat panel, give the machine consumer only finished output. Don't buffer the human path, and don't feed the parser deltas.

Stream anything likely to run past the ~10-minute connection window.

The SDK raises an error at request time when a non-streaming call's output ceiling makes a timeout likely. Streaming keeps the connection active with continuous tokens; a longer client timeout doesn't stop intermediate infrastructure dropping an idle connection, and splitting into many small calls changes the deliverable.

Shaping output

Prefill the assistant turn to constrain how a response begins.

End the messages array with an assistant turn containing e.g. an opening brace, and generation continues from that character — conversational lead-ins never appear. A stop sequence controls where output ends, not where it starts. Caveat: prefill is rejected when extended thinking is on.

Use stop_sequences to cut generation at a marker.

Server-side, enforced on every request, and you stop paying for the discarded tail. Lowering max_tokens truncates at an arbitrary count that rarely lines up with the marker; a prompt instruction is followed only probabilistically.

Force schema-conforming output with tool_choice.

Naming a tool in tool_choice makes every response invoke it. Stronger system-prompt wording raises the odds without eliminating prose answers.

Put reasoning before the conclusion.

Generation is autoregressive — a verdict emitted on the first line is committed before any justification tokens exist and cannot benefit from them. Ask for the analysis first, the verdict last. This is the core of chain-of-thought prompting.

03

Applications & Integration

largest domain

A refusal stop reason is a terminal outcome.

Surface a message or reroute the workflow. Resending the identical request reproduces the decline and burns tokens. It is not truncation, not throttling, not a streaming artifact.

Auditability and reproducibility are the application's job.

The API stores no conversation content for retrieval. Log every request/response pair with model version and parameters in your own store. Platform request IDs support incident investigation, not content replay.

Message Batches: persist results yourself, read per-request status, cancel when wrong.

Results expire (29 days). A completed batch mixes succeeded / errored / canceled / expired — keep the successes, requeue only the failures. If a template bug is discovered mid-run, cancel: finished requests still return, and you stop paying for the known-bad remainder.

Rate limits are several independent buckets at the org level.

Throttling well below RPM with large payloads points to ITPM. Extra keys in the same workspace share the limits. A 100× campaign means advancing the usage tier ahead of time. A hammering internal client is fixed with per-user quotas in your app plus a queue that smooths bursts.

Sustained 529s call for a designed degraded mode.

Serve templated or cached content so a customer-facing feed stays alive while backoff-retries recover. Shortening the retry interval worsens the overload.

Don't stack your own retry loop on the SDK's.

Official SDKs already retry rate-limit and transient errors with backoff. An outer loop multiplies every retry and amplifies load during an incident. Consolidate on the SDK's retry configuration.

Traceable answers → the citations feature on document blocks.

Structured references tied to exact source spans — machine-checkable, unlike prose attributions a prompt instruction produces.

Spend attribution: per-response usage for features, Admin API for the warehouse.

Every response carries token counts — tag them with the calling feature for dashboards. For authoritative nightly reporting by workspace and model, pull the Admin usage & cost endpoints; don't scrape the Console or estimate from characters.

Least privilege: workspace-scoped Console roles, not org-wide admin.

A dedicated workspace with workspace-level roles confines contractors to the keys their prototypes need. A shared account erases accountability; rotating keys leaves the excessive grants untouched.

If identifiers must never leave your systems, redact before transmission.

Strip or tokenize client-side; send only sanitized text. Transport encryption already exists and doesn't change what the recipient sees.

Audio isn't a supported input — add a speech-to-text stage.

The Messages API accepts text, image, and document blocks. Uploading audio via the Files API doesn't let the model hear it.

Full-coverage synthesis over a corpus > context window = chunk then combine.

Summarize each chunk, then a combining pass, so every document contributes. Retrieval systematically omits unqueried content.

Read the model id and per-session context from configuration, not code.

Per-environment config lets dev / staging default to economical models and removes the hardcoded-model hotfix class. Per-session facts (name, tier, today's disclosure text) come from the backend injecting profile fields into the system prompt each request — not from asking the user, not from metadata, not from weights.

Operational visibility: log per-request usage, stop reasons, and error codes with alerts.

A refusal / 429 spike should page within minutes, not surface days later via customer complaints. The status page reports Anthropic-side incidents, not your app-specific patterns; the invoice surfaces cost anomalies weeks late.

04

Model Selection & Optimization

Extended thinking multiplies output-token spend.

Reasoning tokens generate before the visible answer and bill at the output rate, so spend can triple while answer length and request count stay flat.

There is no fine-tuning; brand voice is a prompt problem.

System prompt + curated few-shot examples + evaluation against a style rubric. A quarter spent collecting training pairs targets a capability the API doesn't expose.

Prompt caching fails on short prompts, cold prompts, and unique prefixes.

Below the 1024-token minimum the breakpoint is silently ignored. With 5-minute TTL, queries 20–40 min apart find the entry gone and pay the write premium again (opt into the 1-hour lifetime, or batch the queries). Two-turn chats with distinct openings never collect the read discount at all.

Two pricing levers stack: Batch API + prompt caching.

An overnight job gets the 50% batch cut; a repeated style-guide prefix is served from cache. No time-of-day pricing; temperature has no pricing dimension.

Model choice is an empirical question about your workload.

Run an eval over your own data with success criteria set up front. When the smallest tier misses on quality and the largest overshoots the latency / cost budget, evaluate the mid tier (Haiku < Sonnet < Opus) against the same suite — "newest", peer adoption, and complaint-driven upgrading all dodge the question.

Newest-generation models self-allocate reasoning depth.

Adaptive thinking makes a hand-maintained per-request-type budget table redundant; an effort setting is the coarse dial. Reasoning depth is not fixed per tier.

Latency-sensitive peaks → Priority Tier.

Capacity with SLA treatment so surge requests aren't competing in the standard pool. The batch tier moves the opposite way.

Deterministic computation belongs in code, not the model.

Models generate digits by next-token prediction, so plausible-looking arithmetic errors persist regardless of prompting, extended thinking, or examples. Have Claude extract the figures and compute totals in application code (or the code execution tool). A model-backed unit-conversion tool shouldn't exist.

Reduce perceived latency by streaming and by routing the easy majority to a faster tier.

Streaming changes when text becomes visible; routing simple, high-volume requests to a smaller model (after an eval confirms accuracy) shortens most conversations. Extended thinking adds latency; a higher output ceiling doesn't speed generation.

Cross-document reasoning over ~600K tokens → the extended context beta.

The whole set in one request. Wider retrieval + reranking still fragments cross-document reasoning; a file-by-file agent trades retrieval-stitching for agent-stitching.

05

Agents & Workflows

Concurrent agents need write isolation.

Disjoint file ownership, or separate working copies merged deliberately, so overlapping edits become explicit merges instead of silent overwrites. Full serialization surrenders the concurrency; last-writer-wins is the bug promoted to policy.

Every tool call needs a per-call timeout that returns an error result.

A hung invocation stalls the harness, not the model — convert it into an error the model receives and can react to. Killing the whole agent discards all progress; a retry wrapper without a timeout stacks infinite waits.

Debugging agents requires the full turn-by-turn trace.

Structured logging of every model turn with the tool calls it issued and the results it received. Endpoint-only logs (final answer + latency) can't locate which of a dozen steps failed. This trace is the prerequisite for a regression suite.

Crash-tolerant long runs checkpoint state outside the context.

Write a progress ledger to storage as units complete, and make each step idempotent so a resumed run re-executes safely from the recorded position. The context window vanishes with the process, whatever its size.

Runaway loops need deterministic stopping conditions in the harness.

An iteration cap and a per-run token-spend budget each stop a stuck run on their own. Lowering max_tokens shrinks each turn while the loop continues; prompting the agent to "give up" leaves termination to the same nondeterminism that let it run for hours.

Human-in-the-loop = the Agent SDK permission callback.

A hook intercepts each tool invocation and can allow, deny, or route a high-impact operation to a human approval step — deterministically. For a first launch, pair it with an observe-only mode that records intended actions until the agent's judgment is validated. A reviewing agent adds an opinion without enforcement.

The Agent SDK gives you the loop and context management — not a bigger window or a safety guarantee.

Out of the box it provides the built-in agent loop (tool-call → result cycle across turns) and automatic context compaction / pruning. It does not grant a larger context window than the underlying model, and it does not guarantee the agent stays within its assigned scope — that still needs enforced checkpoints.

Adopt a model-driven agent framework when the task is open-ended and it removes repeated scaffolding.

Frameworks like Strands or PydanticAI are worth it when steps vary run to run and the team keeps re-writing the same loop, tool dispatch, and state plumbing — not to cut per-token cost or hide the assembled prompt, and not for a fixed step sequence (that's a plain prompt chain). Reach for PydanticAI specifically when you need typed, schema-validated agent outputs without hand-writing parsing and retries.

One owner of decomposition — a lead / orchestrator agent.

The lead breaks each task into scoped subtasks, assigns each to a worker, and merges results. Peer agents broadcasting "claim" messages still race and leave gaps; that's coordination theater with no enforcement.

Give each subagent a distinct role, its own slice, and only the tools it needs.

Identical clones with a generic prompt duplicate effort and disagree on merge. Don't slice too thin either — micro-steps that share heavy context force every subagent to reload it, costing more than one agent doing the whole thing.

Subagents are intelligent filters — they return distilled findings, not raw transcripts.

Each does its exploration in its own context and hands back only what the lead needs. Returning full working transcripts floods the lead's context with material it never uses and synthesis quality slides.

Anything a later phase must honor travels explicitly in its task brief.

Fresh subagents start from a clean context. If phase-two workers keep contradicting phase-one's source and naming decisions, embed those decisions in every phase-two task description — the phase-one agents have terminated and can't be queried.

Design tools so mistakes are hard to make.

A path parameter resolved against a working directory the model never sees causes misplaced writes — require absolute paths so the ambiguity can't be expressed. Consolidate always-chained operations (list → detail → create) into one purpose-built tool, and return human-readable names alongside opaque identifiers.

Test agents against mocked tools before launch.

Script both normal and failure responses (the timeout production won't produce on demand) and observe the agent's full behaviour safely. Alerting and transcript-grading are post-hoc.

Gate merges on ground truth when it exists.

For code patches: compile the project and run the test suite. An LLM judge — even with a rich rubric, even a second judge stacked on the first — never executes the code and inherits the same blind spot. Self-reported confidence is the weakest signal.

Raise recall with the parallelization (voting) pattern.

Run several identical review calls in parallel and aggregate the flagged issues — sampling variance means one call misses real violations on any given run. Sequential passes inherit each other's blind spots; temperature: 0 doesn't guarantee identical output and just repeats one pass's misses.

06

Prompt & Context Engineering

The golden rule: show the prompt to someone without your context.

Instructions that only make sense with the author's framing are exactly what fails on teammates' differently-phrased inputs.

Tell the model what to do — and why.

A positive description of the target behaviour plus one exemplar defines the whole acceptable space at once, so new failure modes stop appearing. Better still, give the reason behind a rule ("replies are read aloud, so visual formatting garbles the audio") — the model then generalizes it to request types nobody enumerated.

System prompt = stable identity and rules, kept lean; invariant rules live there once.

Bulky reference material is attached per request only when needed; relocating it to a user message just moves the bloat. Pasting a compliance preamble into every user turn causes drift and silent divergence when someone edits one copy.

Prefer just-in-time context; watch for context rot.

Give the agent retrieval tools that fetch only the sections a task needs. Injecting an 80K-token knowledge base every conversation dilutes attention on the actual instructions even when it's cached — a static digest loses detail, and moving it to the system prompt only changes placement.

Compact long conversations; prune stale turns.

Summarize earlier turns into a compact recap and continue from that plus the recent messages — a run can then go indefinitely. Dropping the oldest messages silently discards the original brief; the largest window only postpones the failure. Also prune stale tool results and low-value turns from the replayed array.

Extraction prompts must give an explicit out for missing data.

Absent fields return null; values are copied only when stated. This removes the pressure to fill every key with a plausible fabrication.

Constrain the start with prefill, the end with a stop sequence.

An assistant turn seeded with { forces clean JSON from the first token. But prefill is rejected under extended thinking — switch to a schema-enforced tool then.

Restructure a rough prompt with the Console prompt improver.

It applies Anthropic's best practices automatically — chain-of-thought guidance, delimited sections, enriched examples — and returns a draft to review before manual tuning. Extended thinking or a bigger tier leaves vague instructions in place.

Prevent regressions with eval-driven prompt development.

Build a test set from real production traffic plus edge cases; score every candidate revision against it; automate grading with code checks or rubric-based model grading so it runs on each change. Rewriting from scratch after each regression discards accumulated working behaviour.

07

Tools & MCP

MCP primitives differ by who controls them.

Tools — model-controlled, invoked when relevant. Prompts — user-controlled templates surfaced in the client's command menu, filled with arguments, entering the conversation only on explicit selection (use these when the model must not trigger a workflow). Resources — application-controlled data the client attaches. Sampling — the server requests a completion from the client's model, so the server holds no keys or model config.

Skills use progressive disclosure.

A session carries only each skill's name and description; the full procedure loads when a matching task invokes it. Skills live in the repo and follow normal review; they complement CLAUDE.md, not replace it.

Keep tool results concise at the source.

Accept filter parameters so the server narrows results, and return paginated sets with a cursor. Summarizing an oversized result afterward means the tokens already flooded the context. Don't mirror a REST API one endpoint at a time — build task-purpose tools and return human-readable context, not opaque IDs.

Return generated images as image content blocks in the tool result.

A tool_result's content is a list of blocks; only an image block routes bytes through vision. Base64 in a text field is a wall of characters no matter the source format.

Debug an MCP server with the MCP Inspector.

Connects directly, lists tools / resources / prompts, invokes them, shows raw exchanges — reproducing failures with no client in the loop.

A stdio MCP server must keep stdout clean.

The stdio transport reserves standard output for protocol messages — print statements there corrupt the stream and the client drops the connection. Send logging and progress to stderr. Flushing or JSON-wrapping the messages still injects foreign bytes into the protocol stream.

Reach for Anthropic's built-in tools before designing a schema.

The text editor tool is Anthropic-defined and client-executed, and the model is trained to use its view / string-replace commands accurately — implement only the execution side against your own checkouts. The code execution tool runs in an Anthropic-managed sandbox (can't touch your servers). Computer use targets GUIs and is heavyweight for programmatic edits.

A third-party MCP server is untrusted code.

Its tool descriptions and results flow into model context every session — review the source and pin a vetted release rather than tracking latest. Restricting it to read-only tools narrows write damage but injected text can still steer the agent; a guidance-file rule to "ignore suspicious text" is what injection is crafted to defeat.

Secrets stay server-side in the tool implementation.

Anything in model context can surface in model output. The tool authenticates to the database itself. Base64 is reversible; splitting a secret across two fields leaves it extractable twice; confidentiality instructions are the control that just failed the pentest.

Treat model-supplied tool arguments as untrusted input.

Validate types and ranges, use parameterized statements — injected SQL is then neutralized in code regardless of the conversation.

Use MCP sampling when a server needs a completion but must hold no credentials.

The client controls model choice, keys, and user approval; the server gets its generated text (a suggested filename, say) without any model machinery.

08

Security & Safety

Authorization must live outside the model.

Tools receive the requesting user's identity from the authenticated session, not conversation text, and enforce record-level access checks in code. No persuasive dialogue can then widen access.

Bound the blast radius of an autonomous agent with enforced checkpoints.

Human approval in front of each consequential action, plus an observe-only launch to validate judgment first — each bounds harm regardless of how the model behaves. A more capable model errs less often but supplies no boundary when it still errs; a longer prohibition catalog stays advisory.

To limit a live data leak now, filter outputs before display.

A response-side scan for identifier patterns that redacts before the customer sees them is a real interim barrier. A disclaimer announces the leak; nightly sampling detects it after the fact.

An open endpoint needs per-user auth plus edge rate limits.

Throttles the scripts driving both the runaway bill and the bulk abuse, and creates the identity needed to ban offenders. Bigger budgets fund the abuse; a cheaper tier discounts it; terms of service have no enforcement mechanism.

09

Claude Code

First step on a new repo: the init command.

Scans the repository and generates a starter CLAUDE.md documenting build commands, test invocations, and layout, which loads into every session — orientation happens once instead of every morning.

Plan mode is the propose-then-approve gate.

A permission mode that restricts the session to read-only analysis and requires the user to approve the plan Claude presents before any change. Headless mode still permits edits; denying only the Edit tool leaves shell commands free; a CLAUDE.md instruction is advisory.

Settings precedence: managed > project > user > local.

A managed settings file, deployed by administrators, sits at the top and cannot be overridden by project or user files — the way to enforce a permission rule on every engineer's machine. settings.local.json is personal and freely editable; CLAUDE.md is model guidance, not enforced policy.

Enforce command policy with permissions allow / deny rules.

In settings.json, enforced by the harness: a deny rule matching git push blocks it regardless of model intent; an allow rule matching npm test pre-approves it so no prompt appears. Setting defaultMode to bypassPermissions removes prompts for everything, including what must stay blocked.

A PreToolUse hook can ask, not just block.

Return structured JSON with the permission decision set to ask to surface a pending call for case-by-case confirmation. Exit code 2 blocks outright (reproducing "it keeps stalling"); a PostToolUse hook runs after execution, too late to stop a destructive action.

Share one canonical standards file via CLAUDE.md import syntax.

Each repo references the canonical document; edits propagate from a single source. Pasting the same 200-line block into eleven CLAUDE.md files is what caused the drift; settings.json holds config, not coding guidance.

Treat CLAUDE.md and hook scripts as config-as-code.

They steer every engineer's sessions, so changes deserve the same pull-request review gate as application code. Moving them out of version control hides changes; renaming them so they stop loading throws away the conventions.

A custom subagent gives you a scoped system prompt and a scoped toolset.

Its instructions encode e.g. a review checklist permanently; its tool allowlist can grant read / search while withholding edit tools so the reviewer structurally cannot modify files. Each invocation gets a fresh context.

10

Eval, Testing & Debugging

Reproduce the exact request in the Console workbench to localise a bug.

If the model's output is clean there, the corruption happens after the response leaves the API — in your parsing, handling, or encoding path (check recent deploys). A drifting snapshot or degraded prompt would garble the workbench output too.

CI: recorded fixtures per commit, a small live smoke suite on merges.

Fixtures make the per-commit suite fast, free, and deterministic while still exercising your parsing and error paths. Asserting on exact response wording is the flakiness source — sampling legitimately varies phrasing; raising temperature amplifies the noise.

Record full step-by-step traces before you can debug a multi-step agent.

Final answer plus latency tells you nothing about which of a dozen intermediate steps produced the wrong result. Capture each step's inputs, outputs, and tool results.

Compiled from full passes of CCDV-F Practice Tests 4, 5 and 6 (53/53, 53/53, 52/53). Every principle traces to an official docs reference under platform.claude.com/docs, code.claude.com/docs, modelcontextprotocol.io, or the Anthropic engineering blog. The remaining practice tests draw on the same domain map and distractor repertoire — the traps section transfers directly.