I Replaced All My Hooks With Mods. Here’s What Changed.
Description and use
Three hooks became shorter, one became possible, and one revealed a security hole in the trust model.
Problem
Five settings hooks (guard, logger, notifier, auto‑approver, context counter) were cumbersome, stateless, and limited in UI capability.
Outcome
Three hooks became shorter, one became possible (notifier), and one revealed a security hole (auto‑approver). Stateful mods reduced I/O and enabled shared state.
Workflow
- 1. Replace guard script with a mod that registers on "tool.call" and denies risky commands.
- 2. Replace notifier script with a mod that hooks "turn.complete" and draws duration and token delta.
- 3. Replace auto‑approver script with a mod that answers "tool.call" events for safe commands and test chain order.
- 4. Replace logger and counter scripts with mods that maintain state in $.state and share between hooks.
- 5. Validate and test the mod chain with "claude plugin test" to ensure guard still denies when approver is loaded.
Evidence
A settings hook is a shell command that Claude Code runs on a lifecycle event, passing JSON over stdin and stdout.
A mod is different. It loads once, stays in the session, keeps state, and its hooks are middleware: observe, rewrite, or answer each event in-process.
A mod that approves tool calls can approve one that an ask rule would prompt for, or that one of your own PreToolUse hooks blocked.
- Record date: 2026-10-06T15:10:59.267Z