Univa Learning

Module 9 of 9 Process

Product Requirements Documents

Level Intermediate Estimated study time 100 minutes Prerequisites none required, though familiarity with Univa's /blueprint Build Brief practice helps
Video lesson: coming soon

Why this matters for Univa

Every Univa project starts as a vague want in a client's head ("I need an app for my tailor shop") and ends as working code. The Product Requirements Document (PRD) is the document that sits in between: it turns "boleh buat app tak" into a shared, written description of what is actually being built, for whom, and why, before a single line of code exists. Skip it and you are guessing at scope on every call, re-negotiating price mid-build, and absorbing endless "boleh tambah sikit?" (can you add a little?) requests that were never priced in.

This matters even more because Univa builds are priced on value, not on hours, with a floor around RM5k for a custom AI build. A fixed-scope, value-priced project only works if the scope is fixed in writing. Without a PRD, "custom AI build" quietly becomes an open-ended subscription to Ahnaf's time, and the client (reasonably, from their side) keeps adding "just one more thing" because nothing on paper ever told them where the line was.

A PRD is also the natural complement to the /blueprint practice already in use. /blueprint turns a one-liner into an 8-slot Build Brief fast, which is exactly right for kicking off a build the same day it is pitched. A PRD is the next layer down: once the Build Brief says "yes, build this," the PRD is where the actual requirements get written down in enough detail that both the client and, increasingly, an AI coding agent can act on them without guessing.

Finally, this matters because Univa builds heavily with Claude Code and similar agents, and a PRD is no longer just a communication document between humans. A sharp PRD is now close to executable: it becomes the plan the agent works from, the acceptance criteria the agent checks its own output against, and the record of "what we agreed" when the agent (or the client) drifts from it mid-build. A vague PRD does not just risk a confused client; it risks a confidently-wrong agent shipping the wrong thing fast.

Core concepts

What a PRD is. A PRD is a written description of what a product or feature should do and why, aimed at aligning everyone (client, builder, and now, coding agent) on scope before work starts. A good PRD answers: what problem are we solving, for whom, what does success look like, what is explicitly included, and just as important, what is explicitly excluded.

