Wrong feature

Built what it understood, not what you meant

按自己的理解做了,不是你要的那个

The agent ships a coherent feature that answers a different reading of the request. Every check passes, because the checks test the agent's reading too.

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

Symptom

You open the result and it is reasonable, tested, and wrong. You can point at the sentence in the ticket that allowed both readings.

Why it happens

Requests are underspecified, and the agent resolves ambiguity silently instead of asking. Tests are usually written by the same agent from the same reading, so they confirm the misread instead of catching it. developertoolkit.ai calls this class "spec misread" and puts its earliest control at the spec stage, before any code.

Example

Illustrative, based on the developertoolkit.ai example: the ticket says round totals to the cent.

ts
// Intended: round the order total once
const total = round2(items.reduce((s, i) => s + i.price * i.qty, 0));

// Agent's reading: round every line item, then sum (totals now drift by cents)
const total = items.reduce((s, i) => s + round2(i.price * i.qty), 0);

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
## Before writing code: confirm the spec
- Restate the request in one sentence and list every assumption you are making.
- If any sentence in the request allows two readings, ask which one before coding. Do not pick silently.
- Write the acceptance checks first (in SPEC.md or as failing tests), including one example that
  distinguishes the intended reading from the most plausible wrong one. Wait for approval on non-trivial work.
- When done, map each acceptance check to the command output that proves it.
Rules

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

AGENTS.md
## Before writing code: confirm the spec
- Restate the request in one sentence and list every assumption you are making.
- If any sentence in the request allows two readings, ask which one before coding. Do not pick silently.
- Write the acceptance checks first (in SPEC.md or as failing tests), including one example that
  distinguishes the intended reading from the most plausible wrong one. Wait for approval on non-trivial work.
- When done, map each acceptance check to the command output that proves it.
Cursor rule

Cursor: project rule

.cursor/rules/spec-misread.mdc
---
description: "AgentFails: Built what it understood, not what you meant"
alwaysApply: true
---

## Before writing code: confirm the spec
- Restate the request in one sentence and list every assumption you are making.
- If any sentence in the request allows two readings, ask which one before coding. Do not pick silently.
- Write the acceptance checks first (in SPEC.md or as failing tests), including one example that
  distinguishes the intended reading from the most plausible wrong one. Wait for approval on non-trivial work.
- When done, map each acceptance check to the command output that proves it.
Template

SPEC.md acceptance checks (written and approved before code)

Teammates annotate this file (or the mockup/artifact) instead of reviewing a big PR. Each check should separate the reading you mean from the reading you don't.

SPEC.md
# Spec: <feature name>

## Goal (one sentence, in the user's words)

## Out of scope
- <things a reasonable agent might also do, but must not>

## Acceptance checks (each one runnable)
- [ ] Given <input>, when <action>, then <exact observable result>
- [ ] Example that rules out the wrong reading: <input> -> <expected>, NOT <plausible wrong output>
- [ ] Command that proves it: `<test or curl command>`

## Open questions (agent must ask, not assume)
- <question>

## Approved by: <name> on <date>
Skill

Shared /verify skill for Claude Code

Commit it to the repo so the whole team (and every agent session) runs the same checks. Replace the commands with your project's real ones.

.claude/skills/verify/SKILL.md
---
name: verify
description: Verify the current change before calling it done. Use before every commit, PR, or "done" message.
---

# Verify

Run every step and paste the real output. Never summarize a step you did not run.

1. **Scope**: run `git diff --stat` and `git status --short`. For every changed file, say which part
   of the request needs it. Any file you cannot justify gets reverted, or listed under
   "Unrequested changes" for the user to decide.
2. **Build and types**: `npm run build` (or the project's build command).
3. **Tests**: `npm test`. Report pass/fail counts. If a test was edited, skipped or deleted,
   say so explicitly with the reason.
4. **Behavior**: exercise the changed behavior once for real (a curl, a CLI run, a screenshot)
   and show what happened.
5. **Report** in this format:
   - Requested: <one line>
   - Changed files: <list, each with its reason>
   - Checks run: <command -> result>
   - Not done / unsure: <list, or "none">

Sources and credit

Related patterns

翻车 of the week

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