DEV Community

Zac
Zac

Posted on

Claude Code scope drift: why it happens and how to stop it

Claude Code drifts. You ask it to fix a bug, and it fixes the bug, refactors two adjacent functions, adds a comment explaining why the old approach was suboptimal, and updates a test that wasn't broken.

None of that was asked for. All of it is now in your diff.

Here's why it happens and how to stop it.

Why Claude Code drifts

Claude is trained to be helpful, and "helpful" often means doing more than was asked. When it reads a function to fix a bug, it notices other things — dead code, inconsistent naming, an error case that could be handled better. The default behavior is to address them.

In a coding session with tight back-and-forth, this is often fine. In an autonomous session or when you want minimal changes, it's a problem.

The CLAUDE.md rule that actually helps

Minimal footprint. Only modify files directly required for the stated task.
Do not refactor adjacent code, add comments to unchanged files,
or improve things you were not explicitly asked to change.
If you notice other issues, add a TODO comment — do not fix them.
Enter fullscreen mode Exit fullscreen mode

The key phrases:

  • "Only modify files directly required" — not files that are related, just the ones the task requires
  • "If you notice other issues, add a TODO comment" — gives Claude somewhere to put observations without acting on them

Before and after

Before the rule:

Task: Fix the null check in getUserById

Result:
- Fixed the null check ✓
- Refactored getUserById to use optional chaining (not asked)
- Added JSDoc to getUser and updateUser while "in the file" (not asked)
- Changed the error message in a catch block (not asked)
- Modified 3 tests to use new patterns (not asked)
Enter fullscreen mode Exit fullscreen mode

After the rule:

Task: Fix the null check in getUserById

Result:
- Fixed the null check ✓
- Added TODO: getUserById could use optional chaining
- Added TODO: error messages in catch blocks are inconsistent
Enter fullscreen mode Exit fullscreen mode

Same observations. Contained actions.

Scope declaration before tasks

Before starting any non-trivial task, have Claude state what files it plans to touch:

Before you begin: list the files you expect to modify and why.
Do not modify any file not on this list without asking first.
Enter fullscreen mode Exit fullscreen mode

This forces Claude to think about scope before acting, rather than discovering it as it goes.

Verifying after

When Claude reports done, ask it to list every file it changed. Compare that to what you expected. Any file not on the expected list is scope drift.

List every file you modified in this session.
For each file, state what change you made and why.
Enter fullscreen mode Exit fullscreen mode

This takes 30 seconds and catches most drift.


I packaged the scope control skills into Drift Detector — three skills that handle scope declaration before tasks, mid-task drift audits, and post-task verification. $15, instant download.

Top comments (0)