Make Your AI's Rules Impossible to Break
This is the one I've been building toward. In the first essay I argued that adherence, not memory, is the real problem. In the second, I put the memory somewhere you own. Now I want to show you how to take a rule your AI keeps breaking and make it something your AI literally cannot break. Not "probably won't." Cannot. And the core of it takes about half a dozen lines.
But before the rule can bind, it has to arrive. So let me deal with delivery first, quickly, because it's the part everyone worries about and it's actually the easy part.
Delivery: getting the memory into every session
The fear is that using project memory means installing something heavy, or changing how you work, or trusting a plugin. It doesn't. On a lot of AI tools now, there's a cleaner path built right in: hooks.
A hook is a bit of configuration. You paste it into a settings file. Nothing gets installed. What it says, in effect, is: before the model sees my prompt, run this command, and put whatever it prints into the context. Every prompt. Every session. Automatically.
So you point that hook at your memory repo. Now, at the start of every session, your briefing and your relevant rules get pulled from your repo and dropped into the model's context before you've typed a word. The model can't forget to load them, because it was never asked to load them. They're just there, the way a fact is there.
That's delivery, and it's deterministic. Not "the model usually remembers to check." It happens, every time, because it's mechanical.
Now, not every tool supports hooks. For the ones that don't, there's the older approach: route the requests through a proxy that injects the same memory on the way through. Different plumbing, same result. Either way, the context arrives, guaranteed. Which tool supports which method is a moving target, so I keep a dated compatibility list rather than making promises that rot.
Delivery solved. Here's the thing though, and I said this in the first essay but it bears repeating. Because, it's the whole reason the rest of this matters: delivered is not the same as heeded. The model can have your rule sitting right there in its context and break it anyway. So let's make the rule clamp down, and sink its teeth in.
Not all memory is the same kind of thing
The insight that unlocked this for me is that your project's memory isn't one uniform thing. Different pieces of it can be enforced with different amounts of force. I think of it as a ladder with three rungs, and the goal is to push each rule as high up that ladder as it can go.
Bottom rung: prose. Some of your knowledge is a judgment call. "Prefer composition over inheritance." "Keep functions small." You can't reduce that to a command that returns pass or fail. So you do the soft version: you deliver it, you keep it in front of the model, and you check it loosely. This is where every current memory tool lives, and it's fine for what it is. It's just the weakest rung.
Middle rung: assertions. Some rules can't be checked by a script but can be checked by a second opinion. "The public API of this module stays stable." No single command proves that, but another model can look at a change and tell you whether it violated the rule. So you run that check on each pass. And here's a trick worth the price of the whole essay: use a different model as the checker than the one doing the work. Different models have different blind spots. The one writing the code will happily rationalize its own drift. A different one, from a different vendor, catches what the first talked itself into. When it catches something, you feed the violation back and the model tries again. It converges on compliance instead of hoping for it on the first try.
In my own implementation today the checker is a different, cheaper model from the same vendor. Cross-vendor routing is built into the selection logic but isn't live end to end yet. The advice stands; I'm just telling you where I am against it.
Top rung: gates. And this is the rung nobody's building for your own project's rules, which is strange, because it's the most powerful one. There's a whole enterprise category doing something adjacent: runtime guardrails that block a model's output when it leaks a customer's data or gets talked into something it shouldn't say. Useful, and not this. Those rules get written by a compliance team, judged by a second model, and aimed at what the model says. What I'm describing is a rule you wrote about your own codebase, checked by a command that either passes or fails, aimed at what the agent does. A large amount of what's in your project's memory is secretly executable. Look at a real rule: "Order data flows through the StateFlow repository, never direct socket reads." That is not a vibe. That is a grep. You can run a command that passes if the rule holds and fails if it doesn't.
So you compile the rule into that command, and you wire the command into the agent's loop. Now watch what changes.
What a gate actually does
Here's a rule, written out. In practice it's a few lines in a file in your memory repo: an ID, the rule in plain language, which rung of the ladder it sits on, the check command, where it applies, and what to do when it fails.
id: stateflow-only
rule: "Order data flows through the StateFlow repository; no direct socket reads in UI code."
tier: gate
check: "! grep -rn 'socket.read' app/src/ui/"
scope: ["app/src/ui/**"]
on_fail: block
That's it. That's the whole rule. You just turned a sentence in your project's memory into a law. (The tier: gate line is what tells outer.bot this is a top-rung rule, not a soft prose reminder — leave it out and the rule gets parsed right past, silently, which defeats the entire point.)
Now the agent goes to work, and at some point it starts to write a direct socket read, the exact thing the rule forbids. Before, that code would land, and I'd catch it in review if I was lucky. Now, the gate fires before the write completes. The action is blocked. The rule's own text gets handed back into the model's context: here's what you tried, here's the rule it breaks. And the model, now looking at the rule it just violated, rewrites the code the right way.
It cannot finish the task in a state that breaks the rule. Not because it became more obedient. Because the loop won't let it. This is the jig from the first essay, made concrete. The model is still the fallible hammer. The gate is the guide that makes the wrong swing impossible.
Two honest limits, because you should hear them from me rather than find them yourself. A gate blocks what it can see. Invoke a script with a trace flag the gate never inspects, and whatever that script does internally is outside its view. And a gate matching on command text can't tell the difference between running a forbidden thing and writing about one, so describing a blocked pattern in a commit message will trip it. Neither of these breaks the idea. What a gate covers, it covers deterministically, every time, which is more than any amount of reminding will ever give you. But "cannot" is a claim about the rules you wrote, not about every path through your machine.
The first time I watched an agent get blocked writing a violation on my own project, then quietly correct itself, I actually laughed. I'd spent years being the gate. Reading every diff, catching every drift by hand. And here was the thing doing it for me, deterministically, on a rule I'd written in four lines.
The receipt
Every time a gate fires, or an assertion catches something, or the model corrects itself, a line gets written to a ledger. What was attempted. Which rule. What happened. Blocked, corrected, or escalated to me when it couldn't resolve on its own.
That ledger changed how I talk about AI work. Because the question that really matters, the one a team lead or a client actually asks, isn't "is your AI smart?" It's "how do I know it did what it was supposed to?" And for the first time I have a real answer that isn't "trust me." I have the receipt. Every deviation accounted for. None of them passing silently.
That's the promise, and I want to be precise about how modest it is, because the modesty is the point. I am not promising the AI never makes mistakes. It does, constantly, same as any of us. What I'm promising is that no mistake against a rule you've written gets through unflagged. It's blocked, or it's corrected, or it's put in front of a human with the evidence attached. No unflagged drift. That's a promise I can actually keep, which is more than "flawless AI" has ever been able to say.
Where the ladder points
You don't compile everything. Plenty of your memory stays prose, because it's genuinely a judgment call, and that's correct. The skill is knowing which rung each rule belongs on, and pushing the ones that can climb as high as they'll go. The judgment calls stay soft. The checkable truths become gates. And the more of your project's hard-won knowledge you move from "the model should remember this" to "the model cannot violate this," the more you can actually trust the work without reading every line yourself.
That's the difference between an AI that remembers your rules and one that's bound by them. Remembering is table stakes now, half the industry ships it. Bound, with receipts, is the part worth building, and it's the part I'd stake real work on.
Next essay is for the people who've been asking the sharpest question of all, usually the ones who lead teams or answer to a security review: in this whole setup, who can actually see what? I'm going to lay out every option and exactly what each one exposes, because if you're going to trust this with real code, you deserve to know precisely where it goes.
I'm Kevin Rodenhofer, building AI infrastructure under my company OuterData Corporation after thirty years of making technology behave. If you want your AI bound by your rules instead of just reminded of them, get in touch. I'll show you every piece.