Skip to content

CCAR-F · Domain 1: Agentic Architecture & Orchestration · 27% of the exam

Task 1.5: Apply Agent SDK hooks for tool call interception and data normalization

PreToolUse and PostToolUse hooks that block or redirect policy-breaking tool calls and normalize tool results before Claude reads them, and when a deterministic hook beats a prompt instruction.

Study it

  • Agent SDK hooks: PreToolUse to block or redirect, PostToolUse to normalize results

    Partly covered by: Guardrails

Sample questions

Try each one before opening the answer. Every option is explained, with the Anthropic documentation page that proves it.

Question 1 · choose 1

Your support agent reads order data from three third-party MCP servers. One returns dates as Unix timestamps, one as ISO 8601 strings and one as "MM/DD/YY", and statuses arrive as numeric codes from one server and as words from the others. Claude sometimes miscalculates return windows. You cannot change the servers. What is the most reliable fix?

  1. AAdd a PreToolUse hook that converts the dates in each tool call's arguments to ISO 8601 before the request reaches the server
  2. BDescribe each server's date and status format in the system prompt and ask Claude to convert them before reasoning
  3. CAsk Claude to call a date-conversion tool after every order lookup before it answers
  4. DAdd a PostToolUse hook that rewrites each result into one date and status format before Claude reads it
Show the answer and why
  • AAdd a PreToolUse hook that converts the dates in each tool call's arguments to ISO 8601 before the request reaches the server

    Incorrect

    PreToolUse runs before the call and sees its input; the inconsistent formats are in the results that come back.

  • BDescribe each server's date and status format in the system prompt and ask Claude to convert them before reasoning

    Incorrect

    This asks Claude to do the conversion correctly every time, which is the probabilistic step that is already failing.

  • CAsk Claude to call a date-conversion tool after every order lookup before it answers

    Incorrect

    An extra tool call per lookup adds latency and still depends on Claude remembering to make it.

  • DAdd a PostToolUse hook that rewrites each result into one date and status format before Claude reads it

    Correct

    A PostToolUse hook can replace a tool's output before Claude sees it, so every result arrives normalized on every call.

Normalize heterogeneous tool results deterministically with a PostToolUse hook. It intercepts the result after the tool runs and before Claude processes it, so the model always reasons over one format.

Question 2 · choose 1

Policy says refunds above $500 must go to a human. Your Agent SDK support agent calls process_refund on an MCP server named billing, and it runs without a person present. Small refunds should still go through automatically, and when a large one is attempted Claude should escalate instead. Which design meets all three requirements?

  1. AState the $500 limit in the system prompt with examples of escalating larger refunds
  2. BLeave process_refund out of allowedTools, so that every refund has to wait for a human to approve it before it runs
  3. CAdd a PostToolUse hook that reverses any refund above $500 and then tells Claude to escalate
  4. DA PreToolUse hook on mcp__billing__process_refund that denies calls over $500 and says to escalate
Show the answer and why
  • AState the $500 limit in the system prompt with examples of escalating larger refunds

    Incorrect

    Prompt rules are followed most of the time, not every time, which is not enough for a financial limit.

  • BLeave process_refund out of allowedTools, so that every refund has to wait for a human to approve it before it runs

    Incorrect

    Unlisted tools fall through to the permission mode; with no one present to approve, small refunds are blocked as well.

  • CAdd a PostToolUse hook that reverses any refund above $500 and then tells Claude to escalate

    Incorrect

    PostToolUse fires after the tool already ran, so the money has moved before the hook can react.

  • DA PreToolUse hook on mcp__billing__process_refund that denies calls over $500 and says to escalate

    Correct

    A PreToolUse hook runs before the call, can return a deny decision with a reason Claude reads, and lets every other refund through.

Use a PreToolUse hook to intercept outgoing tool calls that break a business rule: deny them deterministically and redirect Claude to the alternative workflow. Hooks give a guarantee that prompt instructions cannot.

Question 3 · choose 1

Whenever lookup_order returns an order flagged as a gift, you want Claude to see a note that refunds for gifts go to the purchaser, alongside the result. The result itself should stay unchanged. What should the PostToolUse hook return?

  1. AadditionalContext with the note, appended to the tool result
  2. BupdatedToolOutput with the note in place of the original result
  3. CpermissionDecision "deny" with the note as the reason
  4. DA systemMessage, which Claude reads as part of the tool result
