Heidelberg AICurriculum
Track 13 · Advanced
13.1

Product requirements & spec engineering

Write a PRD (product requirements document) and a spec before you build — fewer bugs, less rework

7 lessons 2026-08-06 AI-generated

1Overview

Using AI to turn a vague app idea into a precise spec before any code is written: the one-liner, user stories, the data model, screens, acceptance criteria, constraints, and a build plan you approve first. Taught as a weak → strong ladder, with a small lab-inventory app as the running example.

In this chapter you will learn how to create clear, data‑first specifications that lock scope, define roles, and establish acceptance criteria before any code is written. You will be able to produce tight version‑one scopes with out‑of‑scope lists, write screen test cases and guardrail rules, and generate incremental build plans that keep each step reviewable. By the end you will have a repeatable process for drafting user‑story specs, data models, flow diagrams, and technical constraints so that every feature is built against a single source of truth and avoids costly rewrites or scope creep.

Vibe coding fails when the AI has to guess what you meant. The fix is a spec: a short, precise blueprint you write WITH the AI before any code exists. Each technique below shows a weak ask and a strong one. Work down from Beginner to Advanced — by the end you can turn a one-line idea into a build plan you approve before a single line is written.

1.1After this chapter you can
Turn a one-line app idea into a scoped spec the AI can build from
Write user stories, a data model, and acceptance criteria
Set explicit constraints and an out-of-scope boundary for v1
Turn the spec into an ordered build plan you approve before any code
1.2How do you start the spec?

You begin by using AI to turn your vague idea into a concise one‑liner, then expand it into user stories, define the data schema, sketch screens, list out‑of‑scope items and acceptance tests, all reviewed before development.

1.3Why lock scope early?

Locking scope creates clear boundaries, explicit guardrails and test cases that prevent bugs, reduce rework and stop scope creep by ensuring every feature is built against an approved specification.

1.4The moves — weak → strong ladder
  1. 1Start with the one-liner
  2. 2Name the users and what they do
  3. 3Must-haves vs out-of-scope
  4. 4Define the data model first
  5. 5Specify the screens and flow
  6. 6Write acceptance criteria
  7. 7Pin the tech & constraints
  8. 8Turn the spec into a build plan
  9. 9Spec the guardrails (the "must never")
  10. 10Keep the spec as the source of truth
From idea to build plan write the blueprint before any code is written One-liner idea, one sentence + "ask me 5 Qs" The spec · PRD.md user stories · data model screens · acceptance criteria constraints & guardrails = source of truth Build plan ordered steps, you approve Build AI writes code, step by step change? update spec first scope v1 · what it will NOT do the "must-never" rules Catch a wrong assumption in a 10-line plan — not in a finished, broken app.

2Techniques

Learn

Beginner

Describe what you are building

Start with the one-liner Name the app, the user, and the core job in one sentence — then make the AI ask before it builds.
Instead of

Build me a lab inventory app.

Try this 💬 AI chat

I want a web app for my lab to track reagents — who has what, quantities, and expiry dates, with a low-stock alert. Users are 5 lab members; no public access. Before writing any code, ask me 5 questions to pin down the requirements.

Why it works: A one-liner plus "ask me first" turns a vague wish into a scoped conversation — the AI clarifies instead of guessing and building the wrong thing.
Name the users and what they do List the roles and their top tasks as user stories.
Instead of

It should have users.

Try this 💬 AI chat

Two roles: (1) Lab member — adds reagents, updates quantities, sees the low-stock list. (2) Lab manager — everything a member can do, plus delete entries and export to CSV. Write these as user stories: 'As a [role] I can [action] so that [reason].'

Why it works: User stories pin down exactly what each person must be able to do, so the AI builds the features that matter — not a generic CRUD app.
Must-haves vs out-of-scope Scope the first version — and say out loud what it will NOT do.
Instead of

Add every feature you can think of.

Try this 💬 AI chat

Must-have for v1: add / edit / delete reagents, low-stock alert, CSV export. Explicitly NOT in v1: barcode scanning, multi-lab support, a mobile app. Build only the must-haves first.

