Overreach

Hardened the code against cases no user will hit

为没有用户会遇到的情况加固代码

The agent (or its reviewer) piles on branches, guards and tests for states no real user can reach, while the obvious problems in the same diff go unnoticed.

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

Symptom

Long handlers for impossible combinations of events, "just in case" checks, extra e2e tests for a throwaway change, and review comments that always find another theoretical case. The diff grows; the real issue a few lines away (an N+1 query, a design problem) stays.

Why it happens

Quoting Thorsten Ball's PR post, @RhysSullivan wrote that models "love to add so much extra code for cases that will never happen". His example of what review "caught": "changing a setting while being demoted from admin in the same request". Replies add more: a 40-line handler for an unreachable state next to a missed N+1 query (@giskyexplorer), "useless machinery that will pass tests" (@Gabezor), e2e tests and a full test review proposed for a goodbye page on a project being shut down (@NapVeg), agents writing too many heavy, slow tests (@kopseng), and review bots that "always find something" users would never hit (@kenryu42). @leothecurious lists "paranoid defensive coding patterns" among the habits that keep him steering. Thoroughness is rewarded and nothing tells the agent how likely a case is, so every case looks worth handling.

Example

Illustrative, based on @RhysSullivan's example.

ts
async function updateSetting(user, key, value) {
  // Agent-added: "user could be demoted from admin during this same request"
  const fresh = await db.users.findFresh(user.id);
  if (!fresh.isAdmin && wasAdminAtRequestStart(user)) {
    await auditLog("demoted-mid-request", user.id);
    throw new ConcurrentDemotionError(user.id);
  }
  // ...30 more lines of guards...
  return db.settings.set(key, value);
}

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
## Handle realistic cases, not imaginable ones
- Before adding a guard, branch or test for an edge case, state in one line how a real user or
  caller reaches it. If you can't, don't add it; mention it in your summary instead.
- Match the effort to the task. A one-off or throwaway change doesn't get new e2e suites or a full
  test review unless the user asks.
- When reviewing, rate each finding by severity and likelihood, and only fix findings the user
  agrees are likely. List the rest as "not fixed: unlikely".
- Prefer one test that starts from real user behavior over many tests for hypothetical states.
Rules

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

AGENTS.md
## Handle realistic cases, not imaginable ones
- Before adding a guard, branch or test for an edge case, state in one line how a real user or
  caller reaches it. If you can't, don't add it; mention it in your summary instead.
- Match the effort to the task. A one-off or throwaway change doesn't get new e2e suites or a full
  test review unless the user asks.
- When reviewing, rate each finding by severity and likelihood, and only fix findings the user
  agrees are likely. List the rest as "not fixed: unlikely".
- Prefer one test that starts from real user behavior over many tests for hypothetical states.
Cursor rule

Cursor: project rule

.cursor/rules/imaginary-edge-case-hardening.mdc
---
description: "AgentFails: Hardened the code against cases no user will hit"
alwaysApply: true
---

## Handle realistic cases, not imaginable ones
- Before adding a guard, branch or test for an edge case, state in one line how a real user or
  caller reaches it. If you can't, don't add it; mention it in your summary instead.
- Match the effort to the task. A one-off or throwaway change doesn't get new e2e suites or a full
  test review unless the user asks.
- When reviewing, rate each finding by severity and likelihood, and only fix findings the user
  agrees are likely. List the rest as "not fixed: unlikely".
- Prefer one test that starts from real user behavior over many tests for hypothetical states.
CI / script

Diff budget check (run before commit or in CI)

Adapted from the diff-budget post on dev.to (yureki_lab). Reads the real git diff, so it also catches edits made through the shell. Usage: python3 scripts/diff_budget.py origin/main 6 150

scripts/diff_budget.py
#!/usr/bin/env python3
"""Fail if the diff vs BASE touches files outside .agent-scope or exceeds the budget."""
import fnmatch, os, subprocess, sys

base = sys.argv[1] if len(sys.argv) > 1 else "HEAD"
max_files = int(sys.argv[2]) if len(sys.argv) > 2 else 6
max_lines = int(sys.argv[3]) if len(sys.argv) > 3 else 150

allowed = []
if os.path.exists(".agent-scope"):
    allowed = [l.strip() for l in open(".agent-scope") if l.strip() and not l.startswith("#")]

out = subprocess.run(["git", "diff", "--numstat", base], capture_output=True, text=True, check=True).stdout
untracked = subprocess.run(["git", "ls-files", "--others", "--exclude-standard"],
                           capture_output=True, text=True, check=True).stdout.split()

files, lines, outside = 0, 0, []
rows = [r.split("\t") for r in out.strip().splitlines()] + [["0", "0", p] for p in untracked]
for added, deleted, path in rows:
    files += 1
    if added != "-":
        lines += int(added) + int(deleted)
    if allowed and not any(fnmatch.fnmatch(path, p) for p in allowed):
        outside.append(path)

problems = []
if outside:
    problems.append("out-of-scope files: " + ", ".join(outside))
if files > max_files:
    problems.append(f"{files} files changed (budget {max_files})")
if lines > max_lines:
    problems.append(f"{lines} lines changed (budget {max_lines})")

if problems:
    print("OVER BUDGET: " + "; ".join(problems))
    sys.exit(1)
print(f"within budget: {files} files, {lines} lines")
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.