Skip to lesson

AnthropicClaude Certified Architect – Professional2026-103.8 Evaluate progressive discovery vs. monolithic context strategy

Govern capabilities after they are discovered

Completed by the knowledge check

Learning objective

Preserve policy enforcement, auditability, and reproducibility when tools or context load dynamically.

Core idea

A role-specific tool set and a blocking PreToolUse check establish known execution boundaries. Dynamic discovery adds another responsibility: keeping those boundaries complete when the operation becomes visible only partway through the run.

Treat discovery as a context-loading decision, not an authority decision. A search result can tell Claude how to call an operation; it must not decide whether the principal may call it. Likewise, an acquired procedure explains a workflow without becoming the source of permission to perform it. Preserve the loaded inputs and the execution decisions separately so an investigator can reconstruct both.

How it works

Keep the discoverable set inside the approved set

In the Messages API, defer_loading: true changes when a definition enters Claude’s context. Every deferred definition still belongs in the request’s tools array. Construct that array from the role’s approved capabilities before choosing which members to defer. See 3.8.2 for loading mechanisms.

A forbidden tool remains reachable through search if it is merely deferred; see 3.1.2 for privilege removal. Your direct client-tool executor must also verify the requested tool_use.name and arguments against its trusted registry before dispatching the handler. The registry’s authorization and schema checks belong to application code; tool search does not implement your business policy.

The same distinction applies to documents. Scope the resource or filesystem reader to the principal’s permitted sources before returning their contents. A catalog can expose useful structure while a detail read remains unauthorized. See 3.2.2 for resource-scoped execution; here the additional requirement is that dynamically loaded material follows the same boundary as preloaded material.

Cover discovered calls with the policy check

For an Agent SDK workflow, register PreToolUse under hooks. A tool-specific matcher covers only the names it matches. If your policy must inspect every discovered operation, deliberately omit the matcher and dispatch inside the callback using tool_name and validated tool_input. The SDK documentation specifies that hooks without a matcher run for every event of that type.

Use a trusted operation classification rather than assuming the name proves the effect. An application can classify mcp__casework__release_payment as a payment operation, for example, and require a valid case approval. That name and classification are illustrative application choices, not Anthropic built-ins. An operation absent from the classification registry should receive an explicit denial until the registry owner classifies it.

Return the denial through hookSpecificOutput.permissionDecision: "deny"; the additional requirement here is complete coverage of discovered operations. A callback that checks only yesterday’s payment-tool name misses a discovered replacement unless its coverage or registry also changes.

If the approval lookup fails, your callback should deliberately return a denial for a policy that requires positive approval. Do not rely on an unhandled exception to express that policy.

So every discovered operation reaches the same hook, and an unclassified operation, a payment without a valid case approval and a failed approval lookup all end in an explicit denial.

Every discovered operation reaches the same hook, and an unclassified operation, a payment without a valid case approval and a failed approval lookup all end in an explicit denialStarts at a discovered operation, which reaches the hook without a matcher on every event. The hook applies the trusted operation classification. An operation absent from the registry goes straight to explicit denial. A payment operation goes to the case approval check, where a missing approval or a failed lookup also ends in explicit denial.every eventabsent from the registrypayment operationno, or the lookup failsDiscoveredoperationHook without amatcherTrusted operationclassificationValid caseapproval?Explicit denial

For a Claude Code PreToolUse command hook, exit code 2 blocks the operation. With plain text or no stdout, exit code 1 is a non-blocking error by default; valid decision JSON follows its own parsing rules. For a command or http policy hook that must also block on failure, set onFailure: "block" in its hook configuration. This requires Claude Code v2.1.295 or later. Test a missing checker as well as a rejected operation: an explicit business denial and a checker failure are separate paths.

Record acquisition and execution as separate events

Tool search exposes the acquisition path through server_tool_use, the search input’s pattern or query, and the returned tool_references. Record no-match outcomes as well as matches. Preserve the definitions used by the request so a discovered name remains interpretable after a catalog release.

For SDK client operations, the hook input includes session_id, hook_event_name, tool_name, and tool_input. The callback’s tool-use ID correlates PreToolUse and PostToolUse. Record the policy decision alongside that identifier, then join it to the execution outcome. A denied call has no successful execution merely because Claude subsequently claims completion.

Add application-owned release identifiers for the policy registry, Skill package, catalog, and retrieved source. These are your audit record fields, not extra SDK hook fields. Store the actual permitted content or a retrievable immutable snapshot; a mutable URI or filename alone cannot explain what Claude read during an earlier run. Apply the organisation’s access and retention rules to the record itself.

Reconstruct inputs without promising identical output

For Messages tool search, pass the assistant content back unchanged, including server_tool_use and tool_search_tool_result, and retain the same complete tools array across continuation requests. The API expands recorded tool_reference blocks throughout the conversation. Do not replace search results with a final-answer summary and expect it to preserve the acquisition history.

For API Skills, pin container.skills[].version to the intended release; the documented latest selector permits the package to change. For local Skills, retain the deployed package revision and supporting files. See 2.5.3 for Skill release delivery.

A reconstruction should recover the model selection, request settings, ordered context, discovery results, policy release, and actual tool outputs. Run investigative replays against recorded read results or an isolated executor so replay does not repeat production writes. Identical recorded inputs make an incident explainable; they do not guarantee identical model output. Separate input reconstruction from deterministic business execution.

Key distinctions and trade-offs

Dynamic loading requires three independent assurances:

AssuranceConcrete implementation
A discovered capability remains authorizedApproved tools registry and executor checks, or SDK PreToolUse coverage
The run can be auditedAcquisition records joined to policy decisions and tool-use IDs
The inputs can be reconstructedReleased definitions, pinned procedures, and captured source results

Recording only the final answer loses discovery misses and denials. Recording every raw object without access controls can duplicate sensitive context unnecessarily. Retain the specific inputs and decisions required for the organisation’s investigation purpose, with an accountable retention owner.

Architecture / decision scenario

A government casework service may discover payment and document tools during a case. Its operating requirement is that every payment has a trusted approval and that investigators can reconstruct the inputs for 180 days. Its pilot catalog grows from 20 to 60 operations; these figures are scenario constraints.

The tempting proposal defers all payment tools and relies on a payment procedure to explain approval. It logs only the final answer. The architect rejects it because a loaded procedure cannot enforce approval and a final answer cannot identify which version or approval decision governed a discovered call.

The service owner restricts the approved registry. In the SDK variant, a PreToolUse callback without a matcher classifies every proposed operation and denies payments lacking trusted approval. The audit writer correlates session and tool-use IDs with the policy release, selected definitions, loaded procedure revision, retrieved content, and backend outcome.

Before rollout, the owner tests a discovered payment alias absent from the classification registry, a failed approval lookup, and a changed document at the same address. The alias and failed lookup must remain unexecuted; the earlier document content must remain reconstructable. An investigator replays the captured read results with writes disabled. The governance choice accepts additional recordkeeping to preserve authority and explainability as the catalog expands.

Common exam traps

  • Granting a discovered operation the classification its name suggests.
  • Assuming an exact-name hook covers dynamically introduced aliases.
  • Taking approval from an acquired runbook or model-supplied justification.
  • Logging a discovered tool’s name without the definition release it resolved to.
  • Relying on a plain-text exit-1 policy failure without onFailure: "block".
  • Retaining only mutable source addresses or only the final answer.
  • Replaying production writes to reproduce an inference.

What to remember

Discovery changes visibility, not authority. Cover every reachable execution path, correlate acquisition with policy and backend outcomes, and retain released inputs for reconstruction without promising deterministic inference.

Knowledge check

References