What a PRD is not. A PRD is not a pitch, not a technical design, not a to-do list, and not a wireframe. Confusing a PRD with any of these four is the single most common way requirements documents fail to prevent scope creep, so it is worth separating them clearly.

  • Product brief: a short, persuasive one-pager, usually written before the PRD, that answers "should we build this at all." It sells the idea (to a client, an investor, or Ahnaf's own priority list) rather than specifying it. Univa's /blueprint Build Brief lives here.
  • PRD: the specification of what gets built and why, once the brief has already secured a "yes." It is the contract between stakeholders on scope, written in product language, not code.
  • Technical spec (tech spec): written after the PRD, usually by the person who will build it (Ahnaf, or an agent under his direction). It answers how the PRD's requirements get implemented: data model, API shape, third-party services, architecture decisions. The REST/GraphQL/gRPC choice from Module 6, for example, belongs in a tech spec, not a PRD.
  • Design doc: covers visual and interaction detail, screens, flows, states (empty, loading, error). Can be a companion to the PRD (referenced from it) or a section inside a lean PRD for small projects; it answers what it looks and feels like, not what it does or why.
  • User story backlog: the PRD broken into small, ticket-sized units of work ("As a shop owner, I want to mark an order as paid, so I can track outstanding balances"), each with its own acceptance criteria, used to sequence actual build work sprint by sprint or session by session.

Where each lives in the delivery flow: brief (should we build it) leads to PRD (what and why) leads to tech spec and design doc (how, and what it looks like, can happen in parallel) leads to backlog (build it in pieces). For a solo builder working with an AI coding agent, the tech spec and the backlog often collapse into the PRD itself for small projects, but the thinking order (why, then what, then how) should never collapse, even when the documents do.

Anatomy of a classic PRD. A full, textbook-style PRD (the kind a PM at a larger company writes for a multi-team project) typically has these sections:

  • Problem statement: the specific pain, in the user's words if possible, not the solution. "Order status is tracked on a paper notebook, so the tailor forgets which orders are overdue" is a problem statement. "Build an order tracking app" is a solution, not a problem statement, and belongs further down.
  • Goals: the outcomes that count as success, stated as results, not features. "Reduce missed pickup dates to zero" is a goal. "Add a calendar view" is a feature that might serve that goal.
  • Non-goals: the single most important section for a scope-creep killer, and the most commonly skipped. Non-goals state, explicitly, what this project will not do, even though it sounds related. "This tool will not handle payroll for shop staff" or "this version will not support multiple shop branches" stops a client's reasonable-sounding follow-up request cold, because it was already declined in writing, with their earlier sign-off.
  • Target users and personas: who actually uses this, and how their context shapes the requirements (a shop owner using a phone with one hand while measuring a customer is a very different design constraint than an office admin at a desktop).
  • User stories / jobs-to-be-done (JTBD): the tasks a user is "hiring" the product to do, phrased from their side ("When a customer calls asking if their order is ready, I want to check status in under 10 seconds, so I don't put them on hold").
  • Functional requirements: the concrete things the system must do, ideally numbered, so they can be individually referenced, tested, and marked done.
  • Non-functional requirements: performance (how fast, how many concurrent users), security (who can see what data, how is it protected), and compliance. In Malaysia, this is where the Personal Data Protection Act (PDPA) shows up for any app storing customer names, phone numbers, or IC numbers: consent language, data retention, and access control belong here, not bolted on after launch.
  • Success metrics: how "it worked" will be measured after launch, ideally numbers, not vibes ("time to log a new order under 30 seconds" beats "the app should feel fast").
  • Milestones: the checkpoints between "not built" and "done," useful for staged delivery and staged invoicing.
  • Open questions: anything still unresolved when the PRD is first written, tracked explicitly rather than silently assumed one way. An open question left open is honest; an open question quietly assumed is where scope disputes are born.
  • Out-of-scope list: distinct from non-goals in spirit even if they overlap in practice. Non-goals state strategic exclusions ("we are not becoming a POS system"), while out-of-scope is the practical, itemized list for this specific version ("SMS reminders are out of scope for v1, revisit in v2").

The lean one-page PRD. Most Univa projects are a single client, a single builder, and a build measured in days or weeks, not a cross-team, multi-quarter initiative. A 10-page classic PRD for a RM5k to RM15k SME build is waste: it takes longer to write than some builds take to ship, nobody re-reads the persona section once the build starts, and by the time it is finished the client has lost patience and just wants to see a demo.

What survives the cut when a PRD goes lean: problem statement (one paragraph), goals and non-goals (a short bullet list each, non-goals never dropped), functional requirements (numbered, the actual meat of the document), non-functional requirements (a few lines, PDPA flagged if personal data is involved), success metrics (two or three numbers), and an out-of-scope list. What gets cut or folded in when the project is small: separate persona documents (fold into one line per user type), the full JTBD interview writeup (fold the two or three that matter into the problem statement), a standalone milestones section (fold into the pricing/phasing already in the proposal), and a formal open-questions log (handle live in the discovery call instead, see the Univa playbook below).

Writing testable acceptance criteria. A functional requirement is not finished until someone can check, unambiguously, whether it is met. The Given/When/Then format (from behavior-driven development) forces that clarity in three short lines:

Given a shop owner viewing an order with status "In Progress"
When they tap "Mark as Ready"
Then the order status changes to "Ready for Pickup" and a WhatsApp message is sent to the customer's saved number

This is deliberately more specific than "the app should notify customers when their order is ready," which sounds fine in a meeting but leaves an agent (or a junior builder) to guess the trigger, the channel, and the exact wording. Write at least one Given/When/Then per functional requirement that has any ambiguity in "when does this actually happen," and skip it for requirements that are already unambiguous (a login screen needing an email and password field rarely needs a Given/When/Then).

Client discovery in one conversation. Most Univa clients are non-technical SME owners who have never seen a PRD and would not want to. The discovery skill is extracting the same information a formal requirements interview would get, inside one normal-sounding conversation, then writing the PRD afterward. See the question checklist in the Univa playbook below for the actual script.

PRDs in the AI-coding era. This is the biggest shift from how PRDs used to be written. A PRD used to be written for humans to read and translate into code by hand, so a PRD writer could leave gaps and trust a competent engineer to fill them in with judgment and unwritten convention. A coding agent does not have that judgment by default; it fills gaps with the most statistically likely guess, which is sometimes right and sometimes confidently wrong. This is the core idea behind spec-driven development: the more precisely a requirement is written, the more directly it becomes usable as a prompt or plan for the agent, and the fewer rounds of "no, not like that" correction follow.

In practice this means a PRD written for agent-driven delivery needs more precision in a few specific places than a PRD written purely for a human team: exact field names and data types (agents guess plausible names that may not match an existing schema), exact error and edge-case behavior (agents often only implement the happy path unless told otherwise), and exact wording for anything user-facing (agents will write their own copy if none is given, and it will sound like an agent wrote it). It needs less precision in other places a classic PRD used to over-specify: internal implementation choices, code style, and file structure, all of which are the agent's or the tech spec's job, not the PRD's.

The PRD stays the source of truth while the agent iterates. When an agent's output disagrees with the PRD, the PRD wins by default, and either the code gets corrected or the PRD gets deliberately updated (never silently drifted from) to reflect a genuine, agreed scope change. This is also why the "gaps" an agent stumbles on are diagnostically useful: a place where the agent asks a clarifying question, or worse, silently invents an answer, is very often a place where the PRD itself was ambiguous, not just a place where the agent is weak. Treat every agent misstep as a possible bug report on the PRD, not only on the agent.

Prioritization frameworks, at a working level. Once a PRD lists more functional requirements than fit in the budget or timeline, something has to be cut or sequenced. Two frameworks cover almost all Univa cases:

  • MoSCoW sorts every requirement into Must have (the build fails without it), Should have (important, painful to skip, but not fatal), Could have (nice, cut first under pressure), and Won't have (explicitly out of scope, doubles as the out-of-scope list). It is fast, needs no math, and is the right default for a lean, single-client PRD.
  • RICE scores each requirement on Reach (how many users it affects), Impact (how much it moves the goal, often a 1 to 3 scale), Confidence (how sure you are about the reach and impact estimates, as a percentage), and Effort (person-time to build), combined as (Reach x Impact x Confidence) / Effort to produce a comparable score across requirements. It earns its extra math when there are more candidate features than MoSCoW's four buckets can cleanly separate, typically once a backlog has ten or more competing items fighting for the same build slot.

For a typical Univa SME PRD with fifteen or fewer functional requirements, MoSCoW is almost always the right tool; reach for RICE only when a client's wish list genuinely outgrows four buckets.

The landscape (comparison tables)

Document types across the delivery flow

DocumentAnswersWritten byRead byTypical length
Product brief (/blueprint Build Brief)Should we build this?Ahnaf, fastAhnaf, sometimes the client1 page, 8 slots
PRDWhat are we building, and why?Ahnaf, from client discoveryClient, Ahnaf, coding agent1 page (lean) to several pages (classic)
Technical specHow will it be built?AhnafAhnaf, coding agentVaries, often folded into the PRD for small builds
Design docWhat does it look and feel like?AhnafAhnaf, client (for sign-off), coding agentA few screens' worth of notes or mockup links
User story backlogWhat gets built in what order?Ahnaf, derived from the PRDAhnaf, coding agent, session to sessionA running list, grows and shrinks during the build

Classic PRD vs lean one-page PRD

SectionClassic PRDLean one-page PRD
Problem statementFull narrative, sometimes with supporting researchOne paragraph
GoalsBulleted, tied to company-level OKRs2 to 4 bullets
Non-goalsExplicit section, often several bulletsExplicit, kept even when everything else is cut
PersonasFull persona documents with names, quotes, demographicsOne line per user type
User stories / JTBDFull interview-derived listFolded into the problem statement, 2 or 3 kept
Functional requirementsNumbered, often grouped by epicNumbered, flat list
Non-functional requirementsDedicated section per concern (perf, security, compliance, accessibility)A few lines, PDPA flagged if relevant
Success metricsTied to a measurement plan and dashboard2 or 3 numbers
MilestonesSeparate project-plan documentFolded into the proposal's payment phases
Open questionsA living, tracked logResolved live on the discovery call where possible
Out-of-scopeExplicit sectionExplicit, always kept
Best fitMulti-team, multi-quarter, or investor-facing projectsSolo builder, single-client SME builds under a few weeks

How to choose (decision rules)

  • If the ask is still "should we build this at all," write a product brief (/blueprint), not a PRD. Do not skip straight to a PRD before the client has said yes to the idea itself; that is wasted precision on something that might not happen.
  • If the client has said yes and the project is a typical Univa SME build (single client, single builder, days to a few weeks of work, budget roughly RM5k to RM20k): write the lean one-page PRD. Anything longer will not get read past the first page anyway.
  • If the project spans multiple stakeholders on the client side (an owner, a manager, and IT staff who all need to sign off separately), or the budget is large enough to justify a formal statement of work: step up to a classic PRD, at least for the problem statement, goals, non-goals, and non-functional requirements sections, since disagreement between stakeholders is the actual risk being managed, not documentation for its own sake.
  • If personal data is involved (customer names, phone numbers, IC numbers, payment details) regardless of project size: always include a non-functional requirements section naming PDPA obligations explicitly, even in the leanest PRD. This is a compliance floor, not a nice-to-have.
  • If the build will be driven substantially by a coding agent (which is now the Univa default): write functional requirements with agent-level precision (exact field names, exact error behavior, exact copy) even inside a lean PRD, since the cost of ambiguity is now paid in agent iteration cycles, not just in a human misunderstanding.
  • If a requirement cannot be phrased as something checkable, rewrite it with a Given/When/Then before calling the PRD done. A requirement nobody can verify is not a requirement, it is a wish.
  • If the client asks for something not in the PRD once the build has started ("boleh tambah sikit?"), treat it as a change request against the shared document, not an informal favor: name it, note whether it fits inside an existing non-goal or out-of-scope line (if so, politely point to it), and if it is genuinely new scope, quote it separately rather than absorbing it silently into the existing price.
  • If a backlog of candidate features is short (under ten) and priorities are mostly obvious: use MoSCoW. If the backlog is long and priorities are genuinely contested: use RICE.

Univa playbook

Client discovery: the one-conversation checklist. Run through these questions in a normal-sounding conversation with a non-technical SME owner. Do not read them out as a form; weave them in, but make sure every one gets answered before the call ends.

  1. "Walk me through what happens today, step by step, before this tool exists." (surfaces the real problem statement, in their language)
  2. "What's the most annoying part of that, the thing that makes you say 'ugh' every time?" (surfaces the actual pain, not just the process)
  3. "Who else touches this, besides you?" (surfaces every user persona, including staff the owner might forget to mention)
  4. "If this worked perfectly, what would be different in a month?" (surfaces goals and success metrics)
  5. "What should this definitely NOT try to do?" (surfaces non-goals directly, and most owners have a clear answer once asked)
  6. "What data are we storing here? Customer names, phone numbers, payment info?" (surfaces PDPA-relevant non-functional requirements)
  7. "How many people would use this, and how often, roughly?" (surfaces performance non-functional requirements, usually confirming that Univa's default stack handles it comfortably)
  8. "Is there anything you've seen elsewhere, an app, a competitor, that does a piece of this well?" (surfaces design references without needing a formal design doc)
  9. "What's your timeline, and is there a date this needs to be ready by?" (surfaces milestones)
  10. "If we had to cut something to hit that date, what's the first thing that could wait?" (surfaces MoSCoW priority directly, from the client's own mouth, which is worth far more than Ahnaf guessing it later)

Write the PRD within 24 hours of this conversation, while the client's phrasing is still fresh, and send it back for a one-line "yes, that's it" before quoting or building. That written yes is what makes the PRD the shared contract: the next "boleh tambah sikit?" gets answered by pointing back at a document they already agreed to, not by an argument about what was said on a call nobody recorded.

Change-request handling once the PRD is signed off:

  • Log every new ask against the PRD's non-goals or out-of-scope list first. If it is already there, point to it, politely, and offer it as a priced v2 item.
  • If it is genuinely new, do not fold it into the existing price silently. Name it as a change request, give a one-line scope and price, and get a yes before building it.
  • Update the PRD itself when a change request is accepted, so the document never drifts silently out of sync with what was actually built. An out-of-date PRD is worse than no PRD, because it creates false confidence.

Ready-to-copy Univa one-page PRD template:

# PRD: [Project Name]
Client: [Name] | Date: [YYYY-MM-DD] | Author: Ahnaf (Univa)

## Problem
[One paragraph, in the client's own words where possible]

## Goals
- [Outcome 1]
- [Outcome 2]

## Non-goals
- [Explicitly excluded thing 1]
- [Explicitly excluded thing 2]

## Users
- [User type 1]: [one line on their context]
- [User type 2]: [one line on their context]

## Functional requirements
1. [Requirement, numbered]
2. [Requirement, numbered]
   - Given [context], when [action], then [result]

## Non-functional requirements
- Performance: [expected load, response time]
- Security: [who can access what]
- Compliance: [PDPA notes if personal data is stored]

## Success metrics
- [Metric 1, with a number]
- [Metric 2, with a number]

## Milestones
- [Milestone 1]: [date or phase]
- [Milestone 2]: [date or phase]

## Open questions
- [Anything unresolved]

## Out of scope (v1)
- [Item deferred to a later version]

## Priority (MoSCoW)
- Must: [items]
- Should: [items]
- Could: [items]
- Won't (this version): [items]

Working with a coding agent from this PRD: paste the full PRD as the agent's starting context before any build session, not just the functional requirements section; the problem statement and non-goals stop the agent from "helpfully" building adjacent features nobody asked for. Ask the agent to restate its build plan against the numbered functional requirements before writing code, and treat any requirement the agent skips, misreads, or asks a clarifying question about as a signal to tighten that line in the PRD itself, not just to answer the question and move on.

Worked example

A small tailor shop wants to stop tracking orders on a paper notebook. One discovery call, using the checklist above, produced this:

# PRD: Order Tracker for Kedai Jahit Aminah
Client: Aminah (shop owner) | Date: 2026-09-07 | Author: Ahnaf (Univa)

## Problem
Orders are tracked in a paper notebook. Aminah forgets which orders are
overdue, cannot check status without flipping through pages while a
customer is on the phone, and has twice lost a page with active orders
on it.

## Goals
- Zero lost orders (digital record replaces the notebook entirely)
- Check any order's status in under 10 seconds during a phone call
- Know which orders are overdue at a glance each morning

## Non-goals
- This is not a point-of-sale or payment processing system
- This will not handle staff payroll or scheduling
- This will not support multiple shop branches in v1

## Users
- Aminah (owner): uses it on her phone, one hand, often mid-measurement
- One part-time assistant: enters new orders, does not need admin access

## Functional requirements
1. Create a new order with customer name, phone number, item description,
   price, and due date.
   - Given the new-order form, when required fields are filled and
     "Save" is tapped, then the order appears in the order list with
     status "In Progress."
2. Mark an order as "Ready for Pickup" or "Collected."
3. View all orders sorted by due date, with overdue orders visually
   flagged in red.
4. Search orders by customer name or phone number.
5. Send an automatic WhatsApp message to the customer when status changes
   to "Ready for Pickup."

## Non-functional requirements
- Performance: fewer than 500 orders active at any time, no special load
  handling needed
- Security: only Aminah and her assistant can log in; assistant cannot
  delete orders
- Compliance: stores customer name and phone number (personal data under
  PDPA); consent line added to the order form, data not shared with any
  third party beyond the WhatsApp message itself

## Success metrics
- Zero orders lost or forgotten within 60 days of launch
- Order status check takes under 10 seconds during a test call

## Milestones
- Week 1: order creation, list view, status updates (demo, 50% payment)
- Week 2: WhatsApp notification, search, overdue flagging (launch,
  remaining 50%)

## Open questions
- Does Aminah want photo attachments per order (measurements, fabric)?
  Deferred to v2 pending her answer.

## Out of scope (v1)
- Multiple branches
- Payment tracking / invoicing
- Photo attachments (pending answer above)

## Priority (MoSCoW)
- Must: order creation, status updates, overdue flagging
- Should: WhatsApp notification, search
- Could: photo attachments
- Won't (this version): payments, payroll, multi-branch

This one page was enough for the coding agent to build the whole v1 in two sessions, and enough for Aminah to say "ya, betul ni" (yes, that's right) before any code was written.

Hands-on exercise

Pick one real idea sitting in the Univa backlog (Idea Dumpster.txt or Ongoing Content Ideas/ both work) and do the following in one evening:

  1. Write a one-page PRD for it using the Univa template above. Force yourself to fill in every section, including non-goals and out-of-scope, even if it feels obvious.
  2. Write at least two functional requirements as Given/When/Then acceptance criteria.
  3. Hand the PRD, as-is, to a coding agent (Claude Code) as the starting brief for a small build session, without adding any verbal clarification beyond what is written.
  4. Watch where the agent gets confused: where it asks a clarifying question, silently guesses a field name or behavior that turns out wrong, or builds something adjacent that was never asked for.
  5. For every place the agent got confused, go back and edit the PRD itself, not just correct the agent's output. Note in one sentence per gap what was actually missing or ambiguous in the writing.

Write two or three sentences afterward: how many of the agent's stumbles actually traced back to a genuinely underspecified PRD line versus a case where the PRD was clear and the agent simply erred. That ratio is a good honest read on how close your PRD-writing habit already is to "agent-ready."

Self-check

  1. What is the difference between a non-goal and an out-of-scope item, and why keep both?
  2. Why does a lean one-page PRD drop the persona section but keep the non-goals section?
  3. A client asks mid-build for "just one small extra feature." What does the PRD-as-contract approach say to do before agreeing?
  4. Why does writing a PRD for a coding agent sometimes require more precision than writing one for a human builder, even though both are reading the same document?
  5. When would RICE be a better prioritization tool than MoSCoW for a Univa client's feature list?

Answers:

  1. A non-goal is a strategic exclusion ("we are not becoming a POS system"), stated to prevent scope drift into an entire adjacent product category. An out-of-scope item is a practical, version-specific exclusion ("SMS reminders are out of scope for v1"), stated to defer a real, in-category feature to a later phase. Both matter because they answer different follow-up questions: a non-goal shuts down "can it also do X" permanently, while an out-of-scope item shuts down "can it do X now" while leaving the door open for "in v2."
  2. Personas exist to build empathy and guide UX decisions across a team large enough that not everyone has met the actual users; a solo builder who ran the discovery call in person already has that context and does not need it re-documented. Non-goals exist to prevent scope creep regardless of team size, so they survive every cut.
  3. Check it against the PRD's non-goals and out-of-scope list first; if it is already listed there, point to the client's own earlier sign-off and offer it as priced follow-on work. If it is genuinely new, name it as a change request with its own scope and price, get a yes, and only then build it, updating the PRD to reflect the accepted change.
  4. A human builder fills gaps in a PRD using unwritten convention and judgment picked up from experience; a coding agent fills the same gaps with its most statistically likely guess, which can be confidently wrong (an invented field name, a happy-path-only implementation, generic filler copy). Writing exact field names, exact edge-case behavior, and exact user-facing wording removes the agent's need to guess in the specific places guessing is riskiest.
  5. When the feature backlog is long enough (roughly ten or more competing items) that MoSCoW's four buckets can no longer cleanly separate priority, and there is a genuine need to rank items within a bucket using an actual score, RICE's reach/impact/confidence/effort math earns its extra overhead. For a typical short Univa SME backlog, MoSCoW alone is almost always sufficient.

Further reading