[BUG] Claude silently reverts existing features when making unrelated changes (no spec/test guardrails)

Resolved 💬 2 comments Opened Jun 21, 2026 by lcslouis Closed Jun 25, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Summary

When Claude makes changes to a codebase — even targeted, unrelated changes — it has
a consistent tendency to silently revert or simplify existing features it wasn't asked
to touch. This happened repeatedly in a real project and caused significant regression
debt requiring manual auditing to find and fix.

Observed Behavior

Across multiple sessions on the same codebase, Claude introduced the following
regressions without being asked to remove anything:

  1. Toolbar menus gutted — A commit adding background AI processing completely

replaced the toolbar structure (Library▾, Book▾, Batch▾ dropdowns) with a
simplified version, removing ~15 actions and their handler methods silently.

  1. Readest push/sync features removed — Auto-push to Readest, manual push,

WebDAV sync, local sync, book mappings — all removed in the same rewrite
without mention.

  1. Background TOC worker dropped_QueueWorker (a background thread keeping

the UI responsive during download queuing) was silently deleted when a new class
was added to the same file.

  1. Update checker dedup regressed — A previously fixed bug (re-downloading all

chapters instead of only new ones) reappeared after Claude rewrote the same
function. The correct fix used len(get_chapters()); Claude reverted it to
get_max_chapter_number() — wrong for books with non-sequential chapter numbers.

  1. DB integrity/recovery methods simplified outcheck_integrity() and

recover_db() in database.py dropped during an unrelated refactor.

Root Cause Pattern

Claude rewrites or regenerates entire functions/classes rather than making surgical
edits. When regenerating, it reconstructs from its understanding of the current task,
not from a complete read of what existed. Features irrelevant to the current task get
dropped because they were never loaded into context.

This is especially dangerous when:

  • The file is large (500+ lines)
  • The change is in one section but unrelated features live in other sections
  • There are no tests covering existing behavior
  • There is no spec document describing what must remain

What Stopped Further Regressions

Two guardrails were added and proved effective:

  1. CLAUDE.md spec file listing every toolbar item, signal, method, and invariant

that must exist, with the instruction: "Do not modify existing features without
user approval." Claude respects this consistently when it's present.

  1. Source-level regression tests (pure text/AST, no runtime required) asserting

specific symbols, method names, and signals exist in source files. These run in CI.

Example that would have caught the toolbar regression:

@pytest.mark.parametrize("method_name", [
    "_make_dropdown_btn", "_push_current_to_readest", "_auto_push_readest", ...
])
def test_required_method_defined(method_name):
    assert f"def {method_name}" in SOURCE

### What Should Happen?

The GitHub MCP tool in this session is scoped only to your repositories — it can't post to `anthropics/claude-code` directly. You'll need to submit it yourself.

Here's the issue, ready to paste at **https://github.com/anthropics/claude-code/issues/new**:

---

**Title:** `Claude silently reverts existing features when making unrelated changes (no spec/test guardrails)`

**Body:**

Summary

When Claude makes changes to a codebase — even targeted, unrelated changes — it has
a consistent tendency to silently revert or simplify existing features it wasn't asked
to touch. This happened repeatedly in a real project and caused significant regression
debt requiring manual auditing to find and fix.

Observed Behavior

Across multiple sessions on the same codebase, Claude introduced the following
regressions without being asked to remove anything:

  1. Toolbar menus gutted — A commit adding background AI processing completely

replaced the toolbar structure (Library▾, Book▾, Batch▾ dropdowns) with a
simplified version, removing ~15 actions and their handler methods silently.

  1. Readest push/sync features removed — Auto-push to Readest, manual push,

WebDAV sync, local sync, book mappings — all removed in the same rewrite
without mention.

  1. Background TOC worker dropped_QueueWorker (a background thread keeping

the UI responsive during download queuing) was silently deleted when a new class
was added to the same file.

  1. Update checker dedup regressed — A previously fixed bug (re-downloading all

chapters instead of only new ones) reappeared after Claude rewrote the same
function. The correct fix used len(get_chapters()); Claude reverted it to
get_max_chapter_number() — wrong for books with non-sequential chapter numbers.

  1. DB integrity/recovery methods simplified outcheck_integrity() and

