Back to Explore
GuideVibeFix 编辑部Updated Oct 24, 2026

Set Acceptance Criteria for Your AI: Definition of Done for Vibe Projects

The AI's "done" is rarely your "done". Learn to write five-element DoD task cards, use cheat sheets for four task types, an AI self-review prompt, and a 10-minute human acceptance pass — turning rework from mystery into checklist.

A wall of task boards covered in sticky notes

A boundary note so you read the right guide: this site already has a PRD writing for AI agents guide (what to build and why), a demo-to-production launch checklist (the gate at release time), an AI debugging methodology guide (what to do when things break), and spec-driven development guides (how to build). This one is none of those — it covers one thing: writing the Definition of Done (DoD) — acceptance criteria for "finished" — before the task starts, so the AI works against a checklist instead of you guessing afterward whether it's actually done.

The AI's "done" is not your "done"

Three scenes every vibe coder knows:

  • You ask the AI to "add CSV export". It says done. You click it — Chinese characters come out garbled. It only tested with English data.
  • You ask it to "fix the mobile nav overlap". Done. You switch to dark mode — the overlap is back. It never tested theme switching.
  • You ask it to "wire up Stripe". Done. Works locally; in production the webhook signature check was never configured and every payment callback gets rejected. To the AI, "sandbox works" meant finished.

The problem isn't laziness. You and the AI never agreed on what "done" means — and nobody wrote it down. The AI's "done" = code written, no errors. Your "done" = edge cases tested, docs updated, nothing else broken. A DoD translates your "done" into a checklist the AI can execute, placed in front of it before the task starts.

The five-element DoD template

Every task card's DoD has these five blocks — one more is clutter, one fewer is a future incident:

1. Functional acceptance (must be demoable). Write in "the user can…" form; every item verifiable by hand. Bad: "improve export". Good: "clicking Export downloads a CSV with 1,000 rows of Chinese data that opens in Excel without garbling".

2. Boundaries and exceptions. Name the 2–3 likeliest failure edges: empty data, overlong input, network failure, insufficient permissions. The AI skips boundary cases mostly because you never named them.

3. Test evidence. Demand proof of done: which test command ran, what the output was; UI tasks need screenshots or recordings. A "done" with no evidence counts as not done.

4. Code hygiene. Three hard lines: no new lint/type errors; no new global state or hardcoded secrets; changes stay inside the files/modules the task names (the AI loves to "helpfully" touch unrelated files).

5. Docs and observability. User-visible behavior changes update the relevant doc (README, changelog, or help page — one is enough); add logging/instrumentation on critical flows for future debugging.

The template, ready to copy:

## DoD (Definition of Done)
- [ ] Functional acceptance:
  - [ ] (the user can…, verifiable by hand)
  - [ ] (the user can…, verifiable by hand)
- [ ] Boundaries & exceptions: (2–3 named, with expected behavior)
- [ ] Test evidence: (test command + output, or screenshots/recording)
- [ ] Code hygiene: no new lint/type errors; changes scoped to (module)
- [ ] Docs & observability: (which doc updated; which log/metric added)

Bad vs good task card: same task, two writings

Task: add a "copy code" button to the blog.

Bad (AI freestyle):

Add a copy button to code blocks on article pages.

