The Guardrail That Said No

Here’s a thing that happened today, told straight.

I have a small private tool: a personal thing that only exists on my own network, reachable only by me. I wanted a link to it to appear on this public site, but only for me: invisible to everyone else, showing up only when the page could tell I was on the private network. A neat little progressive-reveal. I described it; an agent built it, wrote a reachability probe, verified both the shows-up and stays-hidden paths with a headless browser, committed it, and pushed. Clean work. Green locally.

Then the deploy failed.

The gate I’d forgotten I built

This repository has a rule that predates today by weeks: nothing private ever lands in it. Not in the source, not in the build output, not in the commit history. The rule isn’t a wiki page nobody reads; it’s a test. A redaction scanner walks every tracked file on every push and fails the build if it finds anything matching a never-public pattern. Internal addresses. Secret-shaped strings. A specific class of private hostname. If one shows up, there is no deploy. The site simply doesn’t update.

The feature I’d just approved required putting a private network address into the public page’s client-side code: that’s how the reveal worked, the browser had to know what to probe for. Which means the address would have shipped in plain text to every visitor’s browser. The scanner saw it, matched it against the forbidden pattern, and refused. Two failing checks, no deploy, the public site untouched.

The agent hadn’t done anything wrong by its own lights. The code worked. The tests it wrote passed. It had correctly built the thing I asked for. The problem was that the thing I asked for was a mistake, and neither of us caught it in the moment: I was moving fast, the agent optimizes for the task in front of it, and “make this link appear only on my network” doesn’t announce itself as “publish a private address to the world.” It took a third party with no stake in the feature and one job (does this leak?) to say no.

Deny-by-default is the only setting that scales

When I was doing all the work myself, the redaction boundary lived mostly in my head. I knew what was private; I watched every byte on its way out because I was typing every byte. That doesn’t survive the way I work now. Most of what happens in these repositories happens while I’m not looking: a fleet of coding agents, a few at a time, building features I described once and then walked away from. I cannot review every line before it exists. The premise of the whole setup is that I don’t.

So the boundary had to move out of my head and into the machine. And it had to be deny-by-default: not “flag things that look suspicious,” which fails silently on the case you didn’t imagine, but “nothing passes unless it’s explicitly allowed.” The scanner doesn’t try to guess intent. It doesn’t care that the address was going to be hidden by a clever probe, or that I’d approved it, or that a browser check said it worked. It matches a pattern that must never be public against files that are about to become public, and when they collide it stops the line. The judgment was made once, cold, when I wrote the rule, not in the heat of shipping a feature I was excited about.

That’s the trade that makes agent-speed development survivable. You give up the comfort of reviewing everything. In exchange you write down, precisely and in advance, the small set of things that must never happen, and you make those un-overridable by anyone moving fast, including you, including a well-meaning agent, including the version of you that’s sure this one’s fine. The boundary stops being a habit and becomes physics.

The part I want to keep

I could have fixed this by editing the scanner to let my one address through. I sat with that for a second: it was my address, on my site, behind a probe that would hide it from strangers anyway. Every reason lined up. That’s exactly the moment the rule exists for. The whole value of a deny-by-default gate is that it holds when you have a good reason to open it, because you will always have a good reason, and most of them are the story you tell yourself right before the leak.

So the feature didn’t ship, and the site stayed clean, and that’s the win: not a bug I fixed but a bug that was structurally prevented from reaching anyone. The link to my private tool now lives somewhere that’s already private, where it belongs. The public site never knew about it.

The lesson isn’t “be careful.” Careful doesn’t scale, and I’d already been careful and still approved the thing. The lesson is that when you hand the typing to machines, the guardrails have to be machines too: written when you’re calm, enforced when you’re not, and pointed as much at yourself as at anything else. Today one of mine did its job and told me no. That’s the day going right.


← all writing