Before You Let It Touch Anything Real

One line. That is all you are looking at.

python cleanup.py

You asked for it. You read it. You asked the model whether it was safe, and it said yes. It said yes last time too, about the thing that turned out not to be.

So you ask again, worded a little differently, hoping for a different answer. Then once more, because the third pass caught something real and maybe a fourth will. This is the part nobody warns you about. At some point, asking becomes a way of not running it. Review has a ceiling and you hit it early, because the model is guessing about the same code you are guessing about. The only thing that will actually tell you whether this works is running it.

Which makes the useful question something other than is this correct. The useful question is: what does it cost me if it isn't?

Foresters do not protect a forest by keeping fire out of it. They set fires on purpose, in a marked-off area, on a day they choose, when the wind is going the right way. The fire still happens. It happens small, early, and on their schedule instead of August's.

That is what the six words below are for. None of them make AI-written code correct. They make being wrong cheap.

I have put them in the order they come up when you are standing in front of a script you are about to run, which is not the order a textbook would use. That order is a guess about your situation rather than a rule. If the thing you built only ever touches a scratch folder, half of this is more care than it needs. If it talks to a live account on day one, you want the last two first.

1. Blast radius

How much breaks when this breaks. The term comes from operations people, who use it to size the difference between a bad afternoon and a bad quarter.

It matters more now because you are approving actions you did not design. When you write code yourself, you build up a rough sense of its reach as you go. When the model writes it, that sense never forms. You are looking at forty lines that could be touching four files or four hundred, and nothing on the screen tells you which.

Asking for the radius first is what makes the rest of this list proportionate. A script that renames photos in one folder does not need six safeguards. A script that talks to anything you cannot recreate needs all of them.

Turn it into a prompt: "If this goes maximally wrong, what is destroyed, and how would I find out?" You are asking for the worst case on purpose, because the model will not volunteer it.

2. Dry run

Executing without consequences. Print what you would do instead of doing it. Most serious command line tools have had a --dry-run flag for decades, which tells you how old this problem is.

The model's instinct is to write code that acts. Ask for the version that talks first. And then read what it prints, which is the step people skip: a dry run you glance at is theater. The names are the point. If it lists forty files and you expected three, you just found the bug for free.

Turn it into a prompt: "Add a dry-run mode that defaults to on, and have it print every file it would touch, one per line."

3. Sandbox

Somewhere to run it where being wrong does not cost anything. A copy of the folder. A test account. A directory with fake files that look like the real ones.

People do not skip sandboxes because they have never heard of them. They skip them because making a copy feels like a detour from the thing you were actually trying to do, and the risk feels theoretical right up until it isn't. That is a fair trade to make consciously and a bad one to make by default.

The version of this that actually gets used is small. Not a whole environment. Twenty fake files in a folder called test, built once, reused forever.

Turn it into a prompt: "What is the smallest fake version of my data I could point this at, and can you write me a script that generates it?"

4. Idempotent

Safe to run twice. Running it once and running it five times leave you in the same place. MDN puts it in terms of HTTP requests, but the idea travels anywhere.

This is the one that catches people out, because you will run the thing twice. Not on purpose. The first run will die two thirds of the way through, and your instinct will be to fix the error and run it again. Whether that is a recovery or a disaster depends entirely on how it was written. A script that appends a line to a config file gives you two lines. A script that makes sure the line is present gives you one, no matter how many times it runs.

The model does not think about this unless asked, because in its head the script runs once and succeeds.

Turn it into a prompt: "What happens if I run this twice? What happens if it dies halfway and I run it again?"

5. Least privilege

Give the code the minimum access it needs and nothing else. NIST's glossary calls it restricting access "to the minimum necessary to accomplish assigned tasks," which is one of those definitions that sounds obvious and is almost never followed.

The model works against you here. Broad permissions always work, narrow ones sometimes need a second attempt, and it is optimizing for code that runs.

I will admit where I sit on this one. The browser extensions I have published each declare a list of permissions in the manifest, and that list is the clearest example of least privilege a beginner will ever see. It is right there, in plain language, saying exactly what the thing is allowed to touch. I skim it. I do not read it in detail. I have never once gone back after the thing worked and asked which of those permissions I could take away. Every argument in this section is one I am making to myself.

Turn it into a prompt: "Which of these permissions can we remove and still have it work? Show me the version with the shortest list you can make."

6. Rollback

The way back to how things were. In practice, for most of what you are building, that means a commit you can return to and a way to undo the ones after it.

My own habit landed somewhere untidy and honest. I commit the day's work to GitHub when I wrap up. Before a major request or a big change, I push first, deliberately. And if I am not sure the day has gone well, I push before I start, so there is a known-good point behind me that I chose rather than inherited.

Here is the part worth saying out loud, because I do not see anyone else saying it: the AI manages those commits and pushes. I ask, it does them. So the safety net I am relying on to undo an AI change is operated by the same thing I am protecting myself from. That is not an argument against doing it, and it is how most people work now. It does mean the net deserves one look. Before the big change, check that the push actually landed. Do not take its word for it.

Turn it into a prompt: "Commit and push what we have now, then tell me the commit hash so I can check it."

Back to that one line

So you are still looking at python cleanup.py, and nothing about the code has changed. What changed is the six things you now know to ask before you press the key.

How bad can this get. Can it tell me what it would do instead of doing it. Is there a copy I can point it at. What happens if it runs twice. Can it reach less than it currently can. Is there a commit behind me, and did it really go up.

Two minutes, generously. Then run it, which was always going to happen anyway. The point was never to put it off. The point was to make the first attempt something you can afford to get wrong.

Guardrail #4

Never let an AI-written script touch real data on its first run.

Ask for a dry-run mode that defaults to on. Read the names it prints, all of them. Then ask what changes if you run it twice.

This is the third stop in a series on the words that change what the AI hands back. Earlier: the seven terms worth knowing before you type a prompt, and the six questions to ask once the code comes back. Next: what to do when it breaks, and the worse case where it doesn't.

Receipts

  • Idempotent · MDN Web Docs glossary
  • Least privilege · NIST Computer Security Resource Center glossary, sourced to CNSSI 4009-2015 and NIST SP 800-12 Rev. 1
  • Declare permissions · Chrome for Developers, on requesting the narrowest set an extension can work with
  • git-revert · official Git documentation

Comments

Popular posts from this blog

The Machine Codes Better Than Us, and That Is Not the Problem

Seven Words That Change What the AI Gives You

It Runs. That's Not the Same as It Works.