The quiet hooks that keep your diffs clean
Not every agent hook blocks something. The ones I hit most just tidy up after each edit: format the file, catch the test you accidentally focused, leave a paper trail you can grep later.
Blocking hooks get the attention, but the ones I run into most never block anything. They fire after the agent edits a file, or when a session starts, and they quietly do the small chores that otherwise pile up into a messy pull request. Individually they are almost too boring to mention. Together they remove a whole category of tiny mistakes.
Format on every edit
When an agent writes a file straight to disk, it does not trigger your editor's format-on-save, because there is no editor in the loop. So unformatted code lands, and the formatting check in CI goes red over indentation of all things. A hook that runs the formatter on just the file that changed closes that gap. I keep it formatter-only and fast, and leave the heavier lint-and-fix step for commit time, so editing never feels laggy. If a project has no local formatter installed, the hook simply does nothing rather than erroring.
Catch the CI-killers before they land
A single focused test is a genuinely nasty thing to ship. Leave a stray 'only' on one test and the runner silently skips every other test in the file, so the build goes green while most of your suite never ran. A leftover debugger statement is the same species of mistake. A quick grep of the edited file catches both and tells the agent to strip them. It does not block the edit, it just refuses to let the mistake pass unnoticed.
Keep the working tree honest
A smaller one in the same spirit watches for issue-tracker IDs leaking into the code itself. Ticket numbers belong in commit messages and the tracker, not in a test name or a comment where they rot the moment the ticket closes. When one shows up in a file, the hook flags it so the code describes the behavior instead of a number that will mean nothing next quarter.
Context and a paper trail
The last two cost nothing and just help. One runs at the start of a session and injects the current state of my version control, the active change and branch, so the agent knows where it is standing without me spelling it out. The other appends every command the agent runs to a dated log. I almost never read that log, but the one time I need to answer what actually ran here, it is sitting right there, and it never once got in the way to record it.
- Format the changed file on edit, so the formatting check never fails on machine-written code.
- Warn on a focused test or a stray debugger before it reaches CI.
- Flag issue-tracker IDs that leak into source.
- Inject the current version-control state at session start, and log every command for later.
A good quality hook is invisible right up until the day it saves you a red build you would never have seen coming.
The common thread is that all of these are non-blocking and self-guarding. They tidy, they nudge, they record, and then they get out of the way. That is what makes them safe to leave switched on in every project: on their worst day they simply do nothing at all.