Stop asking your AI agent to follow rules. Enforce them.
You've written it a hundred times. In your CLAUDE.md , in your system prompt, in ALL CAPS: NEVER put "use client" at the page level. NEVER commit @ts-ignore without a reason. And your agent does it anyway. Not always — that would almost be easier to deal with. It follows the rule for the first 50k tokens, then quietly stops. Or Sonnet follows it and Haiku doesn't. Or it follows nine rules and forgets the tenth. Here's the thing I finally accepted: a rule in a prompt is a request. The model can decline it. So I stopped asking, and started enforcing. TL;DR Prompt adherence is probabilistic. It degrades with context length and with model size. But half of my coding rules never needed a model at all — they're grep-able. Claude Code hooks + exit 2 turn those rules into a deterministic reviewer that runs after every single edit , costs zero tokens when nothing is wrong , and fires at 100% regardless of which model wrote the code. Once the mechanical rules are enforced from below, you can safely downgrade the model doing the typing. That's the real payoff. Everything below ships in ccteams v0.3.0 , but the pattern takes 30 minutes to build yourself. Two kinds of rules Some background in three lines: I run Claude Code with orchestrated agent teams — a builder writes code, a reviewer verifies it, and both get a stack-specific "playbook" of rules distilled from the mistakes mid-tier models actually make. It works well. I wrote about the prompt-engineering side of it before. But rereading my playbooks, I noticed the rules split cleanly into two categories. Rules that need judgment: Trace the Server/Client boundary by hand. Don't write a fix until you can state the root cause. These need a model. Prompts are the right place for them. Rules that are just string matching: "use client" at the top of app/**/page.tsx → wrong. process.env.SECRET in a client file → wrong. @ts-ignore with no justification → wrong. Why was I asking a language model to remember these? A regex doesn't get