recover_db() in database.py dropped during an unrelated refactor.

Root Cause Pattern

Claude rewrites or regenerates entire functions/classes rather than making surgical
edits. When regenerating, it reconstructs from its understanding of the current task,
not from a complete read of what existed. Features irrelevant to the current task get
dropped because they were never loaded into context.

This is especially dangerous when:

  • The file is large (500+ lines)
  • The change is in one section but unrelated features live in other sections
  • There are no tests covering existing behavior
  • There is no spec document describing what must remain

What Stopped Further Regressions

Two guardrails were added and proved effective:

  1. CLAUDE.md spec file listing every toolbar item, signal, method, and invariant

that must exist, with the instruction: "Do not modify existing features without
user approval." Claude respects this consistently when it's present.

  1. Source-level regression tests (pure text/AST, no runtime required) asserting

specific symbols, method names, and signals exist in source files. These run in CI.

Example that would have caught the toolbar regression:

@pytest.mark.parametrize("method_name", [
    "_make_dropdown_btn", "_push_current_to_readest", "_auto_push_readest", ...
])
def test_required_method_defined(method_name):
    assert f"def {method_name}" in SOURCE

Suggested Improvements

  1. Before rewriting any existing function or class, Claude should re-read the full

function and explicitly confirm it is not removing anything that existed.

  1. Claude should proactively suggest creating a CLAUDE.md spec when starting work on

a codebase that lacks one, especially before editing large files.

  1. Claude should proactively suggest regression tests for existing behavior before

making changes, not only for new features.

  1. When asked to add a feature to a file, Claude should explicitly list which existing

functions it read and confirm nothing is being removed — similar to how it confirms
destructive shell commands.

  1. Context compaction/summarization should preserve a list of known-existing symbols

so long sessions don't lose track of what was in place at the start.

Impact

All regressions were caught and fixed, but required:

  • Manually running git diff <baseline-tag> HEAD across all changed files
  • Reconstructing the original main_window.py from a baseline git tag
  • Writing a full test suite retroactively
  • Writing a CLAUDE.md spec file retroactively

Without a baseline git tag to diff against, several would have gone unnoticed
until users reported broken functionality.

Environment

  • Claude Code (remote/web session)
  • Model: claude-sonnet-4-6
  • Project: multi-file Python/PySide6 desktop app (~30 source files, ~5000 lines)
  • Session length: multiple sessions with context compaction between them

Error Messages/Logs

Steps to Reproduce

Steps to Reproduce

  1. Open a multi-file codebase (500+ lines per file) in a Claude Code session.
  1. Ask Claude to add a new feature to an existing large file (e.g. "add background

processing for AI tasks to main_window.py").

  1. Claude rewrites the file — check the diff:

git diff HEAD~1 HEAD -- <file>

  1. Observe that methods, signals, or UI elements unrelated to the requested feature

are silently missing from the rewritten version.

  1. Repeat across multiple sessions (especially after context compaction). Each new

session that touches the same file has a chance of dropping more features because
the compacted summary describes intent, not the full symbol inventory.

Minimal Reproducible Example

  1. Create a Python file with 3 unrelated classes (A, B, C), each with several methods.
  1. Ask Claude: "Add a new method foo() to class A."
  1. Inspect the result — class B or C methods may be silently removed or simplified,

particularly if the file is long enough that Claude did not read it in full before
writing its replacement.

Confirmed Trigger Conditions

  • File length: 400+ lines
  • Claude uses Write tool (full file rewrite) instead of Edit tool (targeted diff)
  • The feature being added is in a different section of the file than the features

being dropped

  • No CLAUDE.md spec listing required symbols
  • No regression tests asserting existing symbols are present
  • Multiple sessions with context compaction between them (summary loses symbol

inventory detail)

Version

Claude Code CLI: 2.1.185
Model: claude-sonnet-4-6

Claude Model

Sonnet (default)

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

Claude Code CLI version 2.1.185.

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