AI in production · 6 min read

A Written Rule Isn't Enough

Here are the rules my AI can't break, and how I lock them.

My harness rests on rules written in plain text. The AI reads them every session and follows them almost always. Almost. For most rules, an occasional miss is fine: I fix it and add a line. For a few, one miss is one too many. Those I back with code that blocks the action.

Why a written rule isn't enough

A written rule is one instruction among thousands of words. Over a long session, the context fills up and gets summarised, and an instruction can slip into the background. An email or a web page the AI reads can contain instructions that pull it off course. And a model can be wrong with great confidence.

I learned this from a real mistake. My rule already said to show me emails before sending them. One day I rejected a command that sent follow-ups, and later found it had already run: 56 emails were out. The rule was written down. It stopped nothing.

Two-layer diagram. The AI wants to act; its action first goes through written rules, which guide almost always (style and format, order of steps, choice of model, drafts first), then through locks in code, which block every time (a hook for an email to an excluded company, permissions to publish or deploy, no access to secrets, a check that makes the verdict more cautious). The action is carried out, or blocked and I am told. At the bottom, the question to sort a rule: if the AI breaks it once, is that serious and irreversible? No, it stays in text; yes, text plus a lock in code.
Text guides almost always. Code holds the line when it matters.

My red lines, and how they're locked

Never contact an excluded company

The rule is written in the rules files of both my tools, Claude Code and Codex. It's backed by a hook: a small script that runs before any action that sends or drafts an email. If the text names a company on my exclusion list, or an address linked to it, the action is blocked. The same script runs in both tools.

The script has limits, and its own comments say so: it compares text, so it can't know that a person works for that company. The written rule is still needed: it tells the AI to check known links before writing. The code catches the obvious, and the rule covers judgement. When a link is confirmed, it becomes one more line in the list.

Never publish without my approval

In some projects, a publish or deploy command is simply refused by the tool's permissions. The AI can prepare, test and check everything. Going live goes through me.

Secrets don't go through the conversation

My API keys live in my Mac's keychain. Scripts read them directly, and they never appear in a file or in the exchange with the AI. It can't print what it has never seen.

A verdict can only get more cautious

In MesAmendes, my app that checks traffic fines, the model proposes a verdict. Code then checks it against public data, and that code can only make the verdict more cautious, never more favourable. Even when the model is wrong, it can't promise someone their fine will be cancelled.

How to sort your rules

For each rule, ask one question: if the AI breaks it once, is that serious and irreversible?

  • No: the rule stays in text. Style, format, the order of steps, the choice of model. A miss can be fixed.
  • Yes: the rule gets locked by code. A message sent, a payment, a deletion, a release, a secret printed.

In my setup, the second list fits on one hand. That's on purpose: every lock adds friction, so only lock what deserves it.

Four ways to lock a rule

  1. The tool's permissions: forbid certain commands, like publishing or deleting. It's the simplest option, a few lines of settings.
  2. Hooks: a script that runs before an action and blocks it if it breaks the rule.
  3. Don't give access: if the AI doesn't have the key, it can't use it. A draft that waits for your click instead of a direct send.
  4. Checks in the code: tests that must pass, a check that can only add caution.

One catch: each tool has its own settings. Claude Code's permissions don't apply to Codex, and the other way round. A red line has to be locked in every tool that could cross it.

Text and code work together

I keep the written rule even when code locks it. It explains why the limit exists, and it covers the cases the code can't see. It also says what to do when a lock fires: tell me, and don't rephrase the request to get around it. Text guides the AI in almost every case, and code holds the line in the ones that matter.

A question on this topic?Describe your situation in two lines. I’ll reply.