A finding you have to remember to go and look at is a finding you do not see. This closes the loop: `fathom insights` reports findings for other programs, a Claude Code Stop hook runs it when a turn ends, and /insights shows the detail on request. The CLI reports as text, --json, or --jsonl, and --new returns only what has not been reported before. The server owns the reported-findings state, because two sessions can end at the same moment and a read-then-write would have both report the same thing. Two rules follow from running on every turn: - It must be fast. --hook asks a running server for an analysis already computed rather than doing one, and never falls back to analysing directly, which could take seconds. Measured at ~20ms whether or not a server is up. - It must never disrupt the session it observes. Every path exits 0 and prints at most one line. A Stop hook exiting 2 tells Claude Code to keep going rather than stop, so a crash here would hijack the session it was supposed to quietly watch. Surfacing is a higher bar than appearing in the tab, and biased towards silence. A tab is consulted; a notification arrives whether or not you wanted it, and the costs are asymmetric -- a missed finding waits patiently, a wrong nudge trains you to ignore all of them. Medium severity and $0.50 minimum, not already reported unless it has recurred since, and at most one nudge every two hours. A local model, if one is running, can veto a finding as not worth interrupting for. It can never promote one that did not clear the bar, is never consulted about findings below it, and a model failure keeps the finding rather than silencing it. Findings it rejects are recorded, so it is not asked the same question every turn. Also fixes a latent hazard this would have made routine. OpenShard runs tail recovery, which truncates, so a CLI opening a store the server is mid-append to could cut off the chunk being written -- the reader destroying the writer's data. Added a read-only open that skips recovery and opens O_RDONLY, and pointed every read-only command at it, including `fathom query`, which had the same problem already. The nudge's cost figure counted each finding separately, so a set of them could claim more money than the window ever spent: $12.52 against a window costing $7.94. Now counted once per trace. claude/ ships the skill and the hook snippet with an installer. The snippet is printed rather than applied, because a script should not blindly edit a settings file that may already have hooks in it, and a mangled settings.json silently disables everything in it.
Claude Code integration
Two pieces that close the loop between Fathom noticing something and you hearing about it.
The problem they solve
A finding you have to remember to go and look at is a finding you do not see. Fathom's Insights tab is only consulted if you think to open it, which is exactly when you are least likely to.
/insights — the skill
Shows what Fathom found, in the terminal. It runs fathom insights and relays
the output; it does no analysis of its own and does not read your traces.
The Stop hook — the nudge
Runs fathom insights -hook when a turn ends. If something new has turned up
that is worth the interruption, it prints one line:
You've got insights on your Claude usage — Flaky test triage, asked 10 times ($1.25). Run /insights to learn more.
Otherwise it prints nothing.
What it costs you
Nothing per turn, and about 20ms. It asks the running server for an analysis already computed rather than doing one, makes no API calls, and never blocks: any failure — no server, a timeout, a bad response — prints nothing and exits zero.
A Stop hook that exits 2 tells Claude Code to keep going rather than stop, so this one is written to exit 0 on every path. It cannot hijack the session it is supposed to quietly observe.
What it takes to interrupt you
Deliberately more than it takes to appear in the tab. A tab is consulted; a notification arrives whether or not you wanted it. The cost is asymmetric — a missed finding waits patiently, a wrong nudge trains you to ignore all of them — so the bar is set to stay quiet:
- medium severity or higher, and at least $0.50
- not reported before, unless the pattern has recurred since
- at most one nudge every two hours
- and if a local model is running, it can veto a finding as not worth the interruption. It can never promote one that did not clear the bar.
Tune with fathom insights -min-severity high -min-cost 2 -cooldown 6h, or see
the flags on fathom insights.
Install
./claude/install.sh
Copies the skill and prints the hook snippet for you to merge. The snippet is
printed rather than applied because a script should not blindly edit a settings
file that may already have hooks in it, and a mangled settings.json silently
disables everything in it.