Every ambiguous acceptance criterion you catch at refinement costs one comment; the same ambiguity caught in test execution costs a bug ping-pong, a re-open, and a sprint-review argument. Point an adversarial prompt at the backlog and hunt untestability while it is still cheap.
Tier: Foundation · Workflow area: Test design & planning
QA's oldest superpower is asking "what exactly does this mean?" before anyone writes code. This playbook industrializes that instinct: an LLM reads each story hunting ambiguity, missing acceptance criteria, contradictions, and unmeasurable claims — and you carry the defensible findings into refinement as questions, not accusations.
When NOT to use:
jq locally if you are trimming JSON.Export the sprint candidates. Pull story summaries, descriptions, and acceptance criteria. From Jira Cloud, a filter export to CSV works; strip fields you don't need and any client-identifying data:
jq -r '.issues[] | "## " + .key + ": " + .fields.summary + "\n" + (.fields.description // "NO DESCRIPTION")' \
backlog-export.json > stories.md
Run the adversarial critique, one structured pass. The framing matters: the model must attack, not summarize.
You are a hostile-but-fair test lead reviewing user stories for TESTABILITY.
For each story below, report:
1. AMBIGUOUS TERMS — words with multiple readings ("fast", "recent",
"appropriate", "user"), each with two conflicting interpretations.
2. MISSING ACs — behavior implied but never specified (error paths, empty
states, limits, permissions, concurrency).
3. CONTRADICTIONS — ACs that conflict with each other or with another story.
4. UNMEASURABLE CLAIMS — outcomes with no observable pass/fail signal.
5. TESTABILITY SCORE — 1-5 with one-line justification.
Do NOT propose solutions. Do NOT invent requirements. Questions only.
[paste stories.md]
Verify each finding against the source. Models over-flag: some "ambiguities" are settled by team convention or a linked design. Mark each finding valid, known-context (settled, but worth writing down), or noise. A useful pass looks like:
PROJ-214 "Notify users of failed payments"
AMBIGUOUS: "notify" — in-app banner or email? "users" — the payer only,
or all org admins?
MISSING AC: retry behavior; what happens if notification itself fails.
CONTRADICTION: AC-3 says "immediately"; PROJ-198 batches payment events
at 15-minute intervals.
SCORE: 2/5 — no observable definition of delivered notification.
That contradiction against a different story is the class of catch humans miss and models excel at — verify it by opening PROJ-198.
Convert valid findings into refinement questions. Rephrase each as a neutral question ("Should admins also be notified, or only the payer?") — the model can draft these, but you own the tone. Attach them as Jira comments on each story before the meeting.
Close the loop in refinement. Every question gets an answer written back into the ACs — an answer that lives only in meeting memory reproduces the original problem. Re-run the critique on rewritten stories if the edits were substantial.
Run the critique before estimation, not after — ambiguity discovered post-commitment turns into scope pressure on you, and testability questions asked after the sprint starts read as obstruction instead of diligence.
ai-draft for your triage. Keep the human-verdict step; never auto-post to the product owner.Keep a running file of the ambiguous terms your product actually uses ("active user", "processed", "synced") with their agreed definitions, and paste it into every critique — the model stops flagging settled vocabulary and starts finding the new ambiguities hiding behind it.