Building a mechanism that makes an AI coding assistant "not do it" — from advice to enforcement, and the side-door left open in the gate itself
Introduction
I use an AI coding assistant daily. As the party I hand work to changes, how to make it actually keep “the things I want it to be careful about” becomes the problem.
Most people start with advice. You write in a config file (e.g. CLAUDE.md), “take a backup before any destructive operation.” That’s the right first step. But advice has a hole. There’s no gate that confirms it was followed. In a busy workflow, advice eventually gets skipped without anyone noticing.
In fact, I once broke my own memory database that way (The story of breaking a memory vector DB twice). I had decided “I’ll take a backup,” yet I went ahead with a destructive migration without ever creating the actual backup. The advice was there. The enforcement wasn’t.
This article is about raising that advice into enforcement — and the sequel where a side-door turned out to be open in the very gate I’d built.
The limits of the advice layer
A rule written in a config file is, in effect, a “request.” Whether it’s followed, once read, is left to in-the-moment judgment. There is no mechanism that stops the instant a destructive operation is about to happen and confirms “is there really a backup?”
Request for a destructive operation (delete, migrate, overwrite …)
│
├─[advice only]─▶ config says "back up first" ─▶ no check ─▶ skipped ─▶ incident
│
└─[enforcement layer]─▶ stops right before execution (what this article builds)
Building the enforcement layer
This assistant has a hook (PreToolUse) that can intercept right before a tool executes. So I put in a gate there: detect a pattern matching a destructive command, stop execution, and mechanically gather and present evidence of a backup.
Evidence means things like this: the Git state of the working directory (are there uncommitted changes, when was the last commit), whether an escrow/backup directory exists, and what its latest date is. The hook checks all of these automatically and attaches them to the confirmation dialog.
Request for a destructive operation
│
▼
The enforcement layer (hook) stops right before execution
│
├─▶ gathers evidence of a backup
│ ├─ Git state (uncommitted / last commit)
│ └─ existence and latest date of the escrow location
│
└─▶ confirms with the evidence attached (ask)
├─ present ─▶ proceed
└─ absent ─▶ stop
There’s one judgment call here. Whether to make the gate “flatly deny,” or “show the evidence and let a person confirm (ask).” I chose ask. Making the machine deny everything also stops legitimate operations, and the work stalls. The machine sticks to gathering evidence; the final judgment is made by a person looking at that evidence. With this, the advice “back up first” turned into a gate with evidence attached.
A side-door was open in the gate
Building the gate makes you want to relax. But whether the gate you built actually closes the hole is a separate question.
After assembling the enforcement layer, I read straight through the parts of the assistant’s official documentation dealing with the mechanics — hooks, agents, permissions, execution paths for commands. I stored the key points I read into my own knowledge base — the one I mentioned at the top, that vector DB I’d broken twice (my personal searchable memory) — in a form I could pull up later. I managed how far I’d read with a checklist, so nothing got left unread. Then, with that knowledge, I audited my own configuration. And out came the most critical hole.
The enforcement layer’s hook was only reacting to one specific tool (the shell — Bash). The same destructive operation, coming through a different route — a different shell (PowerShell), or a direct file edit — was treated by the hook as “out of scope” and let straight through. Right next to the gate I thought I had built, a side-door was open.
【Before】the enforcement layer only watches "one specific tool (Bash)"
dangerous command via Bash ─▶ hook detects it ─▶ stopped ○
other route (PowerShell / direct file edit) ─▶ hook lets it through ─▶ incident × ← side-door
【After】close every route
Bash / PowerShell / file edit ─┐
├─▶ hook detects it ─▶ stopped ○
(whichever route it comes through, it goes through the gate) ┘
As a countermeasure, I made the hook cover every route, and further added, to the file-edit side too, a machine-enforced gate: “stop if a protected file is about to be overwritten without a backup.” A gate only means something if it’s placed at every entrance leading to the thing you’re trying to protect.
A line that can’t be held by advice
Protect the line you must not cross with enforcement, not advice. “Being careful” only holds up under normal conditions. A line that must never be crossed in a busy workflow is protected not by caution, but by a gate that stops execution.
Test the gate itself from multiple angles. Once you build a gate, check not just “does it correctly stop things” but “can it be bypassed?” Confirming the happy path alone (dangerous operations get stopped) won’t reveal a side-door (some other route slips through). Whether something breaks is decided by whether it can be bypassed.
Read the whole mechanism before you try to govern it. A gate built on partial understanding will happily leave a hole like watching only one kind of tool among the ones it handles. Only once you grasp from the spec what could possibly become an execution path can you count all the entrances.
The one line of advice “back up first” is something anyone can copy. But actually building the gate that stops that line at every entrance of every execution path, and checking there’s no side-door — that work can’t be copied. You have to build it yourself, as a mechanism, and own it.
Related articles
- The actual case where advice alone failed to protect anything and I broke my memory database twice is in The story of breaking a memory vector DB twice.
- The broader effort of raising an AI assistant as a companion is collected in AI Assistant Operations Notes (Series Table of Contents).
- This is the same hook mechanism, but where this article is about the enforcement that stops dangerous operations, the recall mechanism that makes the AI remember “what matters right now” every turn is written up in Injecting into the AI, every turn, “what to recall right now” — the activation layer of a personal RAG.