Reading: Part 20. SDD Antipatterns

Lesson 1 of 5 in module «Part 20. SDD Antipatterns»
You are viewing the lesson without signing in. Sign in to save progress and take tests.

Part 20. SDD Antipatterns

An antipattern is a habit that looks like a correct process but breaks the result. In SDD, such errors are especially insidious: the files exist, the checks exist, the agent works quickly, but the human gradually loses control.

This part serves as a diagnostic map. If the process has become heavy, noisy, or useless, start here.

Specification After Code

Symptom: the agent first implements the feature, then writes requirements.md, plan.md, and validation.md to match the already finished code.

Why it's bad: the specification stops guiding the work and turns into a report. In this mode, it doesn't protect against the agent's unnecessary decisions.

How to fix:

  • commit at least a draft specification before implementation;
  • prohibit the agent from writing product code during the specification creation session;
  • in the merge request, explicitly show the specification commit before the implementation commit.

Giant requirements.md

Symptom: one requirements file contains dozens of items, multiple scenarios, future phases, and controversial decisions.

Why it's bad: the agent starts choosing what to consider primary. The human also stops seeing boundaries.

How to fix:

  • break the feature into phases;
  • move future ideas to roadmap.md;
  • keep in requirements.md only what is needed for the current branch;
  • mark controversial decisions as questions, not requirements.

validation.md That Nobody Ran

Symptom: the validation contains beautiful facts, but no traces of their execution.

Why it's bad: such a file creates a false sense of readiness. It looks strict, but doesn't allow the branch to merge.

How to fix:

  • store a command or manual scenario next to each mandatory fact;
  • in the agent's report, ask for a list of passed, failed, and unverified facts;
  • don't consider a fact confirmed if it cannot be reproduced.

Weakening Facts After an Error

Symptom: a test fails, after which the agent changes the expected result in validation.md, not the code.

Why it's bad: the process starts protecting the agent's implementation, not the product's intent.

How to fix:

  • ask the agent to first show the discrepancy without edits;
  • review validation.md edits especially carefully;
  • save the reason for changing a fact in the specification or merge request;
  • prohibit removing mandatory facts without human decision.

Ritual /clear

Symptom: /clear is called between phases, but after it the agent still receives a long explanation from the chat.

Why it's bad: the command creates the appearance of checking portability. In reality, the process still depends on human memory.

How to fix:

  • after /clear, give the agent only file references;
  • check whether a new session can understand the next task from the repository;
  • if it can't, supplement the specifications, not the prompt.

Skill as a Magic Button

Symptom: the team invokes the Qwen Code skill, but nobody reads SKILL.md or understands what decisions it makes.

Why it's bad: the skill becomes a hidden process. When it fails, people don't know what to fix.

How to fix:

  • store project skills in the repository;
  • review SKILL.md as process code;
  • write not only commands in the skill, but also constraints;
  • don't create a skill until 2–3 repetitions of the manual process.

QWEN.md as a Dump

Symptom: QWEN.md is used to pile up product requirements, stack, personal preferences, temporary tasks, and error notes.

Why it's bad: the agent stops distinguishing permanent rules from temporary context.

How to fix:

  • store product decisions in specs/;
  • store agent behavior rules in QWEN.md;
  • move temporary conclusions to memory or retrospective;
  • regularly remove outdated rules.

Hook That Silently Changes the Project

Symptom: a hook formats, rewrites, or deletes files without an explicit step in the plan.

Why it's bad: some changes appear outside the control of both the agent and the human. Later it's hard to understand who changed the behavior.

How to fix:

  • by default, hooks should check or log, not modify files;
  • allow automatic formatting only as an explicit command rule;
  • all file changes must appear in the regular git diff;
  • when blocking, a hook must explain the reason.

Memory as a Hidden Source of Truth

Symptom: the agent makes decisions based on memory, but these decisions are not in specs/, QWEN.md, or AGENTS.md.

Why it's bad: a new team member won't see the basis for the decision. Another agent might not receive it either.

How to fix:

  • treat memory as a hint, not a rule;
  • move recurring conclusions to reviewable files;
  • delete outdated memory;
  • in a dispute between memory and specification, choose the specification.

MCP Without a Task

Symptom: several MCP servers are connected to the project "for the future".

Why it's bad: the agent gets extra authority and more ways to make mistakes. The team stops understanding what external actions are even possible.

How to fix:

  • connect MCP only for a specific scenario;
  • limit the list of tools;
  • store the configuration in a reviewable place;
  • disable experimental servers after testing.

