"As a user, I want AI recommendations, so that I discover relevant content" describes a feature, not a testable requirement — it hides at least six separable decisions (data availability, confidence handling, latency, fallback states, explainability, and evaluation) inside one sentence. Decomposing it means splitting that sentence into a small set of independently testable stories, each with its own acceptance criteria.
Quick answer: Decompose an AI feature by slicing across new axes — data readiness, model confidence, latency/fallback behavior, explainability, and evaluation — not just user role or screen. Write acceptance criteria for each slice separately, including the "AI gets it wrong" path, before anyone estimates a single point.
Why "As a User, I Want AI Recommendations" Isn't a User Story
The Connextra format — "As a <role>, I want <goal>, so that <benefit>" — was built for deterministic features: a button either works or it doesn't. AI features are probabilistic, data-dependent, and variable in confidence, so one Connextra sentence quietly bundles multiple decisions an engineer can't build from, let alone test.
The format itself isn't the problem. It originated at Connextra, a UK ad-tech company, in the early 2000s, and it has held up for two decades of ordinary CRUD features precisely because those features have one behavior to specify. An AI-powered feature has several, and the Connextra sentence only names the best case.
Here's what "As a user, I want AI recommendations" leaves for someone else to guess:
- Data availability — what happens for a brand-new user with no interaction history?
- Confidence threshold — how confident does the model need to be before a recommendation surfaces at all?
- Latency budget — what's the maximum wait before the UI shows something else?
- Explainability — does the user see why something was recommended?
- Override and feedback — can the user dismiss, downvote, or turn the feature off?
- Evaluation criteria — how does the team know the recommendations are actually good?
None of those are edge cases you patch in later. They're separate pieces of scope that an engineer estimating "As a user, I want AI recommendations" has no way to size, because the sentence doesn't say which of the six they're building. If you want the fuller discipline this sits inside — problem framing, requirements, and acceptance criteria as one connected system — a PRD-writing masterclass for the AI era covers the surrounding practice this article zooms in on.
The Anatomy of a Decomposed AI User Story
A decomposed AI story separates "the model works as intended" from "the model hasn't got enough signal yet" into independently shippable, independently testable stories — instead of one story that silently assumes the happy path is the only path. Each sub-story gets its own owner, its own acceptance criteria, and its own place in the backlog.
Take the single line "As a user, I want AI recommendations, so that I discover relevant content" and run it through that lens. It doesn't become one refined story — it becomes a small family of them:
| Sub-story | Slicing axis | Sample acceptance signal |
|---|---|---|
| Show ranked recommendations for a user with rich interaction history | Model confidence (high) | Top 5 items shown, each above the confidence floor |
| Show a fallback module for a first-session user with no history | Data availability (cold start) | Popularity- or catalog-based fallback renders instead of a blank panel |
| Show a "why this" explanation on tap/hover | Explainability | Explanation references a real signal (e.g., "because you viewed X") |
| Degrade gracefully when the model call exceeds budget | Latency | Cached or static fallback renders within the stated timeout |
| Let a user dismiss or downvote a recommendation | Override / feedback | Dismissal is persisted and excluded from future ranking |
| Suppress recommendations that fail a safety/policy check | Guardrails | Flagged items never reach the ranking output |
| Log ranking inputs and outputs for offline evaluation | Evaluation | Every served recommendation is traceable to model version and inputs |
Each row is small enough to estimate, build, and demo on its own — which is the entire point. A sub-story that can't be demoed independently (say, "handle low confidence" bundled silently inside the happy-path story) is a sign the decomposition isn't finished yet.
Acceptance Criteria for AI Features: A Working Template
Acceptance criteria for an AI story need to specify behavior across the states a model can actually be in — confident, unconfident, silent, wrong — not just the state where everything worked. Given/When/Then is still the right shape; the states you write it against just multiply.
Here's a working fragment for one sub-story — "show ranked recommendations for a returning user" — written the way it should land in a spec, not described in prose:
| Scenario | Given | When | Then |
|---|---|---|---|
| Happy path | User has 10+ tracked interactions | Recommendation panel loads | 5 items render, each with confidence ≥ 0.6 |
| Low confidence | User has 2–9 interactions | Recommendation panel loads | Panel shows a "still learning your taste" fallback module, not raw low-confidence items |
| No data | User has 0 interactions | Recommendation panel loads | Popularity-based fallback renders; no model call is made |
| Latency exceeded | Model response exceeds 800 ms | Recommendation panel loads | Cached last-good results render; a background refresh updates silently on success |
| Dismissal | User dismisses an item | Dismissal is confirmed | Item is excluded from this user's next 30 days of ranking |
| Explanation requested | User hovers/taps "why this" | Explanation is requested | A single real signal is shown (e.g., viewed, purchased, similar-item) — never a generic string |
Two things make this template do real work instead of decorative work. First, every row names a measurable threshold (0.6, 800 ms, 30 days) instead of a qualitative word like "fast" or "relevant" — vague acceptance criteria are the most common reason AI stories bounce back from QA. Second, the "no data" and "latency exceeded" rows exist at all — most first-draft AI stories only specify the happy path and treat everything else as a bug to be discovered in staging.
The data-availability row deserves its own attention before a single ticket gets written: what counts as "enough" interaction history, where that data lives, and how fresh it needs to be are data-modeling questions, not story-writing ones. A PM's guide to reviewing a data model is worth working through before you commit to a confidence threshold you can't actually compute from your schema.
INVEST Still Applies — But You Need New Slicing Axes
Bill Wake's INVEST criteria — Independent, Negotiable, Valuable, Estimable, Small, Testable, first published in 2003 and popularized alongside Mike Cohn's User Stories Applied — are still the right bar for a well-formed story. What changes for AI features is which axis you slice along to hit "Small" and "Testable" in the first place.
Classic vertical slicing, the kind taught in Alistair Cockburn's Elephant Carpaccio exercise, cuts by user-visible functionality: instead of "build the backend" then "build the frontend," you slice a thin end-to-end path a user can actually exercise. That instinct is correct and still applies — but for AI features it needs company. Three additional axes matter:
- Confidence tier — a story for "model is highly confident" is genuinely different work from "model is uncertain," and bundling them hides half the scope.
- Data readiness — cold-start, sparse-data, and rich-data users often need materially different logic, not just different copy.
- Human-in-the-loop level — fully automated, suggest-and-confirm, and human-override-required are three different products, even for the "same" feature.
Two external references are worth keeping on your desk while you slice. Microsoft Research's Guidelines for Human-AI Interaction (Amershi et al., CHI 2019) lays out 18 design guidelines — including "make clear what the system can do" and "support efficient dismissal" — that map almost one-to-one onto sub-stories your decomposition should include. Google's People + AI Guidebook, published by the PAIR team, organizes similar guidance around onboarding, feedback, and error patterns specifically for probabilistic systems.
Neither of those is a template you copy-paste. They're checklists for the axis you might have missed — the same role a UX pattern library plays once you're past "which sub-stories exist" and into "what does each state actually look like." A PM's guide to responsive wireframing is the natural next stop once you've named a low-confidence or empty state in acceptance criteria and need to actually design it, rather than leave it as a sentence engineers interpret differently.
A Decomposition Walkthrough: From One Line to a Sprint-Ready Backlog
Decomposition is a repeatable procedure, not a one-time creative act — the same six-step pass works whether the one-liner is "AI recommendations," "AI-generated summaries," or "AI-assisted search." Run it once per feature stub, before anyone estimates a single point or opens a ticket, and the ambiguity gets resolved on paper instead of in a stand-up three sprints later.
- Write the one-liner exactly as a stakeholder said it. Don't refine it yet — you need the ambiguity visible to cut through it.
- List every state the model can be in for this feature: confident, unconfident, no data, wrong, unavailable, slow. Most features have four to six.
- Pair each state with a user-visible behavior. "Unconfident" isn't a backend flag — it's a specific fallback UI someone has to design and build.
- Add the cross-cutting concerns that apply regardless of state: explainability, override/feedback, logging for evaluation, and any policy/safety check.
- Slice each item to one sprint or less. If a sub-story still needs a "part 1 / part 2," it's bundling two states — split it again.
- Write acceptance criteria per sub-story before it enters the backlog, using the measurable-threshold discipline from the template above — not after a developer asks "wait, what should happen here?"
Applied to "AI recommendations," that procedure produces the seven-row table from the Anatomy section — a backlog a team can actually plan a sprint against, instead of one oversized story that "AI recommendations" turns into three weeks in when someone finally asks what happens to a user with no history.
The output isn't a diagram — it's spec text. A finished sub-story reads like this, not like a paragraph of prose:
Story: Show fallback module for first-session users (cold start)
As a first-time visitor with no interaction history,
I want to see a useful starting point instead of a blank or broken panel,
so that I don't bounce before the recommender has any signal to work with.
Acceptance criteria:
- Given 0 tracked interactions, when the panel loads, then a popularity-based
fallback renders (no model call is made).
- Given the fallback renders, when the user interacts with 3+ items, then
personalized recommendations replace the fallback on next load.
- Given the fallback renders, then no "recommended for you" language appears
(it isn't true yet).
Open question: does "popularity" mean global, category-level, or
geography-adjusted? Owner: [PM]. Needed by: sprint planning.
Notice the open question at the bottom. That's not a gap in the example — it's the honest state of most AI sub-stories the day they're written, and pretending otherwise is how "As a user, I want AI recommendations" got written in the first place.
Where This Breaks Down: Non-Determinism, Drift, and Evaluation Debt
Decomposition isn't a one-time task, because the model underneath an AI story keeps changing after it ships — a retrain, a new data source, or a threshold tweak can silently invalidate criteria that were correct at launch. The Standish Group's long-running CHAOS research has for years named incomplete or changing requirements among the top reasons software projects struggle; AI adds a faster-moving version of that same risk.
Three forms of drift are worth planning for explicitly:
- Threshold drift — a confidence cutoff tuned against one model version may be miscalibrated against the next one, silently changing which sub-story a given user falls into.
- Evaluation debt — the offline metrics (precision, recall, or a proxy like click-through) you accepted at launch need periodic re-validation, or "still meets the bar" quietly becomes untrue.
- Scope creep in the fallback path — cold-start and low-confidence stories tend to get the least attention post-launch, and accumulate the most undocumented special-casing.
None of that is solvable by writing a better story once. It's solvable by treating acceptance criteria as living artifacts, revisited on a cadence, the same way you'd revisit any requirement tied to a system that keeps moving.
That discipline — keeping a PRD living and always current rather than a document written once at kickoff and never reopened — matters more for AI features than almost anywhere else in the product. The ground truth underneath the spec is the part most likely to change without anyone telling you.
Where Prodinja fits
This is the specific gap Prodinja's Spec Studio is built around: it maintains a living PRD, so requirements, acceptance criteria, and open questions for something like the seven sub-stories above stay in one structured document you can edit and version as the model, the data, or the thresholds change — instead of the decomposition living in a doc that's accurate the week it's written and stale two model updates later. It's a place to keep the spec current, not a substitute for doing the decomposition work above.
Key Takeaways
- "As a user, I want AI recommendations" bundles six or more decisions — data availability, confidence, latency, explainability, override, and evaluation — into one sentence nobody can actually estimate.
- Decompose by state, not just by role or screen. Confident, unconfident, no-data, and slow/unavailable are usually four separate stories, each independently testable.
- Acceptance criteria need measurable thresholds (a confidence score, a latency budget, a retention window) — qualitative words like "relevant" or "fast" don't survive contact with QA.
INVESTstill applies, but "Small" and "Testable" now require slicing along confidence tier, data readiness, and human-in-the-loop level, not just user-visible functionality.- Cold-start and low-confidence paths are not edge cases — they're the default experience for a meaningful share of users and deserve their own sub-story and design pass.
- AI acceptance criteria are living artifacts. A model update, threshold tweak, or new data source can invalidate them without anyone editing the spec — revisit on a cadence, don't set once.
- Real frameworks exist for the axes you might miss — Microsoft's Guidelines for Human-AI Interaction and Google's People + AI Guidebook are worth reading once, not reinventing per feature.
Frequently Asked Questions
What's wrong with "As a user, I want AI recommendations, so that I discover relevant content"?
It describes the intent of a feature, not a buildable unit of work — it hides at least six separate decisions (data availability, confidence handling, latency, explainability, override, and evaluation) that an engineer can't estimate or test from the sentence alone. Each of those needs to become its own story with its own acceptance criteria.
How do you write acceptance criteria for an AI feature?
Write Given/When/Then criteria for every state the model can realistically be in — confident, unconfident, no data, slow, and wrong — not just the happy path, and attach a measurable threshold to each one (a confidence score, a latency limit, a time window). A criterion that says "recommendations should be relevant" isn't testable; one that says "confidence ≥ 0.6" is.
Does INVEST still apply to AI user stories?
Yes — Bill Wake's INVEST criteria (Independent, Negotiable, Valuable, Estimable, Small, Testable) are still the right bar for a well-formed story. What changes is the slicing axis: AI stories usually need to slice by confidence tier and data readiness in addition to user-visible functionality to actually hit "Small" and "Testable."
How is a modern AI user story different from a traditional Connextra story?
A traditional Connextra story ("As a <role>, I want <goal>, so that <benefit>") assumes one deterministic behavior. A modern AI story keeps that same sentence for the product intent, but decomposes underneath it into multiple sub-stories — one per model state — each carrying its own acceptance criteria, because a probabilistic system has more than one behavior to specify.
How often should you revisit AI acceptance criteria after launch?
Revisit them whenever the model, the underlying data, or a tuned threshold changes — not on a fixed calendar alone, since drift is triggered by those events rather than time. Treat the acceptance criteria as a living part of the spec you version, rather than a document you finalize once at launch and never reopen.