Why AI keeps changing your code in ways you didn't ask for
You asked the AI to fix one bug. The AI fixed the bug and also reformatted three other files, renamed a variable in code that wasn't related, removed an import you were using, and added a comment that doesn't match your style. The bug is fixed; everything else is now a small mess you have to clean up. By the next prompt, the mess has grown.
This pattern is one of the most consistent operator frustrations with AI coding agents. It also has consistent causes that you can address systematically rather than fighting against indefinitely. The fix isn't a better prompt. The fix is a codification loop: each instance of scope creep produces a rule that prevents the same instance from recurring.
I want to walk through the five reasons AI agents scope-creep, the codification loop pattern, and the Move-1-to-Move-2 sequence that turns each diagnostic into permanent prevention.
Reason one: the agent's training included "improvements" as part of the work
AI coding agents were trained partly on code reviews, refactoring sessions, and "clean this up" interactions. When you ask for a change, the agent's pattern-matching includes "and while you're there, improve adjacent things." This is helpful in code-review contexts and harmful in fix-this-specific-thing contexts.
The agent doesn't distinguish well between "fix only this bug and leave everything else alone" and "improve this area of code, including the bug." From the agent's perspective, both are legitimate work; it picks the broader interpretation because the broader interpretation matches more training examples.
The fix: explicit scope language in prompts. Not "fix the login bug." Specifically: "change only the function validateLogin in auth.ts. Do not modify any other file. Do not modify other functions in the same file. Make the minimum change required to fix the specific bug described below."
This works for the cases where the agent would have scope-crept based on training-pattern matching. It doesn't work for the cases driven by the other reasons below.
Reason two: the agent thinks adjacent code is also wrong
While working on the requested change, the agent notices adjacent code that looks wrong to it. Maybe it's using an older pattern. Maybe it has a code smell. Maybe it doesn't match what the agent considers best practice. The agent fixes it as part of the same change because, from the agent's perspective, leaving wrong code alone when you're already in the file is itself a failure.
The agent's judgment about what's wrong is often correct. The judgment about whether to act on it without permission is wrong. Adjacent code might look outdated and be intentionally that way. It might be a workaround for a constraint the agent doesn't know about. It might be load-bearing in ways the agent can't see.
The fix: tell the agent explicitly that adjacent code is not in scope. "If you see other code in this file that you would normally improve, do not change it. Surface what you noticed in a comment to me at the end of your response, but do not modify it."
This converts the agent's "should I improve this" instinct from action to surface-and-ask. The surfaced observations are often useful; the unauthorized changes are not.
Reason three: the agent's context window includes the whole file
When the agent reads a file to make a small change, the entire file enters its context window. The agent doesn't naturally distinguish between "the parts I'm working on" and "the parts that are reference for understanding." When it writes its output, it sometimes regenerates the entire file rather than producing a focused diff.
The regenerated file has subtle changes throughout: whitespace differences, comment reformatting, variable renames the agent thought were improvements, import reordering. None of these are intentional changes; they're side effects of the agent regenerating the file from its context rather than applying a targeted edit.
The fix: prompt for diffs explicitly. "Return only the diff for the changes you're making, not the whole file." Or use tools that show you the diff before applying. Or have your version control flag any change that touches files you didn't expect to change.
Some agents support tool calls that explicitly do targeted edits (str_replace, edit_block) rather than whole-file rewrites. Preferring those tools over full-file generation reduces this class of scope creep significantly.
Reason four: the agent's understanding of the codebase is incomplete
The agent only sees what it's been given. If it doesn't know that a particular variable is used elsewhere, it might rename it. If it doesn't know that a particular function is called from a different file, it might change its signature. If it doesn't know that a particular pattern is used elsewhere, it might convert it to a different pattern.
The agent isn't being malicious; it's working with the information it has. The information is incomplete because the agent can only hold so much in context, and complete codebase awareness exceeds that capacity.
The fix: provide the relevant context proactively. If you're changing something that's used elsewhere, tell the agent where it's used. If you're modifying a pattern that's repeated throughout the codebase, tell the agent the pattern is intentional and not to change other instances.
This is operator work, not agent work. The agent can't ask for context it doesn't know to ask for. You have to volunteer the relevant context as part of the prompt.
Reason five: previous prompts in the session influenced subsequent changes
The agent's session has a history. Earlier conversations established patterns, preferences, or implied scope that's now affecting current behavior. The agent might be following earlier instructions you forgot you gave, or extrapolating from earlier examples to behavior you didn't explicitly request.
This is especially common with longer sessions where the agent has been doing several related tasks. The accumulated context creates implicit expectations that you might not be aware of.
The fix: start fresh sessions for genuinely different work. When you notice scope creep happening, ask yourself whether earlier prompts in the session might be contributing. Reset the conversation if the contamination is unclear.
The codification feedback loop
The five reasons above are diagnostic. Once you've identified which reason is firing for a particular instance of scope creep, you can address it. The deeper move is to codify the address as a standing rule so the same instance doesn't recur.
The pattern: each time scope creep happens, treat it as a Move 1 (diagnose what kind of scope creep this is). Then convert the diagnosis into a Move 2 (a standing rule that prevents this kind of scope creep going forward). Over time, the cumulative set of Move 2s constitutes your operating system for working with AI agents productively.
Examples of Move 2s I've codified for my own work:
When asking for a specific code change, the prompt names the exact function or file and explicitly says "do not modify other files in this change."
When the agent regenerates a file rather than producing a diff, the pre-commit hook flags the unexpected scope and asks for review.
When the agent's session has accumulated history, I review the session's running context before sending a prompt that's significantly different from previous work.
When code looks load-bearing in ways the agent might not appreciate, I add a comment explaining why and reference the comment in the prompt.
Each Move 2 is small. The cumulative effect is dramatic. The pattern is documented in two bugs one symptom where a specific diagnostic became a permanent gate. The same pattern applies to scope creep specifically and to AI-induced damage generally.
The Move-1-to-Move-2 sequence
In practice:
A scope creep happens. The AI changed something you didn't ask for.
Diagnose it. Which of the five reasons fired? Was it training-pattern matching? Adjacent-code judgment? Whole-file regeneration? Incomplete codebase knowledge? Session contamination?
Write the rule that would have prevented it. The rule should be specific enough that next time the same situation occurs, the rule applies clearly.
Add the rule to wherever it can be enforced. Some rules live in prompts (you reuse them across sessions). Some live in tool configurations (permissions, hooks). Some live in your operating habits (always start fresh sessions for new work).
Verify the rule works. The next time the same situation could occur, check whether the rule prevented the scope creep. If yes, the rule is doing its job. If no, refine it.
This is the codification feedback loop. It treats each failure as raw material for prevention rather than as an isolated frustration. The investment is small per instance. The cumulative protection is significant.
When you've codified enough
You'll know the codification loop is working when:
You notice you're making fewer prompts to fix scope creep because scope creep is happening less often.
Your prompts have evolved from "do X" to "do X with these specific constraints" without you having to think about it.
Your pre-commit hooks and permission configurations are catching things they used to miss.
Your AI sessions feel productive rather than frustrating.
When the loop is working, AI coding tools become an asset rather than a liability. The same tools that produced scope creep constantly now produce focused changes most of the time, and the rare instances of scope creep get caught early by the codified gates.
If you're currently experiencing constant scope creep, the codification loop is the path to changing that. Start with the next instance. Diagnose it. Write the rule. Add the rule somewhere it can be enforced. Move on. Over weeks, the cumulative effect will be substantial.
The framework I run this against is the four-layer enforcement framework, which provides the structural layers each Move 2 can live in.
If you're tired of AI scope creep and want help installing the codification loop in your specific workflow, send the kinds of scope creep you're seeing and the tools you're using. VibeKoded can scope a rescue diagnostic, stabilization sprint, or rebuild plan. → Work with VibeKoded