Hooks docs: four payload field divergences vs shipped behavior (2.1.207, captured)
Summary
Four divergences between the hooks reference documentation and the payloads Claude Code actually delivers, all captured live on v2.1.207 (macOS) with a minimal probe: a project whose .claude/settings.local.json defines hooks that tee stdin to a file, driven by headless claude -p sessions.
Observed vs documented
| Event | Documented | Observed (captured payload) |
|---|---|---|
| PostToolUse | tool_output | tool_response (object) |
| SessionEnd | end_reason | reason |
| UserPromptSubmit | user_prompt | prompt |
| SessionStart | (common-fields table can read as if permission_mode is universal) | no permission_mode on SessionStart; present on UserPromptSubmit / PreToolUse / Stop |
On the fourth row: the current docs do say "Not all events receive this field," which is accurate — the ask is just to make each event's example JSON authoritative and complete, since a hook gating on a field its event never receives fails silently (empty var → the false branch, forever, with no error surface).
Suggested fix
Align the per-event example payloads in the hooks reference with the shipped field names above, and consider noting per event whether permission_mode is delivered.
Raw captured payloads available on request — they're single-line JSON files produced by the tee probe described above, trivially reproducible on any machine.