MVP That Is Too Big

Symptom: the first working version includes authentication, roles, analytics, a beautiful interface, migrations, data import, and integrations.

Why it's bad: the agent quickly creates many files, but the human doesn't have time to understand the quality of the decisions.

How to fix:

  • the first phase should prove one risk;
  • limit the work by time;
  • return to the last green state if the branch has sprawled;
  • add features only after facts that can already be verified.

Hallucinations in Agent Code

Symptom: the agent confidently references a function, method, or package that doesn't exist. The import points to a non-existent module; the call uses an API that only appeared in the next major version; a dependency is added to package.json that doesn't exist in the registry or is named almost like a known one (e.g., requests-py instead of requests).

Why it's bad: hallucinated imports may not fail at the type stage if the agent itself added a stub. Non-existent package names are especially dangerous: an attacker may pre-register such a name in the registry (a slopsquatting attack), and npm install will quietly pull in malicious code.

How to fix:

  • keep a list of allowed dependencies in tech-stack.md;
  • any dependency addition is a separate review step, not part of "implement the feature";
  • at the first type or runtime error, verify the package version against package.json;
  • before npm install, look at the package name with your own eyes; a name differing from the familiar one by a single letter is a stop signal;
  • if the agent references a function that didn't exist in the code before, demand a reference: "show the definition or say where it should appear".

Illusions of Testing

Symptom: npm test is green, but the bug remains. Tests exist, but they don't verify what they claim.

Typical subtypes:

  • tautological test: the test compares a function's result with the same expression as in the function — renaming a variable will break everything, but the logic is never checked;
  • test mirror: the test verifies that the function returns what it returned, without an independent expected value;
  • deception through snapshot: the first run creates a snapshot, the second compares against it; the error is frozen in the snapshot and considered "correct";
  • test that never fails under any error: the only assertion is that the function didn't throw an exception.

Why it's bad: a green test suite stops being a fact of readiness. The specification is formally fulfilled ("90% coverage"), but there are no real guarantees.

How to fix:

  • in validation.md, demand a fact-repro: a command that fails before the fix and passes after (especially for bugfixes, see part 11);
  • during review, read the tests themselves, not just the coverage number;
  • for critical places, apply mutation testing (for Vitest there is Stryker): the service makes small edits to the code and checks whether the tests catch them. If no mutation is caught, the tests verify nothing;
  • prohibit snapshots for business logic; snapshots are only acceptable where the result is a human-readable render.

Developer Doesn't Understand Their PR

Symptom: the author opens a merge request but cannot explain why a particular decision was made; in response to a reviewer's question, they re-ask the agent and forward the answer.

Why it's bad: responsibility for the code is blurred. In six months, no one on the team will be able to say why this particular error handling is here and whether it was a conscious choice. If the author doesn't understand their PR, the reviewer cannot rely on their judgment, and a future reader will wander in hypotheses.

How to fix:

  • introduce a rule: the PR author must explain in one paragraph in their own words what was done and why (see template in appendix C);
  • the reviewer asks at least one question that only a human can answer ("why is the database read outside a transaction here?"); if the author doesn't answer or answers with a chat excerpt, the PR is returned for revision;
  • in the team, encourage the "paired SDD" pattern: one writes the specification, the other reviews it before implementation (part 22, paired credit);
  • for yourself — after merging, re-read the git diff and formulate aloud: "I did X because Y." If you can't explain it, in the next feature ask the agent not only for code but also for an explanation in the PR comments.

Diagnostic Checklist

If SDD has stopped helping, answer:

  1. Are there features where the specification was written after the code?
  2. Can the facts from validation.md be executed without the chat history?
  3. Is it clear which rules live in QWEN.md and which in specs/?
  4. Are there hooks that modify files without an explicit step?
  5. Are there MCP servers without a current task?
  6. Are there decisions that live only in the agent's memory?
  7. Can a new agent after /clear continue working from the files?
  8. Can the current project phase be explained in one minute?

If the answer is negative for three questions, don't add new tools. Simplify the process.

Related Parts

  • Part 16 — the same errors from the reviewer's perspective: how to catch an antipattern in someone else's pull request.
  • Part 18 — antipatterns that are simultaneously security threats (secrets in specifications, MCP without review, weakening validation.md).
  • Part 9 — the "feature type → fact level" matrix, which directly cures the "weak validation.md" antipattern.
My notes
0 / 10000

Notes are saved in this browser. They will not appear on another device.

Course menu

Course

Specification-Driven Development with Qwen Code CLI
Progress 0 / 135