Why it works: An explicit out-of-scope list is what stops v1 from ballooning into a half-finished, buggy everything-app — for both you and the AI.

Intermediate

Structure the spec

Define the data model first Name the objects and their fields before any screen exists.
Instead of

Store the reagents somehow.

Try this 💬 AI chat

Define the data model before the UI. Reagent: { name, category, quantity, unit, expiry_date, location, added_by }. User: { name, role }. Show the schema as a table and flag anything ambiguous before building.

Why it works: The data model is the app's skeleton. Getting it right first prevents the painful rewrites that happen when you find a missing field after the UI is built.
Specify the screens and flow List the pages, what is on each, and how you move between them — then build one at a time.
Instead of

Make it look nice.

Try this 💬 AI chat

Screens: (1) Inventory list — searchable table, low-stock rows highlighted. (2) Add/Edit form — all reagent fields. (3) Export button. Describe the navigation between them, then build screen 1 only so I can check it before you continue.

Why it works: Naming the screens and building one at a time gives you checkpoints — instead of a 2000-line app you have to debug all at once.
Write acceptance criteria Say how you will know each feature actually works.
Instead of

Make the low-stock alert work.

Try this 💬 AI chat

Low-stock alert acceptance criteria: when quantity ≤ the reagent's threshold, the row turns amber and is counted in a 'Low stock' badge at the top. Test case: a reagent at quantity 2 with threshold 5 must show as low. Confirm it passes.

Why it works: Acceptance criteria turn "it works" into something checkable — the AI can verify against them, and so can you.

Advanced

Spec for agents & code

Pin the tech & constraints State the stack, storage, auth, and the limits the AI must stay inside.
Instead of

Use whatever you want.

Try this 💬 AI chat

Constraints: a single-page web app, data in the built-in database (no external service), simple email-link login, no payments, one framework only. If a requirement needs anything outside these, stop and ask me.

Why it works: Stating the stack and boundaries keeps the AI from pulling in heavy dependencies that break the build or quietly route your data somewhere it should not go.
Turn the spec into a build plan Make the AI produce an ordered, checkable plan — and approve it before any code.
Instead of

Now build the whole thing.

Try this 💬 AI chat

From the spec above, produce a numbered build plan: each step is one feature with its acceptance criteria, in dependency order (data model → list screen → add form → alert → export). I will approve the plan before you write any code.

Why it works: An approved plan is the contract. You catch a wrong assumption on a 10-line plan, not in a finished, broken app.
Spec the guardrails (the "must never") Write the rules the app must never break — the bugs that bite later are the unstated ones.
Instead of

Just make it secure.

Try this 💬 AI chat

Non-functional rules: a member cannot delete another member's entries; the CSV export excludes the 'added_by' email; invalid quantities (negative or non-numeric) are rejected with a clear message. Build these as explicit checks and list how each is enforced.

Why it works: The "must never" list up front is what separates a demo from something you can actually trust with real data.
Keep the spec as the source of truth Update the spec when requirements change — and re-feed it each session.
Instead of

Just keep adding features in the chat.

Try this 💬 AI chat

Treat the spec as a living document. When we change a requirement, update the spec first, then ask: 'Given the updated spec, what needs to change in the code?' Paste the current spec at the start of every new session.

Why it works: Chat history gets lost; the spec does not. Re-grounding each session in the current spec stops the code and the plan from silently drifting apart.

3Lessons 7

3.1 Generate a one‑page spec using AI’s five clarifying questions

A concise product requirements document that captures the core idea and scope before any design work.

Produce a single‑sentence description and a one‑page specification after answering five AI‑generated questions

  1. Start with a brief one‑sentence description of your lab inventory app idea
  2. Prompt the AI to ask its five clarifying questions about scope, users, data, constraints, and outcomes
  3. Answer each question directly in the chat, providing concrete details
  4. Ask the AI to compile your answers into a one‑page spec that includes the description, key user stories, and v1 exclusions
  5. Copy the generated spec into a document for later reference
  • You'll see A formatted one‑page specification that lists the app’s purpose, core features, and out‑of‑scope items ready for review
  • Takeaway Structured questioning quickly locks scope and prevents mid‑project rewrites by establishing a single source of truth early
  • Check How does answering the AI’s five clarifying questions help you lock the scope of your lab inventory app before any design work begins?