You get a clickable button. Then: long blocks copy incompletely (untested), no success feedback (users don't know it worked), the button covers code on mobile (never looked).

Good (DoD version):

Add a copy button to code blocks on article pages.
## DoD
- [ ] Functional acceptance:
  - [ ] Clicking copies a 500-line block to the clipboard in full
  - [ ] Button flips to "Copied ✓" for 2s after success, then restores
- [ ] Boundaries & exceptions: clipboard API denied (e.g. non-HTTPS) →
      fall back to selecting the code and prompting manual copy
- [ ] Test evidence: screen recordings on desktop Chrome + mobile Safari
- [ ] Code hygiene: no new lint errors; only the code-block component changes
- [ ] Docs & observability: one line in README's writing-guide section

The difference isn't length — it's that the good version turns "surely the AI will think of that" into "the AI must do that". The biggest illusion in vibe coding is "it's so obvious it'll handle it". It won't, unless you write it down.

DoD cheat sheet for four task types

Different tasks stress different DoD elements. Keep this table next to your task cards:

Task typeDoD emphasisThe one line you must write
UI / frontendMulti-device, multi-state verificationOne screenshot each on desktop + phone; eyeball dark and light mode
Backend APIContract and error casescurl examples + actual output for success / bad params / forbidden
Data migrationRollbackabilityWrite the rollback steps and rehearse them; row-count before and after
Bug fixReproduce → fix → regressRepro steps first, verify with the same steps after, re-run related old tests

The migration row deserves emphasis: schema migration incidents are endemic in vibe projects precisely because "rollback" never appears in the DoD. Making the AI write rollback steps before touching anything forces it to think through "how do I undo this" first.

Wire it into your workflow: the DoD loop

A DoD only works if it lives inside every collaboration with the AI. The full loop:

Definition of Done loop flowchart: write the DoD task card, feed it to the AI and have it restate understanding, AI codes against the DoD, AI self-checks against the DoD with evidence, human does a 10-minute acceptance pass; failures bounce back with the unmet DoD item named

Each step in practice:

  • 1. Write the DoD: append the five-element template to the task description. Smaller tasks need it more — a small task's DoD is three lines and takes a minute.
  • 2. Feed it to the AI: paste the DoD into the prompt plus one sentence: "Before starting, restate the DoD in your own words to confirm understanding." That restatement catches 80% of misreadings; when the AI restates wrong you correct it on the spot — far cheaper than rework after 500 lines.
  • 3. AI codes: add one iron rule — "when you hit something the DoD doesn't cover, stop and ask me; don't guess." The AI's biggest flaw isn't speed, it's confident wrong guesses.
  • 4. AI self-checks: the AI ticks the DoD item by item, each with evidence (test output, screenshots, changed-file list). See the self-review prompt below.
  • 5. Human acceptance: you spend 10 minutes hand-verifying each item. Pass = done.

To make it the default, put the template and the "restate" requirement in AGENTS.md:

## Task completion standard (DoD)
Every task starts with a DoD (functional acceptance / boundaries &
exceptions / test evidence / code hygiene / docs & observability),
written at the end of the task description. Before coding, restate the
DoD in your own words; when you hit anything the DoD doesn't cover,
stop and ask; after finishing, self-check against the DoD item by item
with evidence — items without evidence count as incomplete.

AI self-review: make it check its own boxes first

The AI says "all done" — don't test yet. Hand it this self-review prompt first:

Self-review against this task's DoD, in this format:
- [x] / [ ] item text
  Evidence: (test command + key output / screenshot / file path + line)
  Why not: (if unchecked, say exactly why)
Be honest: mark uncertain items [ ] and explain — never guess.

"Never guess" is the whole trick. AI has a strong tell-good-news bias; without an explicit honesty requirement it marks "probably fine" as [x]. An [ ] in the report isn't bad news — it pinpoints rework to the item level, and fixing becomes fast.

Advanced move: have the AI save reports to docs/dod-reports/<task>.md. After a few dozen, you own a real quality archive for the project: which modules keep skipping boundaries, which task types rework most — all visible at a glance.

DoD vs PRD vs user stories: who does what

Common question: if I have a PRD, why do I need a DoD? The division of labor:

  • PRD answers "what and why". For humans and planning; one PRD covers a feature or a release.
  • User stories answer "who, in what situation, wants what". A format for expressing requirements.
  • DoD answers "how finished is finished". For execution; one DoD governs one task (typically half a day to two days of work).

The chain: PRD splits into tasks → each task gets a DoD → AI executes against the DoD → humans accept against the DoD. The PRD guarantees "the right thing"; the DoD guarantees "the thing right". This site's PRD writing for AI agents guide covers the first half; this guide covers the second — together they're the complete AI collaboration chain.

Full walkthrough: one real task, end to end

A real small task to demo the loop: add an RSS subscribe button to the changelog page.

Step 1: task card + DoD (you, 5 min).

Task: add an RSS subscribe button at the top-right of /changelog;
clicking copies the RSS link.
## DoD
- [ ] Functional acceptance:
  - [ ] Clicking copies the RSS link; button flips to "Copied"
  - [ ] Opening the RSS link in a browser shows valid XML (latest 20 entries)
- [ ] Boundaries & exceptions: empty feed → button disabled with "No content
      yet"; clipboard API denied → fall back to selecting the link text
- [ ] Test evidence: one screenshot each on desktop + phone; curl the feed,
      paste the first 5 lines
- [ ] Code hygiene: no new lint errors; only changelog files touched
- [ ] Docs & observability: one line about RSS in README

Step 2: feed the AI + restatement (you + AI, 2 min). The prompt includes "restate the DoD in your own words before starting". The AI restates "…button disabled when the feed is empty…" — you notice it dropped the clipboard-denied fallback and add it back. Thirty seconds of correction saves a full rework round.

Step 3: AI codes. It implements against the DoD and stops to ask: "absolute or relative URL for the feed?" You answer "absolute", it continues. That's the "ask when unsure" rule paying off.

Step 4: AI self-reviews (3 min). Six [x] items, each with evidence — two screenshots, curl output, changed-file list. You scan it and notice the "phone screenshot" is a desktop browser narrowed down, not a real phone. Now you know to tap it yourself on a phone during acceptance.

Step 5: your acceptance (10 min). The loop: report has a question mark → verify on a real phone → poke one boundary (empty the feed, check the disabled state) → review the diff. All pass — merge, archive the card.

You invested under 20 minutes for "right the first time". The no-DoD version: the AI says done, you click around casually, three days later a user reports RSS copy fails on phones, and you open another rework round — more total time, not less.

Template library: four DoDs to copy

Store in .ai-templates/dod/; new tasks copy one and change two lines:

UI component task:

- [ ] Acceptance: screenshots on desktop Chrome + mobile Safari; dark/light eyeballed
- [ ] Boundaries: empty data, overlong text, load-failure states all have UI
- [ ] Evidence: 2 screenshots; 1 interaction recording (if animated)
- [ ] Hygiene: no new lint/type errors; colors via design-system tokens, never hardcoded
- [ ] Docs: 3-line usage note in Storybook or README

Backend API task:

- [ ] Acceptance: curl + actual output for success / bad params / forbidden
- [ ] Boundaries: missing required params, illegal enum values, duplicate
      concurrent requests (idempotency)
- [ ] Evidence: new/updated automated tests + run output; curl session log
- [ ] Hygiene: no new lint/type errors; error codes from the project table, none invented
- [ ] Docs: API docs updated; key branches log with request id

Data migration task:

- [ ] Acceptance: full run on staging; row counts match before/after
- [ ] Boundaries: rollback steps written AND rehearsed; alert path on failure
- [ ] Evidence: staging migration log; reconciliation SQL + results; rollback rehearsal log
- [ ] Hygiene: script is re-runnable (failed reruns create no dirty data);
      double-check before production
- [ ] Docs: migration recorded in ops docs; progress logging during run

Bug fix task:

- [ ] Acceptance: repro steps documented first, verified with the same steps after
- [ ] Boundaries: regress sibling scenarios (fixed form A's validation → test form B too)
- [ ] Evidence: repro doc; before/after screenshots; related old tests re-run
- [ ] Hygiene: no new lint/type errors; fixed the root cause, not the symptom
      (one-sentence root-cause statement required)
- [ ] Docs: root cause filed in the bug archive; add logging where it was missing

That root-cause sentence is the soul of bug-fix DoDs: it forces the AI to prove it understood the bug instead of just silencing the error.

Your 10-minute acceptance pass

AI self-review done — your turn. Ten minutes, in this order:

  1. Read the report (2 min). Any [ ] items → bounce it back immediately, no further testing needed.
  2. Run the main flow (3 min). Hand-verify each acceptance item. Don't trust screenshots alone — they can be stale.
  3. Poke one boundary (2 min). Pick the boundary you trust least and try it yourself. Empty data, overlong input, offline — dealer's choice.
  4. Read the diff (3 min). Scan git diff: files touched that shouldn't be? Hardcoded secrets, URLs, magic numbers? Someone else's code deleted?

Step 4 is the one vibe coders skip most, yet "helpful" AI file-touching is the top source of rework and production incidents. Build the habit: any file outside the task description gets a "why".

The solo minimal version + how you know it's working

If five elements feel heavy, start with the three-line minimal DoD — one minute to write:

## DoD
- [ ] Hand-verifiable: (one line: what the user can do)
- [ ] Boundary: (the likeliest failure + expected behavior)
- [ ] Evidence: (screenshot / test output / curl — pick one)

The minimal version captures 80% of the value: verifiable, boundaries considered, evidence demanded. Graduate to the full five elements once you're hooked.

How do you know it's working? Watch two numbers: rework rate (share of tasks reopened within a week for "not actually done") and acceptance time (your average minutes hand-verifying a task). Teams that adopt DoD typically see rework halved within two weeks — because "not done" gets caught at AI self-review and never reaches you. Acceptance time drops from "30 minutes of aimless clicking" to "10 minutes of ticking boxes". No precise tracking needed; you'll feel it.

Five common pitfalls

Pitfall 1: a DoD longer than the code. A DoD is a checklist, not an essay. A small task with a 10+ line DoD means the task needs splitting, not a longer DoD.

Pitfall 2: writing the DoD but not using it at acceptance. The most common way to kill it: the DoD gets written, then acceptance is two casual clicks. Keep the ritual: open the DoD, tick each box, merge only when all ticked.

Pitfall 3: unmeasurable words. "Good performance", "smooth experience" can't be verified — which means they're unwritten. Make them measurable: "no frame drops scrolling 1,000 rows", "first paint < 2s on simulated 4G".

Pitfall 4: writing every DoD from scratch. Keep templates for the four common task types (UI, API, migration, bug fix); new tasks copy one and change two lines. Seconds, not minutes.

Pitfall 5: treating DoD as AI-only. Code you hand-write (those lines you tweak after generation) goes through the DoD too. One standard for humans and AI alike, or nobody will take it seriously for long.

Honest closing: a DoD can't guarantee the AI gets it right first try — but it guarantees failures are legible and fixes are precise. Rework conversations change from "this is wrong and that's wrong too" to "DoD item 3 failed — where's the evidence?" For people who build with AI, that's the line between luck and engineering. Try it on your next task: five minutes writing the DoD, have the AI restate, self-check, and attach evidence — "done" will finally mean the same thing to both of you.

Views 3Comments 0

Comments (0)

ME
0/1000
Loading comments...
Browse projectsPublish your project

Related articles

Two developers reviewing code together, open-source collaboration photo
Guide
After the Stars: Operating Your Vibe Project's Open-Source Repo

Every star is a future issue. This guide is the solo maintainer's operations system for life after release: issue triage pipelines, PR review cadence, the automation four-piece, contributor ladders, governance docs, graceful rejections, and dignified handover or archival.

Team CollaborationIndie DevelopmentAI Coding
A developer writing software documentation, desk close-up photo
Guide
Docs Are Your Product's Second Face: Developer Documentation for Vibe Projects

Landing page gets them in; docs decide whether they stay. This guide covers the full playbook for vibe-project developer docs: the 5-minute Quickstart test, the Divio four quadrants, API reference that machines generate, docs-as-code discipline, navigation, metrics, i18n, and an honest assessment of llms.txt.

Developer WorkflowTool TipsDesign Experience
A developer reviewing paper bills with a calculator at a desk beside a laptop
Guide
Don't Let AI Coding Tools Eat Your Margin: A Vibe Developer's Dev-Side AI Bill Playbook

Dev-side AI spend playbook: Cursor / Claude Code / Copilot / Codex billing models explained in one place, a tier-selection decision table, three money-burning traps with circuit breakers, four cost-cutting moves, and a 15-minute weekly bill audit SOP. All prices verified against official pricing pages on 2026-10-23.

Tool TipsProject BuildingIndie Development