Skip to content
← BlogNotes · 10 min read

How I passed Claude Certified Architect – Foundations: what each domain really tests, how I studied, and the concepts that are easy to get wrong.

AIClaudeCode10 min

I have seven Salesforce certifications, so I know the drill: blueprint, notes, practice, exam day. Claude Certified Architect – Foundations, which I passed on 27 October 2026, felt different. Salesforce exams test how well you know a platform; this one tests judgement: which design holds up when two of them both work. It took me two weeks, about 1.5–2 hours a day, alongside full-time client work.

This post is not a list of questions (the exam is under NDA, and that’s not how you learn anyway). It’s how I studied, what each domain really asks of you, and the concepts that are easy to get wrong. You can check the badge on Credly.


🎯 Who This Exam Is For

The exam guide is clear: the target candidate is a solution architect who designs and implements production applications with Claude. It covers four technologies: Claude Code, the Claude Agent SDK, the Claude API and the Model Context Protocol (MCP).

The keyword in the guide is trade-offs. It isn’t a memory test about flags and file names, although you do need those. Every question starts from a realistic production scenario and asks for judgement, not definitions.

Plenty of designs “work” in a demo. The exam is about the one that holds up in production.

Format, price and scoring are on the exam page. What follows is what those pages don’t tell you.


🗺️ The Five Domains (and What They Really Test)

Fig. 1 — The blueprint: five domains, their weights, and what each one really asks of you.

Here’s my one-line version of each domain, after studying all 30 task statements:

  • Agentic Architecture & Orchestration (27%). How an agent loop actually runs, how a coordinator splits work across subagents, and when a rule must live in code (hooks, prerequisite gates) instead of in the prompt. Also sessions: when to resume, when to fork, when to start fresh with a summary.
  • Tool Design & MCP Integration (18%). Tool descriptions, structured error responses, giving each agent only the tools it needs, tool_choice, MCP server scopes, and picking the right built-in tool (Grep vs Glob vs Edit).
  • Claude Code Configuration & Workflows (20%). The CLAUDE.md hierarchy, skills and slash commands, path-specific rules in .claude/rules/, plan mode vs direct execution, and running Claude Code in CI with -p.
  • Prompt Engineering & Structured Output (20%). Explicit criteria instead of “be careful”, few-shot examples for ambiguous cases, tool_use with JSON schemas, validation and retry loops, the Message Batches API, and multi-pass reviews.
  • Context Management & Reliability (15%). Keeping exact facts alive in long conversations, when to escalate to a human, how errors travel between agents, confidence calibration and keeping track of sources.

📚 How I Studied

Fig. 2 — Four steps: Academy courses, notes per domain, real projects, then practice and review.

1. Anthropic Academy first

Before opening the guide, I did eight free Anthropic Academy courses:

  • Claude 101
  • Claude Code 101
  • Claude Platform 101
  • Introduction to MCP
  • Building with the Claude API
  • Claude Code in Action
  • Introduction to Agent Skills
  • AI Fluency They don’t map one-to-one to the exam, but they give you the vocabulary. The API course in particular is where the agent loop and tool use stop being abstract.

2. One Notion page per domain

Then I opened Notion and created one page per domain. I didn’t try to write it all from scratch. For each task statement I collected three kinds of sources: the official docs, examples other people had published, and articles that came at the topic from another angle.

Then I compared the sources. Where they agreed, that went into the note. Where they didn’t, I went back to the official docs and kept what they said. Each note ended up with the same four parts: the rule in one line, the concept, the traps, and a real-world example.

Fig. 3 — The template I used for every task statement. The traps section grew the most.

The traps section is the one that paid off. Comparing sources shows you where people get confused. Asking “what would a tired engineer do wrong here?” forces you to understand why the right answer is right. On exam day the wrong options look exactly like those traps.

3. Use it on real work

I use Claude Code every day on Salesforce projects, so most of what the exam covers was already part of my setup:

  • a CLAUDE.md per repository, plus personal preferences in my user folder
  • skills for repeated tasks and subagents for exploration
  • specs and plans before code
  • several MCP servers
  • hooks and a custom status line Studying didn’t give me new tools. It made me question the setup I already had, with three questions I now ask all the time.

Who needs to see this?

For every new piece of config, I ask whether the whole team needs it (project scope) or just me (user scope).

where each config lives (illustrative)
1~/.claude/CLAUDE.md user scope · only me 2./CLAUDE.md project scope · whole team 3.claude/rules/apex.md loads only for force-app/**/*.cls

Can code check it?

I started reading my CLAUDE.md differently. Any “always do X” line that code can check is a candidate for a hook, because a prompt is a request and a hook is a guarantee.

For example, take this line in a Salesforce CLAUDE.md:

plain-text
1Always run local tests when deploying to an org.

Claude will follow it most of the time. “Most of the time” is not good enough for a deploy, so the line becomes a PreToolUse hook in .claude/settings.json:

json
1{ 2 "hooks": { 3 "PreToolUse": [ 4 { 5 "matcher": "Bash", 6 "hooks": [{ "type": "command", "command": ".claude/hooks/require-tests.sh" }] 7 } 8 ] 9 } 10}
bash
1#!/bin/bash 2# Blocks any deploy that doesn't run tests. Exit code 2 = block, and stderr goes back to Claude. 3cmd=$(jq -r '.tool_input.command') 4if [[ "$cmd" == *"sf project deploy"* && "$cmd" != *"--test-level"* ]]; then 5 echo "Deploys must run tests: add --test-level RunLocalTests" >&2 6 exit 2 7fi