3.2 Create a shared data model table for the lab‑inventory app

A simple spreadsheet that lists each entity, its attributes, and data types.

You will produce a single source of truth that defines all data objects before any UI is designed.

  1. Open a new spreadsheet or table document.
  2. Add a column titled “Entity” and list the core objects (e.g., Item, Category, Location).
  3. Create columns for “Attribute”, “Data Type”, and “Required?” and fill in each attribute for every entity.
  4. Save the file with a clear name like lab‑inventory‑data‑model.xlsx.
  5. Share the file with your team via a shared folder or link.
  • You'll see A table where each row uniquely describes an attribute of an entity, visible to all collaborators.
  • Takeaway Defining data up front prevents mismatched expectations and reduces rework when screens are built.

3.3 Create a shared data model table before building any screens

A tabular definition of all objects, fields, and relationships that the app will use.

Produce a complete data‑model spreadsheet that can be reviewed by the whole team before UI work begins

  1. List every domain object needed for the inventory app (e.g., Sample, Reagent, Location).
  2. Add rows for each object's required fields, entering name, type, and a brief description using Insert Row.
  3. Create columns to define relationships between objects (e.g., Sample → Location is many‑to‑one) with Add Column.
  4. Include a “v1 exclusions” column to note any fields or relations omitted from the first release.
  5. Save the table as a shared document with File → Save As, then circulate it for stakeholder approval.
  • You'll see A finalized data model spreadsheet showing objects, their fields, relationships, and clearly marked v1 exclusions.
  • Takeaway Establishing the data skeleton first eliminates costly schema changes later and aligns all contributors on a common structure
  • Check What details do you record in the shared data‑model spreadsheet to ensure every team member understands objects, fields, relationships and v1 exclusions prior to building screens?

3.4 Write given‑when‑then acceptance tests for each UI screen

Behavior‑driven test scenarios written in Gherkin that describe expected behavior of a screen.

You will have executable acceptance criteria that can be used by developers and testers alike.

  1. Open a text editor and create a new file named screen‑tests.feature.
  2. For each UI screen (e.g., Add Item, View Inventory), write a Scenario title.
  3. Under the scenario, add three steps: “Given” to set up preconditions using the data model, “When” to describe the user action, and “Then” to state the expected outcome.
  4. Save the file and run a quick syntax check with any BDD tool you have (e.g., SpecFlow).
  5. Commit the feature file to your project repository.
  • You'll see A set of clear Gherkin scenarios that can be parsed by a BDD framework without errors.
  • Takeaway Structured acceptance tests bridge the gap between specifications and automated verification.

3.5 Draft the core sections of a Product Requirements Document

A concise PRD that captures overview, features, user stories, and constraints for the app.

You will produce a living document that aligns stakeholders on what is being built and why.

  1. Create a new document titled Lab‑Inventory‑PRD.md.
  2. Write a one‑paragraph Product Overview describing purpose and main value proposition.
  3. Add a Features list where each bullet names a feature (e.g., “Add Item screen”) and includes the corresponding user story from your acceptance tests.
  4. Insert a Constraints section that records any technical limits you discovered while defining the data model (e.g., maximum field lengths).
  5. Save and share the PRD with the team for review.
  • You'll see A markdown file containing clearly labeled sections that can be read by both product and engineering teams.
  • Takeaway A well‑structured PRD serves as a single source of truth, keeping scope tight and decisions transparent.

3.6 Create given‑when‑then acceptance tests for every UI screen

A set of concrete test cases that define when a screen’s feature is considered complete.

