Controls / 8 min
A guard that handles “deny” correctly can still behave differently when its own code fails.
Proposed worksheet · Method notes updated 2026-11-11 · No independent effectiveness test
The decision
Audit the exact pre-action guard and rehearse its failure behavior before relying on it.
Use this when
A Python hook in Claude Agent SDK is part of the path that controls a consequential action.
Skip this when
You do not use the SDK, or the hook only adds optional telemetry. Preserve the ordinary authorization layer either way.
Work through the checks
Inspect the deployed pair
Record the SDK, bundled CLI, hook event and actual configuration. The recovered source review identifies on_failure="block" in Python SDK v0.2.177; its default remained continue. This is a dated feature reference, not a current-version recommendation.
Check capability, not just configuration
Confirm the runtime supports and applied the required behavior. The reviewed change describes refusing connection when blocking support is absent. Stop hooks have different behavior; do not generalize this setting to every hook.
Use a harmless effect counter
In an authorized isolated environment, use a local counter instead of a real message, payment or production change. Exercise allow, deny, exception, None, malformed response and timeout.
Inspect effects and errors together
Allow should increment the counter once. Deny and required failure cases should leave it unchanged and expose a detectable failure. Unsupported blocking capability should stop startup rather than continue silently.
What would count as success?
- The valid path works; a system that denies everything does not pass. Evidence for check 1
- Each failure case preserves the required authorization boundary. Evidence for check 2
- Capability absence is visible and prevents use of the affected path. Evidence for check 3
Evidence to bring back
Proposed evidence plan, not observed results or extra mandatory process. Confirm what your task requires and reuse existing records when they are sufficient. Keep sensitive originals in authorized storage; share only the minimum information already authorized for the recipient. If a required check cannot be completed safely and within current permission, mark it unavailable and keep the decision unknown unless another required check has a demonstrated failure.
The valid path works; a system that denies everything does not pass.
Proposed evidence for acceptance check 1. No result has been observed here.
Bring back: Record the exact SDK/CLI configuration and a harmless allow-case trace with effect count before and after. The valid case should show one intended effect.
Not enough: A suite in which all actions are denied, or an allow response without inspecting the effect.
Each failure case preserves the required authorization boundary.
Proposed evidence for acceptance check 2. No result has been observed here.
Bring back: Keep one result per deny, exception, None, malformed-response and timeout case: input, expected boundary, observed error and effect-counter delta. Use only the authorized isolated fake sink.
Not enough: A hook error or log message without checking whether the effect still happened.
Capability absence is visible and prevents use of the affected path.
Proposed evidence for acceptance check 3. No result has been observed here.
Bring back: Record an unsupported-capability rehearsal and the resulting startup or connection refusal. Identify the SDK/runtime pair actually exercised.
Not enough: A configuration flag or release note by itself; neither proves the deployed pair enforces it.
Stop or recover
Keep the action disabled or behind its existing human gate if a required case fails. Reverting to a fail-open configuration is not a safe rollback.
What this does not establish
The specific SDK change was rechecked against primary sources on 10 November 2026, but its behavior was not rerun for this reconstruction. Verify the current deployed SDK/CLI pair before use. Source review is not runtime validation.
Reference links
These links leave the saved pack when selected. Check whether dated guidance still applies before relying on it.
- Claude Agent SDK Python v0.2.177 (Online source)
Primary release record for introduction of HookMatcher on_failure. Supports the dated feature claim, not a claim about your deployed configuration.
Source review date: 2026-11-10
- HookMatcher on_failure change (Online source)
Same-publisher implementation detail for blocking hook failure handling and capability checks. Not independent runtime validation.
Source review date: 2026-11-10
Keep your own evidence
The draft already identifies this method and its proposed requirements. Confirm those requirements against your task, then supply only the scope and observations you are authorized to record. No evidence or permission is prefilled. Reuse an existing suitable record if you have one.
- Open this guide’s Markdown draft
- Open this guide’s JSON draft
- Inspect the guide’s source hash and method identity
Your browser may show or download text files. Edit a separate working copy in your usual editor. This reader does not accept or save your answers.
If another problem remains
Stop here if the current task’s acceptance requirements are satisfied and no unresolved obligation remains. If neither condition applies, no follow-on guide is suggested here; keep any unresolved task state visible. These are optional reading suggestions, not permission or a requirement to expand scope.
Only if: A failed or interrupted guard path leaves the underlying effect uncertain.
Check the outcome before retryingSeparate the guard response from the authoritative operation outcome before retrying.
Only if: The required boundary works and you now need to compare its overhead or usability.
Measure improvement in accepted resultsMeasure the authorized change against the same quality and control requirements.