Does Your Claude Code Hook See Every Edit? An Edit|Write Matcher Saw 3 of 7 A Claude Code PostToolUse hook configured with the documented Edit|MultiEdit|Write matcher captured only 3 of the 7 file changes Claude Code 2.1.312 made in a test repo, while a Stop hook running git status --porcelain -uall caught all 7, according to a hookcheck.mjs test built around a fake Messages API served on 127.0.0.1. The four missed changes came from Bash commands (sed -i, a > redirect, rm, and git mv), which bypass the file-tool matcher. The test follows Anthropic's Addy Osmani describing on the October 28 AI Engineer channel video that hooks run on edits and study the diffs so PRs get corrected fast, a loop that depends on the hook actually seeing each edit. Anthropic’s Addy Osmani says hooks study the diffs so Claude’s PRs get corrected fast. Bash edits skip the usual matcher; a Stop hook running git status caught all 7. A Claude Code hook on the matcher Edit|MultiEdit|Write saw 3 of the 7 file changes Claude Code made in my test. A Stop hook that runs git status saw all 7. On October 28, the AI Engineer channel posted “How Anthropic Merges 30,000 Code Changes a Day” https://www.youtube.com/watch?v=AnsXWH2 EBU , a conversation between Manish Kapur of Sonar and Addy Osmani of Anthropic. The video description says Anthropic went from about 2,500 to 30,000 merged changes a day, with Claude doing first-pass review backed by verification evidence. Paraphrasing Osmani from the auto-generated captions: Claude reviews first and needs a way to try the change like a user would, and hooks run on edits and study the diffs so the PR gets corrected fast. That loop only works if the hook sees the edit. So I counted what a typical hook sees. Claude Code reads ANTHROPIC BASE URL. The script starts a tiny fake Messages API on 127.0.0.1 that replies with a fixed list of tool calls. The real Claude Code 2.1.312 binary runs those tools and fires real hooks. The fake model makes seven changes in a fresh git repo: three with Claude’s file tools Edit, Write a new file, Write over an old one, plus two Reads first and four with Bash sed -i, a redirect, rm, git mv . Two hooks watch. Hook A is PostToolUse with the matcher Edit|MultiEdit|Write, the docs' own Edit|Write example plus MultiEdit; it logs each payload. Hook B is a Stop hook that runs git status --porcelain -uall when Claude finishes. Save as hookcheck.mjs. Tested on Node 22, with git. // hookcheck.mjs - which file changes does a Claude Code hook see?// Needs: npm i @anthropic-ai/claude-code@2.1.312. No API key; offline after install.// Env: MATCHER PostToolUse matcher , BLOCK=1 Stop hook sends git status// back to the model once, with exit 2 .import http from 'node:http';import fs from 'node:fs';import os from 'node:os';import path from 'node:path';import { execFileSync as run, spawn } from 'node:child process';const CLAUDE = process.argv 2 && path.resolve process.argv 2 ;if CLAUDE || fs.existsSync CLAUDE { console.log 'usage: node hookcheck.mjs