Produce a checklist of pass/fail criteria for each screen based on the spec and data model

  1. Open the approved one‑page spec and data model table
  2. Write a “Given” clause that sets up the initial state for the screen
  3. Add a “When” clause describing the user action on that screen
  4. Finish with a “Then” clause stating the expected outcome
  • You'll see A complete set of testable acceptance criteria ready to verify each screen’s functionality
  • Takeaway Explicit acceptance tests remove ambiguity about feature completeness and enable rapid, reliable verification at every build step
  • Check In what way does creating given‑when‑then acceptance tests for each UI screen confirm that a feature meets the spec and data model requirements?

3.7 Generate an incremental build plan from the PRD

A step‑by‑step schedule that breaks the project into reviewable increments.

You will create a plan that maps each feature to a development sprint and acceptance test checkpoint.

  1. Open a new table named build‑plan.xlsx.
  2. Add columns: “Sprint”, “Feature”, “Acceptance Test (Scenario)”, “Owner”, and “Status”.
  3. Assign each feature from the PRD to a sprint number, linking it to the matching Gherkin scenario you wrote earlier.
  4. Fill in an Owner for each sprint (e.g., “Frontend dev” or “QA lead”).
  5. Save the plan and circulate it for sign‑off before any code is started.
  • You'll see A chronological list of sprints with clear deliverables tied to test scenarios, ready for team commitment.
  • Takeaway Mapping features to incremental milestones ensures continuous review and reduces risk of scope creep.

4You’ll know it worked 18 checkable outcomes in this chapter

  • All screen tests run and pass without failures
  • The plan lists numbered steps matching spec screens, ready for approval
  • The flow diagram lists all screens and their next steps before development starts
  • All memo sections present and each numeric claim cites a source or says 'not in materials'
  • The next build session starts with the updated spec and no drift is detected
  • Screen 1 is displayed and ready for approval
  • All candidates listed with rationale rows and each criterion cell cites a source
  • Spec file contains a guardrails clause preventing cross-customer ticket visibility

18 outcomes in all — one per recipe below.

5FAQ, Tips & How-to 33

one problem, one solution, one action

Research & data tools2

How-to Scientist +1

Need a fixed database schema for a lab sample tracker

A tight v1 scope where the schema is the single source of truth, and the out-of-scope list prevents scope creep during the build.

~5 min · no code Lesson → AI-generated
How-to Scientist +1

Not sure what each screen must do

Each feature has a pass/fail test written before the code, removing ambiguity about what "works" means at review time.

~5 min · no code Lesson → AI-generated

Internal tools & ops3

How-to Founder +1

Unsure what exactly to build

The scope is locked in 10 minutes of questions rather than discovered mid-build when rewrites are expensive.

~5 min · no code Lesson → AI-generated
How-to Founder +1

Want to break a spec into bite‑size chunks

A build that progresses one reviewable chunk at a time, not an all-at-once dump that is hard to course-correct.

~5 min · no code Lesson → AI-generated
How-to Operations +1

Ticket routing not meeting SLA

SLA rules have a pass/fail test written before the code, so the correct behaviour is testable immediately after each rule is built.

~5 min · no code Lesson → AI-generated

Booking & scheduling1

How-to Small biz +1

Unsure which roles need screens in a booking app

Every role's needs are on paper before the first screen, so no user type is forgotten mid-build and the permissions model is obvious.

~5 min · no code Lesson → AI-generated

Commerce & payments1

How-to Small biz +1

Project keeps expanding with extra features

A written boundary that stops "while we're at it" additions from doubling the build time.

~5 min · no code Lesson → AI-generated

Content & marketing2

How-to Creator +1

Don't know what comes after each step

The full user journey is agreed on paper; no screen is a surprise when it appears in the build.

~5 min · no code Lesson → AI-generated
How-to Creator +1

Prevent accidental risky actions

Behavioural boundaries that survive across multiple build sessions and prevent the AI from "helpfully" shipping a dangerous shortcut.

~5 min · no code Lesson → AI-generated

Dashboards & analytics3

How-to Investor +1

Memo drafts need uniform layout and traceable numbers

Every memo draft follows the same structure and is fully source-traceable — reviewers can verify any figure without hunting through the data room.

~5 min · no code Lesson → AI-generated
How-to Finance +2

Need to define tech stack, storage limits and role permissions for a finance dashboard

