# Requirements Traceability

Maintaining links from each requirement through design, tasks, tests and code, so coverage and impact are visible.

**Rests on:** Acceptance Criteria, Product Requirements Documents

*Software Engineering · Spec-Driven Development*


## Why learn this

You are learning this because, once you build AI systems that write and change code, you need to know for certain that every requirement is covered and that changing a requirement doesn't silently break something else. This concept unlocks Spec Drift and the Spec-to-Code Pipeline. With traceability, you can answer 'what breaks if this requirement changes?' in seconds instead of weeks. Without it, you are trusting a document that may no longer describe the system.


## The intuition

Imagine you are building a house. The architect draws a plan: 'the kitchen must have two windows facing east.' The builder reads the plan and builds the kitchen. The electrician reads the plan to know where to put the sockets. The inspector reads the plan to check the windows are there. Now imagine the owner says, 'actually, one window is enough.' The architect changes the plan. But does the electrician know? Does the inspector? If there is no way to trace that change from the plan to every person who acted on it, then the sockets get placed assuming two windows, and the inspector checks for two windows, and the house ends up wrong. Requirements traceability is the system of linking every line on the plan to every action that depends on it, so that when something changes, you can find everything that must follow. In software, the plan is the specification, the builder is the code generator (often an AI agent now), the electrician is the tests, and the inspector is your review. Without traceability, a change to one requirement can ripple through tasks and tests and code without anyone noticing until the system is already wrong.


## An analogy

Think of a physical filing system: a set of index cards. Each card represents one requirement: 'R1: user can log in with email.' On that card you write the design decision that satisfies it ('D1: use OAuth'), the task that implements it ('T1: add login button and backend'), the test that verifies it ('Test 1: login with valid email succeeds'), and the file names of the code that does it ('auth.py', 'login.js'). Now if R1 changes, you pull the card and see everything that must change with it. That is the traceability matrix: a table where each row is a requirement and each column is a type of artifact (design, task, test, code), and each cell shows the link. The analogy holds for a small system, and it stops working when the system grows: a filing cabinet with ten thousand cards is unmanageable, so we use tools and databases to keep the links. But the principle is exactly the same — the cards are the links, and the tool is just a faster way to shuffle them.


## Definition

Requirements traceability is the practice of maintaining explicit links from each requirement to the design decisions, tasks, tests, and code lines that satisfy it, and vice versa, so that coverage and impact are visible at all times.


## How it connects

This concept sits between your notes on Product Requirements Documents (the source of requirements) and Acceptance Criteria (the tests that define done). It also connects directly to Spec Drift, because drift is only detectable when you have links to compare against. And it is part of the Spec-to-Code Pipeline, where traceability is the glue that lets you see what each task in a pipeline is for. You have already noted that 'ambiguity multiplies into every downstream artifact' — traceability is how you catch that multiplication before it gets too big.


## The mathematics

This concept does not require any algebra or calculus. It rests on simple arithmetic — counting and comparing. The mathematical idea is to make sets of things and check whether one set covers another. A traceability matrix is a table where rows are requirements and columns are artifacts. The number of requirements is a count. The number of tests that exercise each requirement is a count. A coverage check is: for each requirement, is the count of tests at least one? That is arithmetic. A completeness check is: for each test, does it map to exactly one requirement? That is also a count. The mathematics of traceability is the mathematics of sets and relations — does this requirement have a link to a test, and does this test trace back to a requirement? You can do all of this with a pen and a tally sheet.

Coverage = (number of requirements with at least one test) / (total number of requirements). Symbol: C = (R_cov / R_total) × 100% — the percentage of requirements that have a link to a test.


## A worked example

```
Suppose you have 3 requirements (R1, R2, R3), 2 tests (T1, T2), and 2 code files (C1, C2). You want to know if every requirement is tested.

Step 1: R1 is linked to T1, so count for R1 = 1   # R1 has a test, so it is covered.
Step 2: R2 is linked to T1, so count for R2 = 1   # R2 also has a test.
Step 3: R3 has no test link, count = 0   # R3 is missing a test.
Step 4: Total tests = 2, but only 2 of 3 requirements are covered   # The coverage level is 2/3, so there is a gap.

Result: The coverage is 2 out of 3 requirements (67%). You know you have a gap to fix.
```


## From scratch, in Python

