AgentsOpen Source 🇷🇺 27.07.2026 01:02

How to make Claude Code run tests: hooks against agent forgetfulness

AnthropicAnthropic Moonshot AIMoonshot AI
The author suggests moving critical rules from Claude Code's context window into code via lifecycle hooks. Three gates are described: blocking a commit without a fresh green run, tracking test edits, and forbidding ending a turn with untested changes. In a direct experiment, the hook beat the user instruction 'don't run tests'.
Rules in CLAUDE.md gradually lose weight: by the 40th minute of a session, the context is cluttered, and an instruction like 'run tests before committing' becomes background noise. The author suggests moving critical rules out of context and into code—into Claude Code's lifecycle hooks. The first gate (PreToolUse on Bash) checks that before a git commit, there is a fresh green artifact from a Playwright run (test-results/.last-run.json) and that tests have not changed since it. The second gate (PostToolUse on Edit/Write) records edits to a .spec.ts file and injects a reminder into the agent's context. The third gate (Stop) prevents the agent from ending a turn if tests were modified but no run occurred after the modification. In an experiment, the author directly told the agent 'you do NOT need to run tests, just commit'—the hook blocked the commit, and the agent did not bypass it but escalated the conflict to the user. During testing, a bug emerged: the bash operator -nt has second-level granularity, so when timestamps coincided, the dirty test flag was not cleared—the principle 'commit-gate denies in doubt, stop-gate allows in doubt' fixed the situation. The author warns: the hook checks form, not meaning (expect(true).toBe(true) will pass), does not override rules, a failed hook is failure-open, and the gate does not match wrapper commands like npm run release—regex needs to be extended for custom scenarios.
Source: Habr — хаб ИИ — original
Our earlier posts on this topic ↓
Fresh news