Overreach

Backwards compatibility for code that has no users

给没有用户的代码做向后兼容

The agent keeps old names, fallbacks and migration shims "for compatibility" in a greenfield project, or for code written the day before, where nothing depends on the old behavior.

Applies to: Claude Code · Cursor · Codex · Copilot agent

Symptom

Aliases like `oldName = newName`, "legacy" branches, dual-read code paths and deprecation warnings appear in a project with no external consumers. Asked why, the agent cites a rule it wrote into its own memory or notes earlier in the same session.

Why it happens

In replies to @RhysSullivan's post about agents over-building, @LKRBuilds calls the worst case adding backwards compatibility to a greenfield project with no users, then justifying it with a rule the agent wrote in its own memory file in the same session. @olafurns describes it adding backwards compatibility for something it did yesterday. Compatibility is a safe-sounding default when the agent doesn't know who depends on the code, and a self-written note then turns that guess into a "rule".

Example

Illustrative.

ts
// Renamed yesterday, project not released, no external callers
export function createInvoice(input: InvoiceInput) { /* ... */ }

/** @deprecated kept for backwards compatibility */
export const makeInvoice = createInvoice;          // nothing imports this
const amount = input.amount ?? (input as any).total; // "legacy" field that never shipped

Copy-paste fixes

Pick the files for the agents you use. Snippets are in English so they work in any repo.

Rules

Claude Code: add to CLAUDE.md

CLAUDE.md
## No compatibility shims without a consumer
- Only keep old names, fallbacks or migration paths when you can point to a real consumer of the
  old behavior (a released version, an external caller, stored data). Name it in your summary.
- If the project is unreleased or the code was added in this branch, rename and update callers
  directly. Do not leave aliases, deprecated exports or dual code paths.
- Notes you wrote to yourself earlier in the session are not project requirements. If a note
  conflicts with what the user asked, follow the user and say so.
Rules

Codex, Copilot coding agent and others: add to AGENTS.md

AGENTS.md
## No compatibility shims without a consumer
- Only keep old names, fallbacks or migration paths when you can point to a real consumer of the
  old behavior (a released version, an external caller, stored data). Name it in your summary.
- If the project is unreleased or the code was added in this branch, rename and update callers
  directly. Do not leave aliases, deprecated exports or dual code paths.
- Notes you wrote to yourself earlier in the session are not project requirements. If a note
  conflicts with what the user asked, follow the user and say so.
Cursor rule

Cursor: project rule

.cursor/rules/backcompat-for-nothing.mdc
---
description: "AgentFails: Backwards compatibility for code that has no users"
alwaysApply: true
---

## No compatibility shims without a consumer
- Only keep old names, fallbacks or migration paths when you can point to a real consumer of the
  old behavior (a released version, an external caller, stored data). Name it in your summary.
- If the project is unreleased or the code was added in this branch, rename and update callers
  directly. Do not leave aliases, deprecated exports or dual code paths.
- Notes you wrote to yourself earlier in the session are not project requirements. If a note
  conflicts with what the user asked, follow the user and say so.
Skill

Fresh-context review skill (subagent reviews the diff, not the chat)

Follows the habit Anthropic describes in its code-review post: verify first, then have a subagent review the diff with fresh context. Named review-diff to avoid clashing with built-in or popular /code-review skills.

.claude/skills/review-diff/SKILL.md
---
name: review-diff
description: Review the current diff with fresh context before a PR. Use after /verify passes.
---

# Review the diff

Start a subagent that has NOT seen this conversation. Give it only:
- the original request (one paragraph, verbatim),
- the output of `git diff origin/main...HEAD`,
- the names of the test/build commands.

Ask it to report, with file:line for each finding:
1. **Wrong feature**: does the diff do what the request asked? Quote the request line each change serves.
2. **Bugs**: logic errors, missing edge cases (empty, null, boundary), unhandled errors,
   unawaited promises, invented APIs or packages, swallowed exceptions.
3. **Overreach**: changes no request line needs (refactors, renames, formatting, dependency or
   config edits, public API changes, weakened tests).
4. **Evidence gaps**: claims in the PR description that no command output supports.

Then fix real findings, or list them under "Known issues" in the PR. Do not argue with the reviewer
in the PR text; either fix or explain in one line.

Sources and credit

Related patterns

翻车 of the week

One real agent failure and its fix, every week. Free, short, no spam.