The Four Categories of Acceptance Criteria: Reducing Uncertainty Before Design Begins

Leadership & Engineering December 31, 2020 Aravind HU

After spending more than a decade working across different flavours of agile teams, one pattern has remained consistent.

Teams struggle not because they lack skill or intent,
but because acceptance criteria are either vague, overloaded, or incomplete.

When acceptance criteria are weak, design becomes speculative, implementation becomes reactive, and uncertainty leaks into every downstream decision.

flowchart TD Weak["❌ Weak Acceptance Criteria"] --> D1["Speculative Design"] Weak --> D2["Reactive Implementation"] Weak --> D3["Downstream Uncertainty"] D1 --> Impact["💥 Impact on Team"] D2 --> Impact D3 --> Impact Impact --> I1["Rework & Delays"] Impact --> I2["Misaligned Expectations"] Impact --> I3["Technical Debt"] Impact --> I4["Reduced Confidence"] style Weak fill:#e74c3c,stroke:#c0392b,stroke-width:4px,color:#fff,font-size:16px style Impact fill:#e67e22,stroke:#d35400,stroke-width:3px,color:#fff style I1 fill:#95a5a6,stroke:#7f8c8d,stroke-width:2px,color:#fff style I2 fill:#95a5a6,stroke:#7f8c8d,stroke-width:2px,color:#fff style I3 fill:#95a5a6,stroke:#7f8c8d,stroke-width:2px,color:#fff style I4 fill:#95a5a6,stroke:#7f8c8d,stroke-width:2px,color:#fff

Acceptance Criteria as a Thinking Tool

Acceptance criteria are often treated as a checklist — something to validate after implementation.

That framing is backwards.

At scale, acceptance criteria are a thinking tool.
They exist to make intent explicit before design and delivery begin.

The fastest way to improve acceptance criteria is not to add more detail, but to classify intent clearly.


Why Classification Matters

One of the most effective ways to define anything complex is to first narrow the problem space.

Once narrowed, the next step is classification.

Classification:

  • removes ambiguity
  • exposes constraints
  • creates shared understanding
  • and enables meaningful design conversations
