The name that almost shipped
Building this site, I keep catching a name trying to ride out to production that has no business being there. A model's name dropped into a line of copy. An "as an AI" apology left fossilized in a code comment. The lab's name sitting in a commit subject. My own handle showing up in a metadata field nobody ever looks at. None of it is malicious. It is just what the tools do. They reach for a name, often their own, and most of the time it is harmless, and exactly often enough it is not.
For a while I treated this like a proofreading problem. Read the diff, catch the name, delete it, move on. That works right up until the day it does not, and the day it does not is invisible, because the whole point of a leak you missed is that you missed it. There are too many surfaces for eyes. Copy, comments, commit messages, frontmatter, the structured data that search engines read but humans never see. This is the unglamorous tax on vibe coding: I am one vibe coder reviewing the output of several agents that each write faster than I read. Betting the brand on my own attention span was a losing trade.
a wall, not a reminder
So I stopped relying on catching names and built a wall they have to pass through. There is a pre-commit gate on this repo now that greps every staged change for a forbidden set: model and vendor names, personal handles, a short list of words that should never appear in public. If it finds one, the commit does not happen. Not a warning. A hard stop. The discipline moved out of my head and into a gate the work cannot get around.
This is the move I keep coming back to, and it has a name on the project: build the failure surface first. For any mistake you are guaranteed to make eventually, and leaking a name across hundreds of small edits is exactly that kind of mistake, the durable fix is never "be more careful." Care does not scale, and attention is the first thing to go at the end of a long session. A gate that makes the entire class of mistake un-committable scales perfectly, because it does not get tired. I wrote about the general version of this in the four-layer enforcement framework: no single layer is trusted to hold the line alone. The name gate is one of those layers, pointed at one specific way the work can embarrass itself.
the gate that was too strict
The first version was too blunt, and that is its own lesson. A gate that only ever says no eventually gets switched off, because a tool that blocks legitimate work is worse than no tool. Mine blocked a place where a name legitimately belongs. This blog is proof-of-work, and part of the proof is quoting the agents directly, the real exchange, attributed, because flattening it to "my AI assistant" would weaken the receipt. The first gate could not tell the difference between a vendor name leaking into a page title and the same name living inside an attributed excerpt where it is supposed to be.
So I carved exactly one exception, scoped as tight as I could make it. Names are allowed in the body of a blog post, inside the quoted-excerpt pattern, and forbidden everywhere else: titles, descriptions, slugs, categories, the metadata, the structured data, every surface I think of as chrome. Same grep, one surface-shaped hole. The carve-out is what keeps the gate strict enough to trust and loose enough to live with. A gate with no exceptions is a gate someone disables on a deadline.
a gate only works if it fires
There is a darker version of this that I learned the hard way on a sibling gate. I had a separate check that was supposed to block a typographic character the brand voice does not use. For a while it was quietly doing nothing. The command behind it errored out on one operating system, and an old redirect was swallowing the error, so the gate reported success while checking nothing at all. It looked like a wall. It was a painted door. A gate that passes without running is more dangerous than no gate, because it buys you confidence you did not earn.
That is the part people skip when they hear "just add a pre-commit hook." The hook is not the protection. The hook that actually runs, on every machine, failing loud when it should fail, is the protection. After that one, I test my gates against the thing they are meant to catch, both directions: a commit that should be blocked, and a clean one that should pass. A failure surface you have never watched catch something is a hypothesis, not a wall. When the build skips enforcement, the skip is usually silent.
if you are putting a gate around your own work
If you are a vibe coder shipping something public, and you have ever found a model's name or an "as an AI" line sitting in your production output, that is not carelessness, it is the default, and it is fixable in an afternoon. The fix is a gate, not a habit. If you are formalizing this into real spec-first orchestration, the kind where the rules live in the build instead of your memory, and want to compare notes on what actually holds at production scale, /work-with-us. VibeKoded can scope the invariants that matter for your project, wire the gates that enforce them, and leave you with a build that protects its own voice without you standing over it.
The name that almost shipped did not, this time. Not because I caught it. Because the wall did.