Hooks designed to fail open for AI coding agents
A memory tool that blocks your coding agent is worse than no memory at all. That one rule shaped Aletheia’s hooks: a hook should not stop the tool that called it, whatever goes wrong. The hooks are built to fail open. This post covers what that includes and what it does not.
The rule
A hook is a command a tool runs at fixed moments. Aletheia’s entry point is aletheia hook <tool> <event>. It reads one JSON payload on standard input. If anything fails, it prints nothing and exits with code 0. The host sees success and carries on. (When it works, the session-start hook does print the context block.)
What “anything” includes
| Failure | What happens |
|---|---|
| The database is locked by another process | The hook waits up to 50 ms, then writes the item to a spool file and exits 0 |
| The database file is missing or unreadable | The item goes to the spool |
| The payload is not valid JSON or is empty | Nothing is stored, exit 0 |
| The project is excluded by configuration | Nothing is stored, exit 0 |
The spool is a JSON-lines file in the data directory with mode 0600. The next hook that finds the database healthy drains it first. I tested both paths in a temporary home: a store made unavailable on purpose, and a write lock held by another process. In both, the next hook flushed the spool and a search found the rows. The payloads were written by hand, not sent by a real host.
One gap matters. A watchdog ends the hook after 150 ms. If it fires while a write is in flight, that item is not spooled and is lost (the hooks reference says so). I did not trigger it.
What it costs
In my tests a post-tool hook took 0.04 to 0.05 seconds, and about 0.1 seconds while another process held the write lock. Those are single measurements on one machine, not a benchmark.
The trade-off
Fail-open means a broken hook is silent. The answer is a check you run on purpose: aletheia doctor reports the server, the hooks, the spool and the last capture, and shows a failing spool as a failure. Silence in the hook, noise in the doctor.
A host-side surprise
Some hosts ask you to approve a hook before it runs. Codex reviews non-managed hooks and skips new or changed ones until you trust them, using its /hooks screen. An installed hook that is not trusted yet does nothing, which is easy to mistake for a broken hook.
What I would do differently
I would have built doctor before the hooks. Fail-open without a way to see failures is just hiding them.
Sources
- Aletheia hooks reference, fetched 2026-10-30
- Codex hooks documentation, fetched 2026-10-31
