Static reading edition · s06-07
Debug hooks as small integrations
Isolate discovery, trust, matching, runtime, and response failures with offline tests.
Understand the approach
A hook that produces no visible result may never have been discovered, may need trust review, may not match, may fail to launch, or may return output that the event ignores. Debug these stages separately. Repeatedly changing all configuration at once destroys the evidence. Start with the current source inventory and one fictional input that has a clear expected result.
In Codex CLI, /hooks exposes configured sources, review status, and controls for non-managed hooks. This is different from the source course's Claude debug flag and shortcut. Managed hooks can be enforced by policy and may not be disableable from the user browser. Reading their status does not authorize changing organization controls. Record the exact client and execution host before deciding a hook is absent.
Run a proposed handler independently with fictional stdin before connecting it. Check the interpreter, path quoting, cwd assumptions, stdout, stderr, exit status, and timeout. Then inspect event selection and trust separately. Concurrent handlers and background delivery can make observed order misleading; tag local test output with a fictional case identifier rather than inferring a sequential lifecycle from timestamps alone.
Debug the first failing boundary
Check discovery, trust and event matching, interpreter startup, then the output contract. Repair the earliest demonstrated failure before changing later stages. A valid JSON response is not proof that the event was delivered by a real client.
Retain a minimal incident record
Keep the client version, redacted configuration excerpt, fixture identifier, expected result, observed result, and one next experiment. Avoid copying a whole transcript when a single event explains the defect. The transcript format is not a stable hook interface and can include sensitive material. A compact incident record makes it easier to reproduce a bug after a runtime update and to tell a new configuration defect from a changed product contract.
About your environment
Verified October 21, 2026. /hooks is documented for Codex CLI. App surfaces and managed policy differ; use the actual available inspection tools and keep this lab inactive.
Try it step by step
- Run the unchanged policy suite and combined depth suite to isolate a code regression before touching client configuration.
- Replay one exact failing input and inspect stdout, stderr and exit status; distinguish an intentional deny from a launch failure.
- Inspect the generated absolute interpreter path and cwd assumptions on the actual execution host.
- In /hooks inspect source, enabled state, current trust and event/matcher. Change only the failing stage, then repeat the same covered operation.
- Restore any deliberately broken scratch copy, disable the practice definition and retain a concise before/after report with version and observed event.
A useful starting example
Illustration · adapt before use.
node labs/hook-policy/demo.cjsDiagnose this draft hook without activating it.
Inspect its source location, event, matcher, interpreter, script path, and expected output contract.
Use fictional input only. Distinguish not discovered, awaiting trust, not matched, launch failure, and invalid output.
Return one smallest next test for each unresolved stage. Do not weaken policy or trust hooks.Failure and denial are not interchangeable
The demo compares malformed stdin with a nonexistent handler file.
node labs/hook-policy/demo.cjsmalformed JSON: deny | handler exit 0
missing handler: launch failed | exit 1 | no policy responseThese lines are measured from local child processes. The second case cannot establish a policy denial because the handler never started.
Your turn
Diagnose one fixture-level failure and one deliberately wrong path in a generated configuration. Repair only that scratch configuration and rerun the same case. A complete report identifies discovery, trust, matching, launch, output-contract or artifact freshness as the failing stage, with actual evidence rather than a generic reinstall recommendation.
Try the exercise before opening its reference answer. Use a disposable practice folder.
Diagnose failure at the right layer
Extract into a new practice folder and keep the included labs folder. Run these commands from that extraction root, or from the course folder, using an existing Node.js installation.
- Command 1 text
node labs/hook-policy/demo.cjsCheck: Separates invalid-input denial from missing-handler launch failure.
- Command 2 text
node --test labs/hook-policy/test.cjsCheck: 13 passing checks preserve the distinction between policy decisions and integration errors.
Fix the failing layer; a launch error is not a denial and offline success is not client discovery.
Check your result
- The report distinguishes policy denial, input validation, no-match coverage, and process launch failure.
- Every conclusion names a reproducible fixture and observed channel or status.
- The final baseline passes and client discovery/trust remain unrun unless actually observed.
Reference answer & rubric Try the exercise before opening
A useful diagnostic report names the first failing layer and one reproducible next test.
- Start with a passing allow fixture to establish the handler contract and runtime.
- Use malformed-field.json to show input validation, then compare malformed JSON with the missing executable case.
- Regenerate paths after moving the lab rather than broadening permissions to hide a missing-file problem.
- Inspect /hooks and exact definition trust only in a chosen supported scratch client; do not assume the offline run loaded it.
- Record client/host/version and redact logs if a real integration problem remains.
- For native practice, follow NATIVE-CLIENT.md through discovery, current-definition trust, covered tool observation and disabling; record unrun stages honestly.
Check your understanding
A handler exits because its runtime path is wrong. What should you conclude?
- The policy check passed because no warning was printed.
- The runtime should be fixed by disabling the sandbox.
- The handler failed to launch; blocking behavior still needs separate verification.
Reveal the answer and explanation
Answer 3: The handler failed to launch; blocking behavior still needs separate verification.
Launch failure and policy success are different outcomes. Fix the path and verify the event's documented failure behavior.
Take this quiz in the interactive lesson to save your answer in the browser.
When it does not work
The handler file exists but the command cannot launch it.
Likely cause: Runtime resolution or shell quoting differs from the draft.
What to try: Regenerate with the actual runtime and inspect commandWindows; replay locally before changing trust or permissions.
A changed hook was skipped after editing.
Likely cause: Definition trust is tied to the reviewed definition.
What to try: Review the exact changed scratch definition through supported controls; never bypass owner or managed policy.
Common mistakes
- Using another product's debug switches and interpreting their absence as missing hook support.
- Fixing a launch error by turning off trust review or assuming all handler failures block the tool.
Source mapping & differences · different
The isolation strategy transfers, but Codex inspection uses its documented hook browser and event contracts rather than Claude-specific debug commands.
Source topic: Debugging hooks ↗Go to the source
Official documentation, checked 21 October 2026. Product names, controls and availability may vary with your version, platform or account.
Completion and quiz progress are saved
only in the interactive course.