Every build session starts with the same constraints locked in, so no feature is built on the wrong stack or with the wrong permissions model.

~5 min · no code Lesson → AI-generated
How-to Finance +2

Specs get out of sync between sessions

Drift between spec and build is caught at the spec update stage, not discovered as a bug three screens later.

~5 min · no code Lesson → AI-generated

Trackers2

How-to Investor +2

Quarterly portfolio updates have mismatched formats

Every quarterly update produces a consistent table the investment team can compare across companies and periods without normalising mismatched formats.

~5 min · no code Lesson → AI-generated
How-to Operations +1

Need a common inventory data model before any screens

A schema everyone agrees on before the first screen, so no feature requires a breaking data-model change mid-build.

~5 min · no code Lesson → AI-generated

Forms, surveys & feedback3

How-to HR / People +1

Can't see every role’s workflow in a leave‑request app

No actor's workflow is discovered mid-build; the permissions matrix falls out of the story set naturally.

~5 min · no code Lesson → AI-generated
How-to Support +1

Ticket reassignment rule changes

The spec stays the single source of truth through the whole build — the AI never works from a stale memory of the original requirement.

~5 min · no code Lesson → AI-generated
How-to Physician

A pre-build spec that pins down exactly what data is collected and who can see it, so the privacy decision is made once at spec time instead of discovered during a compliance review.

~5 min · no code Lesson → AI-generated

Knowledge & docs3

How-to HR / People +1

Mistakes hidden until the end

Mistakes are caught after one screen, not after twelve; the approved spec is the contract that keeps each build step on track.

~5 min · no code Lesson → AI-generated
How-to HR / People

Need a candidate brief from intake notes

Every brief sent to candidates uses the same structure and contains no fabricated requirements — reducing misalignment between candidates and hiring managers.

~5 min · no code Lesson → AI-generated
How-to HR / People +1

Need an audit‑ready candidate shortlist with source citations

The shortlist is auditable (every inclusion and omission has a stated reason), and final decisions remain with the human reviewer, not the model.

~5 min · no code Lesson → AI-generated

CRM & sales2

How-to Sales +1

Need to keep rep data private

A one-page spec that covers permissions, data model, and guardrails before a single field is built — so the AI never builds a feature that leaks one rep's data to another.

~5 min · no code Lesson → AI-generated
How-to Sales +1

Need a view of the deal‑stage pipeline

The full pipeline UX is on paper before any component is built; each screen's inputs and outputs are agreed and the build order is clear.

~5 min · no code Lesson → AI-generated

Customer & client portals1

How-to Support +1

Need a ticket portal spec that blocks cross‑customer visibility

A complete pre-build spec that covers every role's view and a hard data-isolation rule, so the most dangerous mistake is blocked at the spec stage.

~5 min · no code Lesson → AI-generated
How-to Everyone

Not sure a feature works

Say how you will know each feature actually works. Acceptance criteria turn "it works" into something checkable — the AI can verify against them, and so can you.

~5 min · no code Lesson → AI-generated
How-to Everyone

Spec is just text

Make the AI produce an ordered, checkable plan — and approve it before any code. An approved plan is the contract. You catch a wrong assumption on a 10-line plan, not in a finished, broken app.

~5 min · no code Lesson → AI-generated
How-to Everyone

Don't know what fields you need before building screens

Name the objects and their fields before any screen exists. The data model is the app's skeleton. Getting it right first prevents the painful rewrites that happen when you find a missing field after the UI is built.

~5 min · no code Lesson → AI-generated
How-to Everyone

Need a list of things the app must never do

Write the rules the app must never break — the bugs that bite later are the unstated ones. The "must never" list up front is what separates a demo from something you can actually trust with real data.

~5 min · no code Lesson → AI-generated
How-to Everyone

When requirements change and chat history is lost

Update the spec when requirements change — and re-feed it each session. Chat history gets lost; the spec does not. Re-grounding each session in the current spec stops the code and the plan from silently drifting apart.

~5 min · no code Lesson → AI-generated
How-to Everyone

Need a lab inventory app but don’t want guesswork