Show the answer and why
  • AadditionalContext with the note, appended to the tool result

    Correct

    additionalContext adds information next to the result without replacing it.

  • BupdatedToolOutput with the note in place of the original result

    Incorrect

    Replacing the output would drop the order data.

  • CpermissionDecision "deny" with the note as the reason

    Incorrect

    Permission decisions belong to PreToolUse and would block the lookup.

  • DA systemMessage, which Claude reads as part of the tool result

    Incorrect

    systemMessage is shown to the user, not added to the result for Claude.

In PostToolUse, additionalContext adds information alongside a tool result and leaves the result itself unchanged.

Question 4 · choose 1

You want to record every failed tool call (the tool, its input and the error) in your observability system. Successful calls are already logged by another hook. Which hook event fits?

  1. APreToolUse
  2. BPostToolUseFailure
  3. CPostToolUse
  4. DSessionEnd
Show the answer and why
  • APreToolUse

    Incorrect

    PreToolUse runs before the call, so the outcome is unknown.

  • BPostToolUseFailure

    Correct

    It fires when a tool execution fails.

  • CPostToolUse

    Incorrect

    PostToolUse runs after successful executions.

  • DSessionEnd

    Incorrect

    SessionEnd runs when the session ends, not for each failed call.

PostToolUse covers successful tool runs; PostToolUseFailure covers failed ones.

Question 5 · choose 1

In interactive Claude Code sessions, you want any command that touches the production database to stop and ask the developer at the keyboard for confirmation, even when other rules would allow it. What should the PreToolUse hook return for those commands?

  1. ApermissionDecision "ask", with a reason shown in the prompt
  2. BpermissionDecision "deny", with a note to retry later
  3. CpermissionDecision "allow", with a warning in the reason
  4. Dexit code 1, which pauses the command for review
Show the answer and why
  • ApermissionDecision "ask", with a reason shown in the prompt

    Correct

    "ask" sends the call to the permission prompt so the developer decides.

  • BpermissionDecision "deny", with a note to retry later

    Incorrect

    Denying blocks the command; the developer never gets to decide.

  • CpermissionDecision "allow", with a warning in the reason

    Incorrect

    "allow" skips the prompt the developer should see.

  • Dexit code 1, which pauses the command for review

    Incorrect

    Exit 1 is a non-blocking error; the command proceeds.

A PreToolUse hook's "ask" decision routes the call to the user's permission prompt with your reason, even where rules would allow it.

Question 6 · choose 1

Your /db-migrate skill should run a schema linter after every file edit, but only once the skill has been invoked, not in every session. Where should the hook be defined?

  1. AIn the project CLAUDE.md, as an instruction to lint after edits
  2. BIn ~/.claude/settings.json, so that it runs for every session
  3. CIn a .claude/rules/ file scoped to migration paths
  4. DIn the skill's own frontmatter, as a hooks entry
Show the answer and why
  • AIn the project CLAUDE.md, as an instruction to lint after edits

    Incorrect

    CLAUDE.md is guidance; it does not register hooks.

  • BIn ~/.claude/settings.json, so that it runs for every session

    Incorrect

    User settings hooks run everywhere, not only after the skill.

  • CIn a .claude/rules/ file scoped to migration paths

    Incorrect

    Rules load instructions; they do not run commands.

  • DIn the skill's own frontmatter, as a hooks entry

    Correct

    Hooks in skill frontmatter are registered on invocation and stay for the rest of the session.

Hooks can be defined in skill and subagent frontmatter, scoping them to the time after the skill is invoked or to the subagent's run.

Question 7 · choose 1

You wrote a PostToolUse hook with matcher "Edit.*" to format files after Edit calls. It also fires when Claude edits Jupyter notebooks through NotebookEdit, where the formatter breaks the notebook. How should you fix the matcher?

  1. AChange it to "edit" in lowercase
  2. BAnchor it as ^Edit$ or list Edit|Write
  3. CMove the hook to PreToolUse so it runs before NotebookEdit
  4. DChange it to "*" and check the tool name inside the script
Show the answer and why
  • AChange it to "edit" in lowercase

    Incorrect

    Tool names are case-sensitive; this matches nothing.

  • BAnchor it as ^Edit$ or list Edit|Write

    Correct

    Regex matchers are unanchored, so Edit.* also matches NotebookEdit.

  • CMove the hook to PreToolUse so it runs before NotebookEdit

    Incorrect

    The event changes when it runs, not which tools match.

  • DChange it to "*" and check the tool name inside the script

    Incorrect

    This runs the hook for every tool just to filter it again.

Matchers with special characters are unanchored regular expressions; anchor them or use exact names to avoid matching tools such as NotebookEdit.

Practise domain 1 →Practise all domains →