Defining What “Done” Means: Letting AI Spell Out Every Condition So You Can Decide Which Ones Count
You’ve got a feature to build, and you want to hand it to AI cleanly. Say you’re building a tool that lets neighborhood tutoring co-ops match volunteers with kids who need help. The feature is “let a parent request a tutor for their kid.” Simple enough. So you tell your AI assistant to build it, and a minute later it’s there: a form, a submit button, a request saved to the database, a little “thanks, we’ll be in touch” message. You click through, it works, you mark the feature done and move on to the next one.
And “done” is exactly the word doing the damage. Because what you actually built is the sunny-day version, the one where the parent fills in every field correctly, the network behaves, and a tutor is available. You never said what “done” meant, so AI picked the easiest possible definition: the code runs and the happy path works. It didn’t ask what happens when no tutor is available, or when the same parent submits twice, or when the kid’s grade level is left blank. You didn’t decide those things weren’t part of done. You just never decided they were, and now they’re quietly not built, waiting to surface as “bugs” that were never actually bugs. They were just parts of the job nobody defined as part of the job.
What this job actually is
Defining “done” is two jobs wearing one word. The first is laying out the conditions: for this feature to really be finished, what all has to be true? Not just the happy path, but the empty states, the error states, the edge cases, the “what if two people do this at once,” the “what if they leave this blank,” the “what if it works but takes eight seconds.” That’s a breadth-and-completeness problem, and AI is genuinely good at it. It can generate a long, thorough list of every condition a feature like yours might need to satisfy, including the ones you’d forget precisely because they’re annoying to think about.
The second job is deciding which of those conditions actually count as done for your version, right now. Because that long list AI hands you is not a definition of done; it’s a menu of everything done could possibly mean. Some of those conditions are load-bearing (if this one isn’t handled, the feature is broken and you’ll regret shipping it). Some are genuinely nice but can wait. And a few are gold-plating, the kind of polish that would eat a week and matter to almost nobody. Sorting those apart is a judgment call about what your feature actually has to guarantee to be trustworthy, and it depends on what your users are counting on and what a failure would cost them.
Here’s the distinction that matters: AI can generate every condition a feature might need to satisfy, but deciding which ones count as done is yours. A longer checklist is not a clearer finish line. The value of defining done comes from drawing a line you’ll actually stand behind, one that catches the failures that would hurt and lets the trivial ones go, and that line is a decision about your specific users and your specific stakes. AI can list conditions all day and still not know which ones are the difference between a feature people trust and a feature that embarrasses you the first week, because that difference lives in what your product promises, and AI doesn’t know that unless you tell it.
How to delegate the expansion
So lean on AI for the part it’s good at, which is thinking of everything. The careless version is “build this feature,” which quietly lets AI define done as “it runs.” The good version splits the work: first get the full landscape of conditions, then you decide the line, and only then build against it.
Describe the feature and ask AI to lay out every condition that would have to be true for it to count as genuinely finished, grouped by kind. Ask for the happy path, sure, but push it into the corners: what should happen when a required field is empty, when the same action happens twice, when there’s nothing to show, when an outside service is slow or down, when two users collide, when the input is technically valid but weird. Ask it to include accessibility conditions, the “what does a screen reader do here” ones people skip. Ask it to flag conditions that are commonly forgotten in features like this. The goal is a list that’s almost uncomfortably complete, because you can only draw a sharp line if you can see everything you might be drawing it around.
Tell AI about your feature and your users so the conditions are relevant, but stop short of asking it to prioritize. The moment you ask “which of these do I really need,” you’ve handed off the line. Keep the ask on expansion: show me everything that could count as done, organized, so I can decide what actually does. What you want back is the full menu of finish lines, not AI’s guess at where yours should be.
The judgment you keep
Where the finish line goes is the call, and it’s yours because it turns on something AI can’t see: which conditions your feature has to guarantee to be worth trusting, and which ones are polish you can skip for now.
This is hard because almost every condition on the list is a real, reasonable thing a feature could handle. Cutting the obviously pointless ones is easy. The judgment is in the middle, where a condition is genuinely good and you still have to decide it’s not part of done yet, because it doesn’t protect the thing this feature actually has to protect. For the tutoring app, “what happens when no tutor is available” might be dead center of done, because a parent who submits a request into silence and hears nothing has hit the exact failure that makes them give up on you. Meanwhile “let the parent edit their request after submitting” might be a perfectly nice condition that has nothing to do with whether the core promise holds, and shipping without it costs you little. One of those belongs inside the line and one belongs outside it, and only you know which is which because only you know what the feature is really promising.
AI can’t make this call because it can’t feel the weight of each condition in your product. It can tell you the empty-tutor case exists; it can’t tell you that case is the whole ballgame while the edit-request case is a shrug, because that weighing depends on what your users are trusting this feature to do and what breaks their trust when it fails. Draw the line too loose and you ship something that falls apart the first time reality touches it, then spend weeks fixing “bugs” that were really just undefined scope. Draw it too tight and you gold-plate a feature nobody needed perfected while the rest of the app waits. The line is where the feature gets its actual shape, and getting it right is the difference between “done” meaning something and “done” meaning “it ran once on my machine.”
Before you ship this job
Here’s what good delegation looks like, and the line it can’t cross.
The sample prompt. Something real you might send:
I’m building MatchUp, an app where a neighborhood tutoring co-op connects volunteer tutors with parents who need help for their kids. My main user is someone like Renée, a parent of two who wants to request a tutor for her eight-year-old in about a minute, from her phone, and actually hear back. The feature I’m building is “let a parent submit a request for a tutor.” Before I build anything, I want the full picture of what “done” could mean for this feature. Lay out every condition that would have to be true for this feature to count as genuinely finished, grouped by type: the happy path, empty and missing-input cases, duplicate or repeated submissions, error and outage cases (what if saving fails, what if a notification service is down), collision cases (two parents, one tutor), empty states (no tutors available at all), performance conditions, and accessibility conditions. Push into the corners and include the conditions people commonly forget for a feature like this. Don’t rank them or tell me which ones matter most; I want the complete menu so I can decide where my finish line goes.
Use this and you get a real map of everything done could mean. Copy it as-is and you’ve let me draw MatchUp’s finish line instead of yours. Renée’s version of “done” is shaped by what she can’t afford to have fail (a request that vanishes into silence), and the menu only means something once you’re the one deciding which conditions clear the bar and which wait.
The part you can’t hand off is the line itself: which conditions your feature must satisfy to count as done right now, sorted out from the ones that are genuinely nice but can wait, judged against what your feature actually has to guarantee for your users to trust it.
How to check AI did its part: scan the list for the ugly cases, not the clean one, and specifically look for the failures that happen when something goes wrong rather than right (nothing to show, input left blank, the same thing submitted twice, an outside service down). If AI’s list is mostly happy-path steps dressed up as conditions and you can’t find the “what happens when this fails” cases, the expansion isn’t wide enough to draw a real line from, and you send it back and ask specifically for the failure and empty states. A “definition of done” made entirely of things going right is just the happy path with a checkbox next to it, and it’ll let you ship exactly the gaps you were trying to catch.
What you get for doing it this way
Go back to that feature you marked done after clicking through the sunny-day path once. The difference between letting AI’s easiest definition of done become yours and setting the line yourself is the difference between a feature that works in the demo and one that holds up the first time a real parent leaves a field blank or submits into an empty roster. When you let AI spell out every condition and you decide which ones count, you ship features that are actually finished, in the sense that matters: they handle the failures you decided they had to, and you’re not surprised by “bugs” that were really just scope you never named.
AI can lay out every condition a feature could possibly satisfy. Which of them your version has to satisfy to be worth trusting was always going to be your call, because only you know what your feature is really promising and what breaks it. That’s the job: let AI make the list of finish lines long, then have the judgment to pick the one you’ll actually stand behind.