With the hook, Claude can’t forget. If it tries, the hook blocks the command and tells it why, and it fixes the command itself.

Main context or subagent?

This changed the most. When a task splits into independent parts, each part gets its own subagent and a complete brief. I launch them together so they run in parallel, and the main session only gets the conclusions back, which keeps its context clean.

For any change that matters, I also ask for a second opinion from an agent with no context. I give it the change itself, not my reasoning or what I expect it to find. An agent that already knows my conclusion tends to confirm it. A fresh one reads the code the way a reviewer would, and it often catches what I had stopped seeing.

4. Practice, then back to the notes

In the last few days I did timed practice sessions, one scenario at a time. I didn’t just count the score. Every wrong answer went back into the matching Notion page as a new trap, with one line on why I fell for it. By the end, the traps lists were the most useful part of my notes.


🧠 The Concepts That Are Easy to Get Wrong

Fig. 4 — Eight confusions that come back again and again, and what actually holds up.

The image has all eight. None of them is hard. They’re just easy to get wrong when you’re in a hurry.

stop_reason drives the loop, not the text

An agent loop keeps going while Claude asks for tools and ends when it says it’s done. It doesn’t end because the reply has some text, sounds finished, or contains the word “done”. An iteration cap is a safety net, not the way the loop ends.

agent_loop.py
1while True: 2 response = client.messages.create(model=MODEL, max_tokens=4096, tools=tools, messages=messages) 3 messages.append({"role": "assistant", "content": response.content}) 4 5 if response.stop_reason != "tool_use": 6 break # "end_turn" = done; max_tokens, pause_turn, refusal... need their own handling in production 7 8 results = [ 9 {"type": "tool_result", "tool_use_id": block.id, "content": run_tool(block.name, block.input)} 10 for block in response.content if block.type == "tool_use" 11 ] 12 messages.append({"role": "user", "content": results}) # answer every tool_use, not just the first

Tool descriptions drive tool choice

Claude picks a tool mostly from its description. When it keeps choosing the wrong one, the first fix is a sharper description that says what the tool does, what it takes, and when to use it instead of a similar tool. Few-shot routing examples or merging tools come later, if at all.

Prompts guide, code guarantees

If a step must happen every time (verify identity before a refund, back up before a delete), don’t write it louder in the prompt. Put it in a hook or a prerequisite gate: code that refuses to run step B until step A has succeeded. Keep prompts for judgement calls, and keep hard gates for the few steps where one failure is too many.

Subagents start from zero

A subagent does not inherit the coordinator’s context or remember earlier runs. Everything it needs goes in its prompt, with sources attached. If you want them in parallel, start them all in the same response. Starting one per turn makes them run one after another.

Project vs user scope

This one shows up all over Claude Code. Things the team needs go in the project: .mcp.json, .claude/commands/, .claude/skills/, the root CLAUDE.md. Personal and experimental things go in the user scope: ~/.claude.json, ~/.claude/CLAUDE.md. Secrets never go in the repo. Use environment variable expansion such as ${GITHUB_TOKEN} instead.

Context is a budget

Summaries turn exact numbers into vague prose, so keep amounts, dates and IDs in a facts block that is never summarised. Trim long tool results down to the fields you need. Send noisy exploration to a subagent so the main session stays clean.

A strict schema doesn’t mean correct data

tool_use with a JSON schema gets rid of syntax errors: no missing fields, no broken JSON. It doesn’t check meaning. Line items that don’t add up to the total, or a date in the wrong field, still pass. Add your own checks after the schema, and when one fails, send the specific error back to Claude for a retry.

Don’t let the author review its own work

Asking the same session to review the code it just wrote rarely finds much, because it reviews against its own reasoning. Use an independent instance with only the change, and run focused passes (one for security, one for logic) instead of one “review everything” prompt.


💡 What I’d Tell Someone Starting Today

  • Start from the guide, not from blog posts (including this one). The task statements are the syllabus, and the guide also has hands-on preparation exercises worth doing.
  • Build the small things. An agent loop with two similar tools, a structured MCP error, a skill with context: fork, a .claude/rules/ file with paths. Half an hour each, and you’ll remember them.
  • Read carefully, to the end. In real architecture one small detail (the scope, the order, the guarantee) is often what separates a good design from a fragile one.
  • Watch the clock, but don’t rush. There’s enough time if you don’t get stuck. Flag the hard ones and come back.

🏁 Prompt or Code? The Question I Now Ask Every Day

My Salesforce certifications taught me a platform. The biggest change wasn’t the badge. It’s that I now ask “prompt or code?”, “project or user?” and “main context or subagent?” every time I set something up in Claude Code.

If you already build with Claude every day, you’re closer than you think. Take the Academy courses, write your own notes per domain, build the small things and go for it. 🚀

If you’re building with Claude on Salesforce and want a second pair of eyes, get in touch.

Happy coding! 👨🏼‍💻

Written by Ricardo SimõesSalesforce + AI developer · Portugal / Remote
Questions about this post, or just want to talk Salesforce and AI? Happy to chat.
0Comments

Comments

Loading animation
→Keep readingAll posts →