I spent a chunk of my career wiring automation into banks, which means I have built more traceability matrices by hand than I would like to admit. The job always looked the same. An audit is six weeks out, someone asks for proof that every requirement was tested, and a person, usually me, starts screenshotting tickets from Jira, exporting test runs from a separate QA tool, and stitching the two together in a spreadsheet that is already wrong by the time it finishes printing.
Here is the opinion it took me too long to say out loud. In regulated software, the traceability matrix is the deliverable, not a report you generate under duress. If you are rebuilding it from screenshots the week before the auditor arrives, you do not have traceability. You have a fire drill that produces a document shaped like traceability.
The matrix is real. The way most teams build it is broken.
A traceability matrix is a simple idea. Every requirement maps to the design that satisfies it, the test that verifies it, and the defect history that shows the test actually means something. Auditors in finance, medical devices, and aerospace ask for it because it answers one blunt question: can you show that what you said you would build is the thing you actually tested and shipped?
The idea is sound. The implementation is where it falls apart. In most shops the requirement lives in Jira, the test lives in TestRail or Xray or a tab in Excel, the architecture decision that made the requirement risky lives in Confluence, and the defect sits back in Jira under a different project key. None of those tools share a single identity for the requirement, so the matrix only exists when a human re-joins them by hand. It is a join query executed by a tired person at 9pm, and it has all the reliability you would expect from that.
Why the hand-built matrix is worse than no matrix
A matrix you assemble at audit time certifies a snapshot. It was true for the twenty minutes it took to export, then the next merge made it slightly false, and nobody re-ran it because re-running it is another day gone. So you end up with a document that looks authoritative and is quietly out of date. That is arguably worse than admitting you cannot produce one, because now you have signed your name under a join that may not hold.
The auditor's real question is never "do you have a matrix." It is "prove, right now, that requirement 14 was tested and passed." If answering that means an engineer spends an afternoon reconstructing links, then traceability is not a property of your system. It is a performance you put on when asked. And the whole point of traceability is that it is meant to be continuous, the way version control is continuous. You do not rebuild your git history before an audit. You should not be rebuilding your requirement-to-test history either.
Traceability is a graph problem wearing a document costume
Here is the reframe that changed how I build this. A matrix is a flat view of something that was never flat. The real structure is a graph. A requirement has acceptance criteria. Each criterion is verified by one or more tests. Each test carries a pass or fail history. Defects link back to the criterion that was too vague to catch them. The "matrix" is just one projection of that graph, the row-and-column view an auditor likes to read.
Store the links as a graph and the matrix becomes a query instead of a craft project. Better still, the gaps become a query too.
# The audit question, expressed as a query over the graph:
# "Which requirements have no passing test?" That is the first thing an auditor hunts for.
requirement
-> acceptance_criteria
-> verified_by(tests where status = passing) # the actual proof
WHERE count(verified_by) == 0 # the hole in your coverage
# If this returns rows, your matrix has gaps. Run it in CI, not in March.
The day that query runs in your pipeline instead of in a spreadsheet, traceability stops being an event and turns into a property. A requirement that merges without a linked passing test fails the build, the same way an untested path can fail a coverage gate. You are not preparing for the audit. You are continuously sitting in the state the audit checks for.
What this looks like on a normal Tuesday
You do not need a graph database and a research team to start. You need a stable identity for each requirement and the discipline to link the test back to that identity, not to a free-text title that someone will reword next sprint. A convention as dumb as REQ-IDs in your test names, plus a script that diffs the set of requirements against the set of referenced IDs, will catch most missing links. The tooling matters less than the rule: a requirement is not done when the code merges, it is done when a test references it by ID and passes.
It also forces a distinction the spreadsheet hides. Test coverage and requirement coverage are not the same number. You can sit at 90 percent line coverage and still have a requirement that nothing verifies, because coverage counts code, not promises. The graph counts promises, which is the thing the auditor actually came to check.
Where the heavyweight tools genuinely win
I am not going to tell you to rip out a validated toolchain. If you are in medical devices or aerospace and you already run something like Polarion or DOORS inside a qualified, auditor-accepted process, that tooling is part of your validation, and replacing it is itself an audit risk nobody on a sales call will warn you about. The same goes for a mature Jira setup with Xray or Zephyr that your auditors already accept. The integration may be clunky, but clunky and accepted beats elegant and unproven when a regulator is in the room.
Jira also still wins on deep custom workflows and the size of its marketplace. If your compliance process genuinely needs forty fields and a fourteen-state approval, the lighter tools will fight you the whole way. And in fairness to the tools that do not pretend, Notion and Linear are honest about not being compliance systems. Linear tracks issues better than almost anything and makes no claim to be your system of record for an audit. Do not bolt a traceability process onto a tool built to be fast and opinionated about tickets, because you will spend your life maintaining the duct tape.
Where I landed
After enough of those 9pm spreadsheets, I stopped treating the matrix as a document to produce and started treating it as a graph to maintain. That is the thesis I built Stride around: stories, acceptance criteria, tests, and defects live as linked nodes on one graph, so the matrix is a live view and the gaps surface while you work instead of the week before the auditor lands. I am the founder, so read that with the salt it deserves. The principle does not depend on my product. You can start tomorrow with REQ-IDs and a diff script. The goal is to make traceability continuous instead of heroic.
So I will put it to the people who have actually survived an audit: what is the worst traceability gap you found at the worst possible moment, and when you fixed it, did you fix the process or just patch the spreadsheet? I am collecting the failure modes, because they teach more than any vendor checklist.
Top comments (0)