graph LR Problem["🎯 Complex Problem"] --> Narrow["Step 1:
Narrow Scope"] Narrow --> Classify["Step 2:
Classify Intent"] Classify --> B1["✓ Remove Ambiguity"] Classify --> B2["✓ Expose Constraints"] Classify --> B3["✓ Shared Understanding"] Classify --> B4["✓ Enable Design Conversations"] B1 --> Output["🎯 Clear Direction"] B2 --> Output B3 --> Output B4 --> Output style Problem fill:#e74c3c,stroke:#c0392b,stroke-width:3px,color:#fff style Narrow fill:#f39c12,stroke:#d68910,stroke-width:3px,color:#fff style Classify fill:#3498db,stroke:#2c3e50,stroke-width:3px,color:#fff style Output fill:#2ecc71,stroke:#27ae60,stroke-width:3px,color:#fff style B1 fill:#d5f4e6,stroke:#27ae60,stroke-width:2px style B2 fill:#d5f4e6,stroke:#27ae60,stroke-width:2px style B3 fill:#d5f4e6,stroke:#27ae60,stroke-width:2px style B4 fill:#d5f4e6,stroke:#27ae60,stroke-width:2px

Without classification, acceptance criteria become a flat list — and flat lists hide uncertainty.


The Four Categories of Acceptance Criteria

Over time, I’ve found it useful to classify acceptance criteria into four distinct categories.

Each category answers a different question about the system.

graph TB System["🏗️ Your System"] System --> Must["✅ MUSTS
What it MUST do"] System --> OughtNot["🚫 OUGHT NOTS
What it MUST NOT do"] System --> Want["⭐ WANTS
What enhances value"] System --> DontWant["⚠️ DON'T WANTS
What erodes value"] Must --> Q1["Defines:
Minimum Viable Correctness"] OughtNot --> Q2["Defines:
Boundaries & Constraints"] Want --> Q3["Defines:
Value Enhancers"] DontWant --> Q4["Defines:
Anti-patterns to Avoid"] Q1 --> E1["Example:
User can login"] Q2 --> E2["Example:
No PII in logs"] Q3 --> E3["Example:
Auto-save drafts"] Q4 --> E4["Example:
No 5-second delays"] style System fill:#34495e,stroke:#2c3e50,stroke-width:4px,color:#fff,font-size:16px style Must fill:#2ecc71,stroke:#27ae60,stroke-width:3px,color:#fff style OughtNot fill:#e74c3c,stroke:#c0392b,stroke-width:3px,color:#fff style Want fill:#3498db,stroke:#2c3e50,stroke-width:3px,color:#fff style DontWant fill:#f39c12,stroke:#d68910,stroke-width:3px,color:#fff style Q1 fill:#d5f4e6,stroke:#27ae60,stroke-width:2px style Q2 fill:#fadbd8,stroke:#e74c3c,stroke-width:2px style Q3 fill:#d6eaf8,stroke:#3498db,stroke-width:2px style Q4 fill:#fdebd0,stroke:#f39c12,stroke-width:2px

1. Musts — Non-Negotiable Requirements

Musts define what the system has to do in order to be considered correct.

These are the core requirements:

  • without which the solution has no value
  • and failure is not acceptable

Musts establish the minimum viable correctness of the system.


2. Ought Nots — Explicit Constraints

Ought nots define what the system must not be or do.

These constraints often get overlooked, yet they are critical.

They may include:

  • security boundaries
  • compliance limitations
  • performance ceilings
  • architectural guardrails

Making constraints explicit early prevents expensive rework later.


3. Wants — Value Enhancers

Wants describe behaviors or features that enhance the value of the solution but are not mandatory for correctness.

These are important, but optional:

  • they improve usability
  • increase adoption
  • or strengthen experience

Separating wants from musts enables better prioritization and sequencing.


4. Don’t Wants — Value Erosion Signals

Don’t wants capture behaviors that reduce the value of the solution.

They represent:

  • negative user experiences
  • operational friction
  • or unintended side effects

Explicitly calling these out protects the solution from subtle degradation over time.


Why This Classification Works

When acceptance criteria are structured this way, several things happen naturally:

  • Teams gain clarity on intent
  • Design discussions become focused
  • Trade-offs become visible
  • Assumptions surface early
flowchart LR subgraph Before["❌ Before Classification"] B1["Flat List of Requirements"] B1 --> B2["Hidden Assumptions"] B1 --> B3["Unclear Priorities"] B1 --> B4["Ambiguous Constraints"] end subgraph After["✅ After Classification"] A1["Structured Categories"] A1 --> A2["Explicit Intent"] A1 --> A3["Clear Priorities"] A1 --> A4["Visible Trade-offs"] end B4 --> Transform["🔄 Apply 4 Categories"] Transform --> A1 A4 --> Result["🎯 Outcome:
Reduced Uncertainty
Better Design Decisions"] style Before fill:#e74c3c,stroke:#c0392b,stroke-width:3px,color:#fff style After fill:#2ecc71,stroke:#27ae60,stroke-width:3px,color:#fff style Transform fill:#3498db,stroke:#2c3e50,stroke-width:3px,color:#fff style Result fill:#27ae60,stroke:#229954,stroke-width:3px,color:#fff,font-size:14px

Most importantly, this structure reduces technical uncertainty before design begins.

That is where acceptance criteria deliver their real value.


From Understanding to Synthesis

Once musts, ought nots, wants, and don’t wants are clear, teams can move confidently into design.

flowchart TD Start["📋 Acceptance Criteria"] --> C1["Define MUSTS"] Start --> C2["Define OUGHT NOTS"] Start --> C3["Define WANTS"] Start --> C4["Define DON'T WANTS"] C1 --> Understanding["🧠 Clear Understanding"] C2 --> Understanding C3 --> Understanding C4 --> Understanding Understanding --> State1["✓ Problem Well Understood"] Understanding --> State2["✓ Constraints Explicit"] Understanding --> State3["✓ Priorities Clear"] State1 --> Design["🎨 Design Phase"] State2 --> Design State3 --> Design Design --> Synthesis["🚀 Confident Synthesis"] Synthesis --> Outcome1["Better Architecture"] Synthesis --> Outcome2["Faster Implementation"] Synthesis --> Outcome3["Lower Risk"] style Start fill:#3498db,stroke:#2c3e50,stroke-width:3px,color:#fff style Understanding fill:#f39c12,stroke:#d68910,stroke-width:3px,color:#fff style Design fill:#9b59b6,stroke:#8e44ad,stroke-width:3px,color:#fff style Synthesis fill:#2ecc71,stroke:#27ae60,stroke-width:3px,color:#fff style Outcome1 fill:#d5f4e6,stroke:#27ae60,stroke-width:2px style Outcome2 fill:#d5f4e6,stroke:#27ae60,stroke-width:2px style Outcome3 fill:#d5f4e6,stroke:#27ae60,stroke-width:2px

At this point:

  • the problem is well understood
  • constraints are explicit
  • and synthesis of design concepts can begin with confidence

Acceptance criteria stop being documentation and start becoming an enabler of good engineering.


Closing Thought

Strong acceptance criteria are not about control.

They are about clarity.

And clarity is what allows teams to design, build, and evolve systems with intent rather than guesswork.

Previous Post

Measure… Measure… Measure…

Next Post

Options… Options… Options…

Share this post