AI Changes Scope Because the Task Boundary Is Unclear

You asked the model to do one thing; it also did three adjacent things you did not want.

You asked the model to fix one function. It fixed the function. It also “while it was at it” reformatted two adjacent functions, renamed a constant, and added a comment block above the file because “this should explain the module purpose”. None of that was in your prompt. But none of it was forbidden either. The model expanded scope because RLHF trains it to leave things “better than it found them”, and “better” is unbounded unless you explicitly bound it. The fix is not to scold the model after the fact — it is to draw the boundary explicitly in the prompt, with both an in-scope set and an out-of-scope set.

This page walks through why models default to scope expansion and how to draw boundaries that hold up across both code edits and content tasks.

Common causes

1. Open verbs license expansion

“Improve”, “clean up”, “polish”, “refactor” all imply “make better wherever you can”. The model takes that literally.

How to spot it: your verb is open. Scoped verbs are “edit function X”, “replace line Y”, “rename variable Z”.

2. No explicit out-of-scope list

You said what to do but not what to leave alone. The model assumes everything within view is fair game.

How to spot it: your prompt has in-scope but no out-of-scope.

3. Long context shows fixable adjacent issues

You pasted the whole file. The model sees both your target and 5 other things that look fixable. Without a boundary, it fixes them all.

How to spot it: scope expansion lands in adjacent code or content visible in the prompt.

4. Multi-step task with no per-step boundary

Step 1 was scoped to function X. Step 2 says “now improve the module” — boundary evaporates. By step 3 the model has rewritten the file.

How to spot it: scope creep correlates with step number in multi-step workflows.

5. Agent has wide write permission

In Cursor Composer, Claude Code, or Codex with broad scope, the model can touch any file. “Scope” mechanically becomes “everything it can read”.

How to spot it: changes appear in files you never named.

Before you change anything

  • Identify exactly what should change (in-scope).
  • Identify what should not change (out-of-scope).
  • Decide whether the model should flag adjacent issues or just ignore them.
  • For multi-step work, plan boundaries per step.
  • For agent runs, narrow tool permissions to the target directory only.

Information to collect

  • Current prompt.
  • The over-scope output (git diff for code).
  • A list of changes that should not have happened.
  • The in-scope and out-of-scope sets.
  • Model, agent, and tool permissions in effect.

Shortest path to fix

Step 1: Replace open verbs with scoped verbs

Bad:  "Improve the user.py file."
Good: "Edit only the function `validate_email` in user.py. Keep all
       other functions byte-identical. Do not reformat unchanged lines."

The scoped verb plus an explicit object eliminates ambiguity.

Step 2: Declare an out-of-scope list

Out of scope (do not modify):
- Any function other than validate_email.
- Imports and exports.
- The MAX_RETRIES constant.
- Existing comments.
- File-level docstring.

If you would normally "clean up" something, list it in a
SUGGESTED_FOLLOWUPS section instead of changing it.

The SUGGESTED_FOLLOWUPS pattern lets the model surface its observations without acting on them.

Step 3: Use marked edit zones

Edit only the code between the markers below. Leave everything
outside the markers exactly as written.

# AI-EDIT-START
def validate_email(email: str) -> bool:
    return "@" in email
# AI-EDIT-END

Physical markers are robust against scope drift.

Step 4: Require diff or structured output

Output as a unified diff. Only include hunks for changes inside the
edit zone. Do not output the full file.

Diff format makes out-of-scope edits mechanically visible — and the model knows it.

Step 5: For multi-step work, re-declare boundary per step

Step 1: Edit ONLY validate_email. Out of scope: everything else.
Step 2: Once step 1 is approved, edit ONLY send_email. Out of scope: validate_email (now frozen) + everything else.

Carry forward “now frozen” lists so scope is monotonic, not accumulating.

Step 6: For agents, restrict tool permissions

In Cursor Composer, open only the target file. In Claude Code, restrict the working directory. In Codex, set scope to one file or one PR. Mechanical permission > prompt-level instruction.

How to confirm the fix

  • The diff is restricted to the in-scope set.
  • Out-of-scope files / functions / sections are byte-identical.
  • SUGGESTED_FOLLOWUPS (if present) lists adjacent issues the model noticed without changing.
  • Re-running the prompt produces a similar-shaped diff.
  • A teammate reviewing the diff cannot point to surprising changes.

If it still fails

  1. The model may be ignoring boundaries — try Edit-tool exact-match mode where boundaries are mechanical.
  2. The agent may have wider permissions than your prompt implies — restrict at the tool level.
  3. For repeated work, lock the boundary in system prompt / project instructions, not user message.
  4. Switch to a smaller / cheaper model — many follow scope constraints more strictly.

Prevention

  • Default verb: “edit”, “rename”, “replace” — never “improve”, “refactor”, “polish” without scoping.
  • Always declare out-of-scope; if nothing is sacred, say so.
  • Use marked edit zones for content; use exact-match Edit tools for code.
  • For agent workflows, restrict tool scope mechanically.
  • Use SUGGESTED_FOLLOWUPS pattern: let the model report observations without acting on them.
  • Audit diffs / outputs every time. Do not trust the model’s self-summary of changes.

Tags: #Troubleshooting #Prompt #Prompt quality #Prompt engineering