Some working agreements are judgment calls forever. Others are mechanically checkable: quoting bugs, type leaks at serialization boundaries, metered clients in test files. Those graduate: from a line of prose the agent might honor, to a hook that flags the problem at edit time, every time, for free.
You’ve met this before. Linters, pre-commit hooks, CI checks. Shift-left, poka-yoke. The agent twist is only the audience: the hook’s report lands mid-session where the agent reads it and fixes the finding before you ever see it.
Where this comes from: a shell word-splitting incident (the classic unquoted
$varin a rename loop, AF-12) became an edit-time hook runningruffon python andshellcheckon shell for every file the agent touches. The detail that matters: shellcheck’s default severity misses SC2086 (the exact class that motivated the hook), so it must run at--severity=infoor it silently fails its own founding incident. That’s the difference between installing a linter and encoding your incident.
The graduation rule
Advisory, never gate. The hook reports findings; the agent fixes what its own edit introduced and leaves pre-existing findings unless asked. A hard-failing gate on taste- or judgment-adjacent checks recreates the failure the workflow list warns about: the problem being named is skipping judgment, and a gate that replaces judgment repeats it. (The entries marked ⚙ on the workflow list are the natural graduates: checkable by a script, still deserving a human-visible report.)
Try it
Do it by hand
- Pick your most mechanical agreement: quoting (AF-12), numeric type leaks (AF-13), billed clients in tests (AF-06).
- Wire it to your harness’s hook mechanism (Claude Code: a
PostToolUsehook on Edit/Write in settings) so it runs on every edited file, scoped to the file just touched. - Set the policy in writing: fix findings your edit introduced; leave pre-existing ones unless asked. Without that line, the first legacy file the agent touches becomes an unrequested refactor.
Or paste this into Claude
Install an edit-time advisory lint. Whenever you edit a *.py or *.sh
file, run ruff on python files and shellcheck at --severity=info on
shell files (default severity misses SC2086-class quoting bugs, which
are exactly what I care about), scoped to the file just edited.
Findings are advisory: fix the ones the current edit introduced; leave
pre-existing ones unless I ask. Wire it into this harness's hook
mechanism (in Claude Code, a PostToolUse hook in settings); if there's
no hook mechanism, write the script anyway and tell me exactly where
to call it. Show me every file before writing it.
Watch out
- Default severities: the founding incident of your hook may be below the tool’s default threshold. Verify the hook flags the exact incident that motivated it (step 2: baseline before trusting the probe).
- Hard gates on advisory checks: blocked edits teach the agent to route around the check, not to honor it.