# Product Requirements Documents

A structured statement of what a product must do and for whom, from which technical design and tasks derive.

**Leads to:** Acceptance Criteria, Engineering Intent Documents, Requirements Traceability, Spec-to-Code Pipeline, Task Cards

**Rests on nothing.** A place to start.

*Software Engineering · Spec-Driven Development*


## Why learn this

A clear product requirements document stops a project from failing because everyone misunderstood what needed to be built. It acts as the single source of truth that prevents confusion from spreading through the engineering team, the designers, and the testers. When you define exactly what the product must do and for whom, you create a stable foundation for every subsequent step: technical design decisions, daily task lists, quality checks, and the final code delivery. Without this document, you risk 'spec drift', which is the phenomenon where the building process slowly moves away from the original goal because the team adds features or changes directions without constantly checking back against the initial plan. It also helps you maintain 'requirements traceability', meaning you can always prove that a specific test or piece of code directly addresses a stated user need, rather than guessing whether it does. Finally, it ensures that your team passes 'review gates'—specific checkpoints where stakeholders formally approve that the work matches the original plan before moving to the next phase. Mastering this document means you spend less time fixing misunderstandings and more time building the right thing.


## The intuition

Think of a product requirements document as the legal contract between the people who want the software built and the people who are building it. It is not the code, nor is it the technical blueprint; it is simply the precise statement of what the product must achieve for its users. Crucially, it states the *what* and the *why*, deliberately avoiding the *how*. 

Consider a concrete example: You are planning a mobile app for a local grocery store. Your requirements document would state: "A customer must be able to browse items by category, add them to a cart, and place an order for delivery." This is clear and actionable. It does *not* say, "We will use React Native for the front end and Node.js for the backend." That detail belongs in the technical design phase.

Why does this distinction matter? Imagine if the requirement were vague, such as "the app should be fast." A developer might think 2 seconds is fast enough; a user might expect it to load in under 200 milliseconds. This ambiguity multiplies as work progresses. The designer might create a heavy animation that slows down the page, the task list might prioritize irrelevant features, and the testing team might not know what speed threshold to measure. By the time the code is written, the original goal is distorted. A well-written requirements document prevents this by making the desired outcome unambiguous from day one. It serves as the anchor point that every other artifact—designs, tasks, tests—checks back against to ensure accuracy.


## An analogy

Imagine you are commissioning a builder to construct a new kitchen in your home. You do not hand them a vague note saying "make it nice," because that is a subjective feeling, not a requirement. Instead, you provide a detailed list: "I need a granite countertop six feet long, two windows above the sink, and electric outlets on both sides of the stove." This list is your requirements document. The builder then draws up the blueprints (technical design), creates a schedule for plumbing and electrical work (task cards), and later inspects their own work to ensure the outlets are grounded and functional (acceptance criteria). If the final kitchen lacks the two windows, the project fails the original agreement. The analogy is not perfect because software can be more flexible than brick-and-mortar construction—you might discover mid-build that a different countertop material saves money—but the core principle remains: you must define exactly what you want before work begins to avoid costly rework later.


## Definition

A product requirements document is a formal written agreement that defines what a product must do, for whom, and why, serving as the primary reference point for all design and development decisions.


## How it connects

This document is the starting point of the Spec-Driven Development process. It follows directly from the Engineering Intent Document, which is an earlier step where teams broadly define the problem, target users, and high-level goals without getting into specific features. Once those broad goals are set, you write the product requirements document to make them concrete and testable. This document then connects forward to Acceptance Criteria, which are specific tests derived directly from each requirement to verify success, and it enables Requirements Traceability, the practice of keeping a clear link between every user need and the corresponding code or test that fulfills it.


## The mathematics

This concept uses arithmetic, not algebra or calculus. The mathematics here is about counting and checking — the kind of arithmetic you might do in a shop. The main operation is the **count** and the **comparison**. A count is when you find out how many of something there are. A comparison is when you decide if two numbers are equal, or if one is greater than the other. For example, if a requirement says "the app must support 100 users at once," you can test it by counting: are there 100 users logged in? If the requirement says "the app must load in under 2 seconds," you compare the actual load time to 2. These are the only mathematical operations involved in writing a requirements document. The branch of mathematics is **arithmetic** — counting and comparing — and it is chosen because a requirement is a statement about quantity and thresholds, not about continuous change. You do not need calculus or algebra to write a clear requirement; you need to be precise about numbers.

Not applicable — this concept does not require a symbolic formula. The key is the *testability criterion*, which informally is:

For each requirement r, there exists a measurable quantity q and a threshold t such that the requirement is satisfied if q <= t or q >= t.


## A worked example

```
You are writing requirements for a food delivery app. You have three candidate requirements. You need to decide if each one is a good requirement by checking if it is testable. A testable requirement is one where you can use arithmetic to check if it is met.

Step 1: Requirement 1: "The app should be fast." → Count: How fast is fast? There is no number. → Not testable.   # This requirement has no measurable quantity. You cannot count or compare anything. It is not a good requirement.
Step 2: Requirement 2: "The app must load within 2 seconds on a 4G connection." → Test: measure load time = 1.8s. Compare 1.8 <= 2.0 → True → Testable.   # This requirement has a number (2 seconds) and a condition (within). You can measure the load time and compare it to the threshold.
Step 3: Requirement 3: "The app must support 200 simultaneous users." → Test: simulate 200 users, count how many can use it without error. If all 200 work → True → Testable.   # This requirement has a countable quantity (users) and a threshold (200). You can test it by counting.

Result: Good requirements are testable because they contain numbers and thresholds that you can verify with arithmetic. Vague requirements like "fast" are not testable.
```