Name the app, the user, and the core job in one sentence — then make the AI ask before it builds. A one-liner plus "ask me first" turns a vague wish into a scoped conversation — the AI clarifies instead of guessing and building the wrong thing.

~5 min · no code Lesson → AI-generated
How-to Everyone

Too many ideas for version 1

Scope the first version — and say out loud what it will NOT do. An explicit out-of-scope list is what stops v1 from ballooning into a half-finished, buggy everything-app — for both you and the AI.

~5 min · no code Lesson → AI-generated
How-to Everyone

Can't map out pages and flow

List the pages, what is on each, and how you move between them — then build one at a time. Naming the screens and building one at a time gives you checkpoints — instead of a 2000-line app you have to debug all at once.

~5 min · no code Lesson → AI-generated
How-to Everyone

I must restrict the AI to my chosen stack, built‑in database and email‑link login

State the stack, storage, auth, and the limits the AI must stay inside. Stating the stack and boundaries keeps the AI from pulling in heavy dependencies that break the build or quietly route your data somewhere it should not go.

~5 min · no code Lesson → AI-generated
How-to Everyone

Can't tell who does what in the lab

List the roles and their top tasks as user stories. User stories pin down exactly what each person must be able to do, so the AI builds the features that matter — not a generic CRUD app.

~5 min · no code Lesson → AI-generated

The same set on /recipes, filtered by tool and role.

6Videos 2

New course! Spec-Driven Development
DeepLearningAI Beginner

The case for writing the spec first — from DeepLearning.AI's course on spec-driven development with coding agents.

7FAQ 7

Why write a spec before "vibe coding"?

Because vibe coding fails when the AI has to guess what you meant. A short, precise spec turns a vague wish into something the AI can build correctly the first time — instead of a confident, bug-ridden everything-app you then have to unpick.

Won't writing a spec just slow me down?

It is faster overall. You catch a wrong assumption on a 10-line plan in seconds, not after the AI has generated 2,000 lines of the wrong app. The spec is the cheap place to be wrong.

What is the minimum a useful spec needs?

A one-line description, who the users are and their top tasks (user stories), the data model, the screens, acceptance criteria for the key features, the tech constraints, and an explicit out-of-scope list. That fits on a page and is enough for the AI to build from.

What are acceptance criteria?

A checkable statement of how you will know a feature works — ideally with a concrete test case. "When quantity ≤ threshold the row turns amber and is counted in a Low-stock badge" can be verified; "make the alert work" cannot.

How do I stop v1 from ballooning?

Write the out-of-scope list out loud — the features v1 will NOT have. An explicit boundary is what stops both you and the AI from quietly adding "just one more thing" until nothing is finished.

Should I let the AI start coding straight away?

No — have it turn the spec into a numbered, dependency-ordered build plan and approve that first. The approved plan is the contract; you review 10 lines, not a finished app.

What happens when requirements change mid-build?

Update the spec first, then ask "given the updated spec, what needs to change in the code?" Treat the spec as the living source of truth and re-paste it at the start of each session, so the code and the plan never silently drift apart.

8Glossary 9 terms

Show the 9 terms
Spec parts
PRD
Product requirements document — the short, precise blueprint you write with the AI before any code.
User story
One need, in the form "As a [role] I can [action] so that [reason]." — pins down who does what and why.
Data model
The objects and their fields (the app's skeleton) — defined before any screen exists.
Acceptance criteria
A checkable statement of how you'll know a feature works, with a concrete test case.
Out-of-scope
An explicit list of what v1 will NOT do — what stops it ballooning into a buggy everything-app.
Guardrails
The "must never" rules (security, permissions, validation) the app must not break.
Process
Build plan
An ordered, dependency-sorted list of steps the AI proposes and you approve before it writes code.
Living spec
Treating the spec as the source of truth — update it first when requirements change, and re-feed it each session.
Vibe coding
Describing an app in plain English and letting AI build it — fast, but it fails when the AI has to guess what you meant.

9See also

💬 Discuss this chapter

Ask, share, or report — over on the Heidelberg AI community forum.