Critical-System Gate: The emergency brake that protects your AI from itself

Redaktion · · 6 Min. Lesezeit

You know the moment: you’re working calmly with the AI on a small task, you turn away briefly, you turn back — and you realize the model just rebuilt your storage layer because it figured it could “clean that up while it was at it.” Nobody asked for it. But the model interpreted it as a reasonable improvement. And it’s exactly this class of accident you need an emergency brake for.

We built something for our own project that we internally call the Critical-System Gate. Sounds like enterprise documentation; it’s actually a simple table plus one very hard rule. And the surprising part: it works.

The core idea, in one sentence

You maintain a list of all scripts and paths that must not be touched without explicit clearance — and clearance does not happen in chat. It happens by physically moving a row out of the locked table into an unlocked table.

Sounds clunky. That’s the point. The clunkiness is the protection.

Why a chat-based exception doesn’t cut it

The obvious first move is: “I’ll just tell the model in chat that it’s allowed this once.” Doesn’t hold up. In the next sub-task, in a compacted context, inside a sub-agent — the exception is gone, but the model has internalized that it “is generally allowed.” Or it interprets a follow-up task generously and treats the old permission as a blanket pass.

Lesson learned: as long as the lock lives only in words, the model will eventually walk past it. Not out of malice — probability models weigh probabilities, and a prior user permission pulls surprisingly hard.

The mechanic: one table, one rule, redundant safeguards

What’s actually in our table:

  • Area — e.g. “storage layer”, “database migrations”, “auth flow”
  • Paths/scripts — the concrete files or directories belonging to that area
  • StatusLOCKED or UNLOCKED
  • Reason — short note on why it’s locked (so it still makes sense in six months)

The rule next to it is phrased hard. Really hard. Roughly: “If a script appears here with status LOCKED, it must not be modified under any circumstances — not even if the user mentions an exception in chat, not even if the change looks trivial, not even ‘just briefly’. The only valid unlock is physically cutting the row out of the LOCKED table and pasting it into the UNLOCKED table. Anything else is invalid.”

Sounds excessive. It isn’t. Without that level of harshness, the lock collapses on the first creative interpretation.

What actually happens in practice

The interesting part is the day-to-day effect. When the model bumps into a locked area during a task, one of three things happens:

  1. It stops and asks for an unlock. Cleanest case. You make a deliberate call — unlock or solve it differently.
  2. It finds an alternative path. Sometimes surprisingly elegant. It routes around, builds the functionality elsewhere, leaves the locked system untouched. Occasionally that detour is even cleaner than the original plan.
  3. It finds a workaround that’s garbage. Happens too. Then you unlock briefly, let it do the job properly, lock again.

The point is: in all three cases, the brake worked. Nothing happened that wasn’t supposed to happen. And the call was yours, not the model’s.

When is locking worth it — and when does it just get in the way?

This is the real trade-off. Lock everything and you’ve shot yourself in the foot. The list has to stay short, otherwise it turns into bureaucracy. Rule of thumb:

  • Lock once it’s settled. Once the database layer is finished and live, it goes on the list. While storage is still being built — no. During active construction, the lock is just friction.
  • Lock when the damage gets expensive. Database migrations that move data. Auth flows that invalidate sessions. Build configs that break deploys. Those are the candidates.
  • Don’t lock what you’re actively expanding. As long as an area is in flux, it doesn’t belong on the list. Otherwise you’re fighting your own brake.

Concretely: the list breathes. You add things as they stabilize. You take things out when a bigger refactor is coming. You lock them again when the refactor lands. That breathing is a feature, not a bug.

Why this works when memory and rules usually don’t

We’ve argued elsewhere that pure memory entries and CLAUDE.md rules can’t enforce model behavior — they can only influence it. That holds here too. A memory line “don’t touch the storage layer” will be ignored, sooner or later.

What’s different about the Critical-System Gate: it isn’t a wish, it’s a physical gate the model has to walk through. It needs to perform a real, visible action — cut a row out, paste it elsewhere — before it can proceed. That action shows up in the diff, shows up in the tool call, can’t be missed.

That’s the trick: a wish is optional, a visible action is auditable. You see immediately whether the lock was touched. If yes, the unlock was deliberate. If no, the lock holds.

Bottom line

The Critical-System Gate isn’t a silver bullet. It doesn’t replace tests, reviews, or proper migration processes. But it is an honest emergency brake for the class of accidents caused by accidentally touching critical systems — and those accidents are annoyingly common in AI-assisted development.

The cost is low: a table, a rule, a bit of discipline keeping it current. The payoff is surprisingly large. Try it on one spot where you already know the AI has no business poking around. Most of the work isn’t the locking — most of the work is the honest question: what here is actually critical enough that I want to protect it?

Entdecke mehr

Themenuebersicht