Why Acceptance Criteria Must Evolve
For 20 years, Acceptance Criteria (AC) were treated as a checklist for humans. Developers read them, interpreted them, debated them, and implemented them. This workflow assumed human cognition as the execution engine.
But in 2025, the execution engine is increasingly AI agents, IDE copilots, and autonomous coding loops. These systems build logic directly from requirements—yet most ACs today are written in vague, narrative prose:
“User should be able to easily upload a photo.”
This is unreadable to an AI agent. “Easily”? What does that mean? Max size? Supported formats? Timeout limits? If the requirement is fuzzy, the generated code is fuzzy—or wrong.
The old discipline was: write AC for clarity.
The new discipline is: write AC for execution.
This guide will teach you how to write ACs optimized for machines—specifically for workflows powered by ProdMoh and the Model Context Protocol (MCP).
1. The New Standard: Machine-Readable Acceptance Criteria
You are not writing ACs for “developers” anymore—you are writing ACs for:
- Cursor's AI agent
- VS Code AI extensions
- PRD-consuming MCP clients
- Automated test generators
- CI policy gates
These systems require structured, deterministic assertions. The fewer adjectives and adverbs, the better.
❌ Bad (Human-centric)
• The user can easily upload a picture
• The system should validate the image
• The image should be visible instantly
✅ Good (Machine-centric)
[
{"type":"predicate","expr":"file.size <= 5MB"},
{"type":"predicate","expr":"file.format in ['jpg','png']"},
{"type":"predicate","expr":"response.status == 200"},
{"type":"invariant","expr":"aspect_ratio == 1:1"}
]
Notice the difference: no ambiguity, no prose—just executable logic.
2. The 5 Rules of Writing Acceptance Criteria for AI
Rule 1 — No Adjectives or Adverbs
Words like “easy”, “fast”, “intuitive”, “robust”, “smooth” mean nothing to an LLM.
Replace them with numeric or boolean expressions.
Rule 2 — Express Logic as Predicates
Predicates are the atomic units for test generation:
{"type":"predicate","expr":"cart.total >= 0"}
ProdMoh automatically parses these and feeds them into the MCP stream.
Rule 3 — Provide Concrete Examples
AI agents rely heavily on examples to create mocks, tests, and implementation suggestions.
{
"input": {"query": "red shoes"},
"output": {"items": [{"id":"p-103","price":199}]}
}
Rule 4 — State Invariants Explicitly
Invariants are global truths that should always hold. These are powerful for catching logic regressions.
{"type":"invariant","expr":"stock_count >= 0"}
Rule 5 — Separate Functional & Non-Functional ACs
NFRs should never be mixed with functional logic.
{"type":"nfr","expr":"api.latency_p95 <= 300ms"}
3. The Structure of an AI-Optimized Acceptance Criteria Block
A complete AI-ready AC block has four components:
- Predicates (primary truth statements)
- Examples (input/output mappings)
- Invariants (global truths)
- NFRs (latency, throughput, rate limits)
Full Example
{
"id":"S-200",
"title":"Search results show paid badge for priced items",
"acceptance":[
{"type":"predicate","expr":"response.json.items.length >= 1"},
{"type":"predicate","expr":"response.json.items[i].badges includes 'paid' when price > 0"},
{"type":"invariant","expr":"item.price >= 0"}
],
"examples":[
{
"query":"red shoes",
"product":{"id":"p-103","price":199},
"expected":{"badges":["paid"]}
}
],
"nfr":[
{"type":"nfr","expr":"api.latency_p95 <= 300ms"}
]
}
4. How IDEs Convert AC into Tests (MCP Flow)
Once ACs follow this structure, MCP-enabled IDEs like Cursor can generate high-fidelity tests automatically.
Example mapping
{
"predicate":"response.json.items[0].badges includes 'paid'",
"template":"test('item has paid badge', async () => { const r = await search('red shoes'); expect(r.json.items[0].badges).toContain('paid'); });"
}
This allows agents to:
- create mocks
- generate Jest tests
- self-correct code until tests pass
- enforce NFR constraints
Structured AC is the fuel that powers autonomous engineering loops.
5. A Checklist for PMs: “Is this AC AI-ready?”
Before publishing in ProdMoh, ensure:
- No adjectives or vague prose
- Every truth stated as a predicate
- Examples match acceptance conditions
- Invariants are explicit
- NFRs separated from functional logic
- All numbers defined (max_length, size_limit, thresholds)
This takes 2–5 extra minutes for a PM but saves 10–50 hours during development.
6. Common Mistakes & Fixes
1. Writing behavior instead of logic
Bad: “Items should load fast.”
Good: {"type":"nfr","expr":"latency_p95 <= 300ms"}
2. Writing narrative AC
Bad: “User can add items to cart and see total update.” Good:
[
{"type":"predicate","expr":"cart.items.length == previous_length + 1"},
{"type":"predicate","expr":"cart.total == sum(cart.items[*].price)"}
]
3. Edge-case assumptions
AI does not assume. If you don’t specify “zero state”, it won’t infer it.
7. Templates You Can Use in ProdMoh
Template: Predicate AC
{"type":"predicate","expr":" "}
Template: Invariant
{"type":"invariant","expr":""}
Template: NFR
{"type":"nfr","expr":" "}
8. Conclusion
AI-ready Acceptance Criteria are not a “formatting improvement.” They are a foundational shift in what a PRD is.
When ACs become structured, deterministic, and machine-readable:
- AI agents generate higher-quality code
- Tests become auto-generated
- CI validates product intent continuously
- Developers avoid clarifications and guesswork
- Product teams ship faster with fewer regressions
As more engineering teams adopt MCP and agentic workflows, the skill of writing AI-ready AC will become as fundamental as writing user stories themselves.