πŸŽ“ Claude Architect KB CCAR-F Β· CCAR-P study guide

The Six Scenarios β€” Worked Walkthroughs

The official CCAR-F exam guide publishes six scenario contexts the exam draws from β€” that's the public blueprint, and it's a gift: study the contexts and on exam day you're recognizing, not guessing. Everything below is original study material built on that public blueprint β€” a reference architecture per context, the judgment calls each one exercises, and the wrong-answer patterns to watch for. Nothing on this page is recalled, copied, or reconstructed from live exam questions.

🧭 How to read a scenario like an architect β€” the five-question actor test. Every stem below (and on the exam) yields to the same silent interrogation, one question per domain: Who decides? (the model proposes; the harness executes β€” Domain 1) Β· Who runs it? (model-chosen, harness-run β€” Domain 2) Β· Who guarantees it? (persuaded / API-enforced / harness-validated β€” Domain 3) Β· Whose process executes? (dispatcher / MCP server / Anthropic infra β€” Domain 4) Β· Who manages the memory? (physics vs librarianship β€” Domain 5). When two answer options both β€œwork,” the most appropriate one is almost always the one that puts each verb with its rightful actor.

S1 Β· Customer support agent (Agent SDK + MCP + escalation)

flowchart LR
  U[Customer chat] --> A[Agent SDK loop]
  A --> M1[MCP: CRM server]
  A --> M2[MCP: billing server]
  A --> G{Harness gates: confidence Β· allowlist Β· risk}
  G -->|high-risk or low-confidence| E[Escalate: ticket + context packet + human]
  G -->|ok| ACT[Tool action] --> R[Reply from approved templates]

