Why AI Breaks Working Code, and How to Fence It In
AI breaks working code because it cannot tell a deliberate oddity from a mistake, and because it often changes more than you asked for. You stop most of this by writing down what is on purpose and naming what it may touch.
How does a harmless request break something?
Say you are making Clockwork Orchard, an invented game where crows steal apples. Before a crow flies off with an apple, it waits 0.4 seconds. You added that wait after a long evening of playing, so the player can see the crow coming.
A month later you ask, "Make the crows a bit faster." Your AI looks at the crow code and finds a pause with no explanation. To the AI, that looks like the slow part. It removes the pause, and the crows are faster.
They also now snatch apples with no warning, and the game feels unfair. Nothing crashed, and no red message appeared. The AI did what you said, using what it could see.
Three things combine here:
- It cannot see why. Your reason lived in your head. The Claude Code docs name this as a main cause of bad sessions: the AI is "missing information it can't get from reading the repo", which means your project files.
- It tidies by default. Something that looks odd gets improved, and hand-tuned details always look odd.
- It reaches wider than you asked. A small request can turn into a rewrite of a whole file, and everything in that file is now at risk.
The wider problem of one feature breaking another is covered in my game keeps breaking. This page is about the quiet version, where working details vanish.
What is a fence?
A fence has two parts.
A list of what is on purpose. Keep a file called on-purpose.md, with one line per oddity and its reason:
Crow waits 0.4 seconds before flying off, so the player sees it coming.
Apple 7 sits off the grid, so the first ladder feels like a stretch.
A limit in each request. Compare these two:
- Without a fence: "Make the crows a bit faster."
- With a fence: "Make crows fly 20% faster. Change only their flight speed. Keep the 0.4-second warning."
What belongs on the list?
You do not need to list everything. Three kinds of thing earn a line:
- Anything you tuned by hand until it felt right.
- Anything that took more than two tries to get right.
- Anything a stranger would call a mistake, and you would not.
Paste this to your AI
You keep changing things I did not ask you to change, so let's build a fence.
1. Go through my game and list everything that looks odd, unnecessary or oddly specific, such as a wait, a strange number or a special case. Quote each one and say where it is.
2. Ask me about each one: on purpose or not? Do not guess. Write my answers, with the reason, into on-purpose.md.
From now on, before any change:
- Read on-purpose.md.
- Draw how this part of the game is meant to behave as a small Mermaid diagram, with the on-purpose items marked on it. Run your planned change through the drawing and tell me which steps it touches.
- Tell me what you plan to touch and what you will leave alone.
- If the change needs anything beyond that, stop and ask me.
After any change, show me what really changed, old and new side by side in plain words. Name any on-purpose items nearby and tell me what you looked at or tried that shows they still hold. If you do not know, say so.
Or skip this and connect the MCP: your AI then finds all of this by itself.Connect the MCP
How to check it worked
- Read the list. Does it contain something you remember tuning? If not, your AI skimmed, so name a detail and ask where it is.
- Ask for a change next to a fenced detail. In the example, ask for faster crows. The warning should show up in the drawing as a step of its own, and it should stay in the game.
- Compare what changed with what you asked for. Anything extra deserves a question.
- Try to talk it out of the list. Ask it to remove a fenced detail without giving a reason. It should quote the reason from the list and ask if you are sure.