Ledger/Building with AI

Why my Claude Code rules never stuck

A rule in a file asks the agent to behave. Put rules where every project reads them, phrase them as behavior someone can observe, and add a check at a moment the agent always passes through.

7 min read

A coding agent can be told the same thing many times and still repeat the mistake. When mine did, the rules existed. They were in the wrong places, and nothing checked them.

Here is one case. An agent told me a set of app screens was perfect, twice, while two labels ran past the edge of their pill. It then wrote itself a good rule about zooming in before calling a visual fix done. Later, on the same app, it moved on from a paywall edit that nobody had built or looked at. The screen was broken.

The rule was in that project’s memory the whole time. Claude Code loads the top of a project’s memory index into every session and opens the full rule files on demand, so the agent had it within reach. Nothing made it look. What was missing was a moment when something compares the claim with what was actually done.

01Count your corrections before you write rules

The corrections you type to an agent are a record of what you enforce by hand. Counted, they rank problems by how often they come back, which is a better starting point than a list of rules written from memory.

Take a month of them, from wherever you keep them. Mark every message where you corrected the agent, give it a class, and count.

There are two traps. Resumed sessions repeat old messages, so remove the copies first, or one bad week counts twice. And keyword searches overcount, since a plain no is not always a correction. Use the counts to find candidates, then read them in full.

In my own messages the same few corrections came back for weeks, and each one was already written down somewhere. They were judgment calls, not code: what counts as done, what counts as proof, who decides. Yours may sort differently. The counting is the part that travels.

02Rules in a project folder never reach the other projects

Every session starts blank, from the files it loads. Rules tend to get written where the mistake happened, in the folder of whatever project is open, so the next project starts without them.

In my own setup, the rules were scattered across the folders of my projects, and the one file Claude Code loads in every project, the user-level CLAUDE.md, was empty.

The fix is one short global file for whatever applies everywhere, with a size budget written at the top. Every line in it is carried into every session, so each extra paragraph makes every session heavier. The Claude Code docs suggest keeping each CLAUDE.md under 200 lines.

Project files keep project rules. A correction you have made in two different projects moves up to the global file, and so does any rule that would still hold in a project you haven’t started yet.

03Write each rule as something you can observe

A rule phrased as a quality leaves the grading to the agent. “Be careful” and “check twice” leave nothing in the transcript you could point to. Phrased as a behavior, the same rule can be checked from the outside, by you, a script or a second model.

One rule came from a single failure. An agent once read a short “ok” as permission to deploy to production, right after offering the deploy. The rule that came out of it says that consent names the object: deploy, backend, production. Anyone reading the transcript can tell whether it held.

Four questions for every rule in your agent’s files
1. Could someone who wasn't in the session tell, from the transcript alone, whether this rule was followed? If not, rewrite it as a behavior.
2. Would it still hold in a project I haven't started yet? If yes, it goes in the global file. If it names a file, a screen or a client, it stays in the project.
3. Which moment will check it: the end of a turn, before a push, before a tool call? Without one, it stays a reminder.
4. Has this correction come back since I wrote the rule? Then stop reminding. Turn it into a check.

04Check the claim against the transcript, and let admission through

The Claude Code docs call these files “context, not enforced configuration”. For an action that has to be blocked whatever Claude decides, they point to a PreToolUse hook. A hook is a small script Claude Code runs at a fixed moment, such as before a tool call or when the agent tries to end its turn.

The hook worth writing first leaves quality aside, because quality needs taste. It compares a claim with the transcript. If the final message says “verified” and the turn ran no tool at all, no check happened in that turn. A script can see that. Have it block once, ask the agent to name the observation or say what was not checked, and then let the turn close.

That is all it catches. If the turn ran any tool, even one that has nothing to do with the claim, the check stays silent. So it stops a claim with nothing behind it, and a claim with the wrong thing behind it passes.

Word matching is blunt, so build the exit in. “Not verified” contains “verified”, so a plain match blocks the very admission the check exists to ask for. A claim word right after a negation should count as an admission and go through. An agent that has not checked something then says so in the open, which is better for you than a false claim: in my own messages, a false claim drew a harder correction than an admitted gap.

Log every block, so you can count false alarms. And make the script exit silently if it breaks, since a check that stops your work when it fails is a check you will turn off.

05A check has to fire at a moment the agent always passes through

A check that runs when you type fires on your schedule, not the agent’s. I had a hook that watched context size, and it fired only on my next message, so a long build session ran well past the size I wanted before anything spoke up. For a claim, the end of a turn is the better moment, because every answer passes through it. For something that grows during a long run, like context size, the moment is a tool call, which a long run passes through again and again. Before a push is the third, for anything that leaves your machine.

Taste failures are harder, because design has no keyword. An agent once published two dashboard mockups it had never rendered, because its screenshot tool couldn’t capture the page in that session. A script can ask whether an image entered the turn at all, though not whether it was the right one.

The finer failures need a reader: a number with no source, a list of options where you asked for one recommendation. A second model can reread the final message at the end of the turn and block once on the hard failures, with the same log you keep for the script.

06Count whether it worked

Write the failure test before the check, as a number you can miss: for example, if the corrections you counted haven’t fallen by half after two monthly counts, the rules aren’t working. I don’t have that result for mine yet.

Count the same way in both periods: corrections per message, with duplicate messages removed, in two windows that don’t overlap, the month before the file and the month after. Comparing a raw count with a cleaned one would have shown a drop of more than half that came only from the cleanup.

The rule

If you have corrected your agent the same way twice, don’t write a third reminder. Turn it into a check at a moment the agent always passes through, then count whether the correction drops.

Keep reading

All entries

Aftershock

Oct 17, 2026This time, the update is what I removedThe best thing in this update is what is no longer in it.From a product that covers every case to one that gets usedFounder notes5 min
Lorenzo Alejandro Montes

Lorenzo Alejandro Montes

I make consumer apps and take them from the first interview to the store listing. Crew and Farro are live on iOS and Android.

Lorenzo Alejandro Montes Milan, Italy RSS feed
04 / Building with AI SCRL 0.00 Milan --:--