## From scratch, in Python

```python
# We will write a small tool to check if requirements are testable.
# First, let's learn the Python building blocks.

# A list is an ordered collection of items. It can be changed after creation.
# Example:
requirements = ["The app should be fast.", "The app must load within 2 seconds on 4G.", "The app must support 200 simultaneous users."]

# A dictionary looks things up by name, not position. It pairs a key with a value.
# Example:
requirement_1 = {"text": "The app should be fast.", "has_number": False}
requirement_2 = {"text": "The app must load within 2 seconds.", "has_number": True}

# A function is a reusable block of code. It takes inputs (called arguments) and returns a result.
# We define a function to check if a requirement text contains a number.

def has_number(text):
    # Loop through each character in the text.
    for char in text:
        # If the character is a digit (0-9), we found a number.
        if char.isdigit():
            return True
    return False

# Test the function on each requirement.
for req_text in requirements:
    if has_number(req_text):
        print("Testable?", req_text)
    else:
        print("Not testable?", req_text)

# Output:
# Not testable? The app should be fast.
# Testable? The app must load within 2 seconds on 4G.
# Testable? The app must support 200 simultaneous users.

# Now, a more advanced check: we want to see if the requirement has a comparison word like "within" or "at least".
# We can use the 'in' operator to check if a substring exists.

def is_testable(text):
    has_threshold = has_number(text)
    has_comparison = ("within" in text or "at least" in text or "more than" in text or "less than" in text)
    return has_threshold and has_comparison

for req in requirements:
    print(is_testable(req))

# Output:
# False
# True
# False  # Because "200 simultaneous users" has a number but no comparison word. It could be interpreted as exactly 200 or at least 200.

# To make it testable, you must add a comparison. For example: "must support at least 200 simultaneous users."
```


## What the code does

We start by defining a list of requirement strings. Then we define a function `has_number` that loops over each character in the string and checks if it is a digit. `isdigit()` is a method that returns True if the character is a digit. The loop is a `for` loop, which goes through each item in a sequence. The `return` statement exits the function and gives back a value (True or False). We then loop over the list of requirements, call `has_number`, and print a message. Next, we define `is_testable` which uses the `in` operator to check if a word like 'within' or 'at least' appears in the text. The `and` operator combines two conditions. If both are true, the requirement is testable. This tool is a simple example of how you might automate the checking of requirements for testability, which is a real part of a quality gate.


## Common misconceptions

**Requirements are the same as a vision statement** — A requirements document is just a fancy way of saying 'I want an app that helps people shop.'

A vision statement is a broad idea. A requirement is a specific, testable statement. 'Help people shop' is not testable — there is no number to check. 'The app must allow a user to complete a purchase in under 3 minutes' is testable. In fact: A requirements document contains specific, measurable statements, not general aspirations.

**Requirements must specify the technical solution** — To write a good requirement, I need to say 'We will use a React front end and a Python backend.'

That is the 'how', not the 'what'. The requirement should state what the product must do, not how to build it. Mixing 'how' into the requirements makes the document prescriptive and prevents developers from finding the best solution. In fact: Requirements state the 'what' and 'why'; the technical design states the 'how'.

**If the requirement is clear to me, it is clear to the developer** — I know what I mean when I say 'make it easy to use', so the developer will too.

Clarity in your own head is not clarity on paper. 'Easy to use' is subjective. The developer might interpret it as 3 clicks, you might expect 1 click. Without a number, there is no way to check. In fact: Write requirements that are testable, with numbers wherever possible. If you cannot measure it, it is not a requirement.

**There is no need to review the requirements; the code will be reviewed later** — We can skip the requirements review and just review the code when it's done.

Reviews at the requirements stage are the cheapest place to catch defects. Catching a missing requirement after coding is 10x more expensive than catching it in review. The spec-driven approach says review is the quality gate. In fact: Review the requirements document before any code is written. That is the first and most important control point.


## In short

A product requirements document states what a product must do and for whom, in a way that is testable. It is the first control point in a spec-driven workflow. Write requirements with numbers and thresholds, not vague adjectives. Review them carefully before moving on, because every downstream artifact — design, tasks, and tests — depends on them.


## Where this is used

In practice, product requirements documents are used in every AI project, from large language models to small device models. For a large language model like GPT, the requirements document would specify things like: "The model must be able to summarize a 10,000-word article in under 100 words" — that has a quantity and a threshold. For a small language model running on a phone, the requirement might be: "The model must run on a device with 4GB RAM and respond in under 100 milliseconds." That is a quantitative requirement the hardware team can verify. In retrieval-augmented generation (RAG), the requirement might be: "The system must return relevant answers from the knowledge base 95% of the time." The developer can test that by counting. For agentic systems, the requirement might be: "The agent must complete a task that requires at least 5 tool calls without human intervention." Again, a number. In everyday applied machine learning, say a fraud detection model, the requirement is: "The model must flag at least 90% of fraudulent transactions and produce at most 1% false positives." These are all testable because they have numbers. A developer writing the requirements document will use a checklist — maybe in a markdown file — that includes sections like 'Users', 'Goals', 'Functional requirements', 'Non-functional requirements'. Each requirement is written as 'The system shall ...' with a measurable condition. When a developer writes code, they will check the requirements document to make sure what they built meets the criteria. If the requirement is not testable, the developer will go back to the person who wrote it and ask for clarification. This is the quality gate. If you write a vague requirement, you are pushing the ambiguity downstream, and it will cost time and money later.


---

Read this on the web: https://basavapurushottam.com/learn-ai/product-requirements-documents