Probes: when to escalate (confidence floor, out of scope β€” the request falls outside what this agent is chartered to do, dependency down, user asks); tool allowlisting per category; treating MCP tool results as untrusted; conversation-state summarization for long sessions; idempotent side effects (refund can't double-fire); honest degradation when a backend is down.

πŸͺ€ Planted trap: "add a prompt instruction so it never issues refunds over $50" β€” wrong; the limit is a harness gate, with HITL approval for over-threshold refunds.

S2 Β· Claude Code for team code generation

Probes: what belongs in project CLAUDE.md (shared conventions, build/test commands) vs user memory; slash commands for repeated parametrized prompts; skills for procedures; hooks (PostToolUse format-on-write; PreToolUse guard on dangerous Bash); settings precedence (enterprise > project > user); permission allowlists; .mcp.json checked in for team-shared servers.

πŸͺ€ Planted trap: enforcing standards via memory instructions when a hook is the guaranteed mechanism.

πŸ” See it run β€” one "add an endpoint" request through the team setup

Entry point: a developer types "add a DELETE /invoices/:id endpoint."

  1. Claude Code (the harness) loads the project CLAUDE.md β€” the shared conventions say every new endpoint needs a schema, a unit test, and a docs entry.
  2. It calls the Claude API; the model returns an Edit that writes src/api/invoices.ts.
  3. Applying the Edit fires the PostToolUse hook (matcher: Write|Edit) β€” Prettier reformats the file deterministically, spending no model tokens.
  4. The model then proposes Bash(rm -rf build); the PreToolUse guard inspects the command, matches a banned pattern, and exits 2 β€” the action is blocked and the reason is fed back to the model.
  5. The model reroutes to npm run build, which is on the permission allowlist, so it runs.
  6. Settings precedence (enterprise > project > user) decided every gate above β€” the developer can't silently loosen the guard locally. The hook, not a memory instruction, is what made formatting and safety guaranteed.

S3 Β· Multi-agent research system (coordinator + subagents)

flowchart TD
  C[Coordinator: plan Β· decompose Β· synthesize] --> S1a[Subagent: source search]
  C --> S2a[Subagent: deep read]
  C --> S3a[Subagent: verify claims]
  S1a & S2a & S3a --> C

Probes: why subagents (context isolation), what returns upward (compressed findings, not transcripts), parallel reads vs serialized writes, a hub-and-spoke shape (workers report to one coordinator) rather than peer-to-peer chatter between workers, cost/latency multiplication, when a single agent suffices, verification by a judge β€” a second, separately calibrated model that checks the answer as one signal, with factual claims still verified against sources or deterministic checks.

πŸͺ€ Planted trap: sharing one context window across all workers β€” the whole point is separate windows.

S4 Β· Developer productivity tooling (built-ins + MCP)

Probes: built-in tool semantics β€” Read/Write/Edit (file ops), Bash (powerful, gated), Grep/Glob (read-only search); permissioning Bash narrowly (Bash(npm run test:*)); when to add an MCP server vs shell out; headless invocations in scripts; sandbox/least-privilege thinking.

πŸͺ€ Planted trap: granting blanket Bash(*) when scoped allowlists are the tested answer.

πŸ” See it run β€” "fix the failing auth test" through the built-in tools

Entry point: a developer says "run the auth tests and fix the one that fails."

  1. Claude Code uses Grep/Glob (read-only search) to locate the test file β€” no permission prompt, because these tools can't change anything.
  2. Read loads the failing test and the source it exercises.
  3. The model proposes Bash(npm run test:auth); the harness checks it against the allowlist Bash(npm run test:*) β€” it matches, so it runs. Blanket Bash(*) was never granted.
  4. The failing output returns as a tool_result; the model proposes an Edit to src/auth.ts, permitted by Edit(src/**).
  5. It re-runs the scoped test command β€” green.
  6. A side request to Read .env for a secret is denied by the Read(.env*) rule β€” least privilege holds. The scoped allowlist fired the safe branch; the blanket-Bash trap would have handed the model the whole shell.

S5 Β· Claude Code in CI/CD

flowchart LR
  PR[Pull request] --> GH[GitHub Action]
  GH --> CC[claude -p headless Β· stream-json]
  CC --> REV[Review comments / suggested edits]
  REV --> GATE{Blocking?}
  GATE -->|deterministic checks: tests, lint| BLOCK[Fail the check]
  GATE -->|advisory: AI review| COMMENT[PR comment]

Probes: headless mode + output formats; least-privilege tokens; pinning model + action versions; advisory vs blocking gates (block only on deterministic criteria); budget caps per run; audit logging; hooks inside CI for guaranteed formatting/tests.

πŸͺ€ Planted trap: making the AI review a blocking gate β€” the exam's philosophy: block on determinism, advise on judgment.

πŸ” See it run β€” one pull request through the pipeline

Entry point: a developer opens a pull request; the GitHub Action fires on the event.

  1. The runner invokes claude -p in headless mode with --output-format stream-json and a least-privilege token scoped to this repo.
  2. The harness calls the Claude API; the model reviews the diff and emits its findings as JSON.
  3. The Action consumes that JSON and posts it as a PR comment β€” advisory only, never blocking.
  4. In parallel, the deterministic gate runs the tests and lint.
  5. The Blocking? branch fires on determinism only: tests fail β†’ the check is failed and the merge is held; the AI review stays a comment.
  6. --max-turns capped the run so a loop couldn't burn budget silently, and the pinned model + action versions kept the run reproducible. Every step landed in the audit log.

S6 Β· Structured data extraction (JSON-schema validated)

Probes: the structured-output ladder (prompted JSON β†’ prefill β†’ schema-as-forced-tool β†’ validate + repair loop); stop_reason checking before parsing; additionalProperties: false; low temperature; batch API for volume; eval sets with field-level accuracy metrics; handling documents exceeding the window (chunk per document boundary, per-chunk extraction, deterministic merge).

πŸͺ€ Planted trap: "sometimes the JSON is cut off" β†’ max_tokens truncation, not a prompting problem.

πŸ” See it run β€” one invoice through the extraction ladder

Entry point: a nightly job sends one invoice's text to the Claude API with the extraction schema wired as a forced tool and temperature 0 for repeatable output.

  1. The model returns a tool_use block whose arguments are shape-constrained to the schema (additionalProperties: false β€” no stray fields).
  2. The harness checks stop_reason before parsing: tool_use means complete. Had it been max_tokens, the JSON was truncated β†’ raise max_tokens and retry, not reword the prompt.
  3. Application validation then runs on the parsed object β€” field types and business rules β€” because schema-valid is not the same as business-valid.
  4. An invoice larger than the context window is split on document boundaries, extracted per chunk, then deterministically merged β€” no model in the merge step.
  5. The volume branch: 10,000 invoices go through the batch API at lower cost; per-field accuracy is scored against an eval set before the run is trusted.

🎯 Meta-pattern across all six: find where the deterministic boundary should sit. Every scenario plants at least one question whose wrong answers move enforcement into the prompt and whose right answer moves it into the harness (gates, hooks, schemas, allowlists, budgets).