```python
# We have a list of requirements, a list of tests, and a list of links.
# A link means: this test verifies this requirement.
requirements = ["R1", "R2", "R3"]
tests = ["T1", "T2"]

# A list of tuples. Each tuple is (test_name, requirement_name).
links = [
    ("T1", "R1"),
    ("T1", "R2"),
]

# We want to find which requirements have no test.
# Start with an empty list of requirements that are covered.
covered = []

# Go through each link and add the requirement to covered if not already there.
for test, req in links:
    if req not in covered:
        covered.append(req)

# Now check each requirement.
print("Requirements without a test:")
for req in requirements:
    if req not in covered:
        print(req)

# Count the coverage.
total_count = len(requirements)
covered_count = len(covered)
coverage = (covered_count / total_count) * 100
print(f"Coverage: {covered_count}/{total_count} = {coverage}%")
```


## The same thing, with a framework

```python
In practice, developers do not write this from scratch — they use a requirements management tool like Jira or IBM DOORS, or a lightweight Python library like `pandas` to hold the matrix as a table. Underneath, a `pandas` DataFrame is simply a table of rows and columns, very much like our lists and tuples. A developer would load the matrix CSV, then use a `groupby` to count how many tests map to each requirement, exactly like our loops. The tool is just a faster way to do the same counts and comparisons.
```


## What the code does

We make three lists of plain text names. A tuple is a pair of values that cannot be changed, and we use tuples for the links to make it clear each link is a fixed pair. The `for` loop goes through each link, one at a time, and puts the requirement name into the `covered` list if it is not already there. The `if` check prevents adding the same requirement twice. After the loop, the second `for` loop prints any requirement not in `covered`. Finally we use `len()` to count the items and calculate the percentage. This is the same logic a traceability tool does internally, just with hand-written lists.


## Common misconceptions

**Traceability is just a document I write once** — I'll write a traceability matrix at the start and it will be fine.

Specifications change, tasks change, and code changes. A matrix that is not updated is as good as no matrix, because it gives you false confidence. In fact: Traceability is a living system — you update the matrix every time a requirement, design, task, test, or code changes.

**Traceability is extra paperwork that slows me down** — I don't need traceability because I can just search for a requirement name and see where it appears.

Searching only finds exact text matches. Requirement changes often reword things, so search misses links that matter. In fact: Traceability is a deliberate, bidirectional link. Search is a rough heuristic; traceability is a guarantee.

**The matrix needs to track every line of code** — I need a row for every test and every code file, otherwise it is incomplete.

Granularity matters. The matrix is for level of requirement to level of test or code module, not every line. Over-granularity makes the matrix useless because it is too much to maintain. In fact: Traceability is at the requirement level to the artifact level — not code lines. Keep granularity meaningful.

**Traceability is only for compliance projects** — This is only for government projects or medical devices. Normal AI projects don't need it.

Compliance projects need it because regulations demand it, but every project with AI agents writing code needs it to catch drift before it breaks the system. In fact: Traceability is a software engineering practice for any project where requirements are the control surface — which is all spec-driven AI development.


## In short

Requirements traceability is the practice of linking each requirement to its design, tasks, tests, and code — and back. It makes coverage measurable and impact analysable. Without it, spec drift is invisible; with it, you can answer 'what breaks if this changes?' in minutes. Maintain the matrix as a living artifact, not a one-time document.


## Where this is used

This concept is everywhere in AI development, and not just in theory. When you are training a large language model, the requirements are the data sources and the capabilities you need — 'must answer questions in Hindi' or 'must not output hate speech'. Traceability means you can map each capability to the training data that teaches it and the evaluation test that verifies it. If you change a requirement — say you drop the Hindi capability — you know which data you can delete and which evaluation you can remove, without accidentally removing something else. For a small language model running on a phone, the requirements are strict: 'must fit under 1 GB and respond in under 200 ms'. Traceability links each model weight or architecture choice to that requirement, so a change to the model is checked against those constraints. In retrieval-augmented generation, the requirements might be 'must only answer from the provided documents' — traceability links each answer to the document it came from, so if a document is updated, you trace which answers are now stale and need regeneration. In agentic systems, requirements become the agent's instructions like 'must call the booking tool when the user asks to book' — traceability maps each requirement to the code path that implements it, so when the requirement changes, you know which tool calls to update. In everyday applied machine learning, a fraud model has requirements about precision and recall — traceability links each threshold to the test that validates it, so a business decision to change the threshold is checked against the required metrics. What a developer actually writes is usually not this from-scratch loop — they use a tool like Jira to link epics to stories to tests to code commits, or they use a structured spec-to-code pipeline where each task card carries its requirement IDs. What breaks when traceability is done badly is that spec drift goes unnoticed — a requirement changes, the test is not updated, and the model or system silently behaves incorrectly. The specification becomes stale, and because 'a stale specification is worse than none because it is trusted', you can end up with a system that looks right on paper but is wrong in production.


---

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