The matrix
- Cell a person typed requirement ↔ test
- Later the function moved
Topic · Traceability
Proof rebuilds the matrix from the specs and the code. A link that went stale fails CI instead of staying a green cell nobody re-checked.
proof audit --check spec_lint_ac_subset_of_satisfies --check spec_lint_ac_inverse_coverage
DOORS, Jama, and Polarion store the links a person asserted. They never re-read the code. That is the gap this page is about.
01 · What a matrix is
Down one axis, the requirements. Across the other, the artifacts that are supposed to satisfy them: design, code, tests. A cell is filled when a link exists. One direction is coverage. The other is the inverse: does this code still trace up to a requirement anyone asked for, or is it orphaned.
Safety standards make this explicit. NASA SWE-134 requires bidirectional traceability between requirements, design, code, and test cases. DO-178C and ISO 26262 require the same for certified avionics and automotive software. The unit is a single row: FSW-REQ-0100 → FRET:FSW-REQ-0100 → test case → code location.
02 · The database
IBM Rational DOORS, Jama Connect, Siemens Polarion: good at storing requirements, versioning them, capturing links, and running change-impact analysis. If you search for a requirements traceability matrix tool, this is what you get, and for authoring it is the right answer.
When the engineer wrote REQ-0100 → cache.go:118, it was true. Six months and forty commits later the function moved and nobody reopened the tool. The matrix still shows green. The database has no way to know, because it never reads the code. It only stores what it was last told. That is the failure mode every hand-maintained matrix drifts into: it records the intent that was true, not the code that is true now.
03 · The exhibit
The last column is the one a requirements database cannot fill on its own, because it requires re-reading the code.
The matrix
The binary
Nobody re-read session.go.
StaleThe matrix
Still green. The database was not told.
Green cellProof
Same link. Two truths. Click the tabs.
| Requirement | Satisfied by | Verified by | Re-checked against source? |
|---|---|---|---|
| STK-REQ-004 · session times out after idle | SYS-REQ-870 → session.go:74 |
TestIdleTimeout |
Yes. Link holds. |
| STK-REQ-004 · same, decomposed child | SYS-REQ-879 → session.go:112 |
TestReauthOnResume |
No. Child satisfies the parent but is missing from its acceptance criteria. |
The first row is what every tool shows: a filled, green cell. The second row is filled and green in a hand-maintained matrix too, and it is wrong. A person reading DOORS sees full coverage. The inverse-coverage check reads the satisfies back-links and reports the drift.
spec_lint_ac_inverse_coverage specs/stakeholder/requirements/STK-REQ-004.req.yaml:49 SYS-REQ-879 satisfies STK-REQ-004 but appears in none of its acceptance_criteria[*].derived_reqs. The AC decomposition under-reports the actual fan-out.
04 · The command
Requirements carry structured links in their spec. The audit re-derives the matrix from those links and the code on every run. Two checks guard the two directions.
proof audit --check spec_lint_ac_subset_of_satisfies \
--check spec_lint_ac_inverse_coverage
spec_lint_ac_subset_of_satisfies catches a stakeholder requirement whose acceptance criteria cite a child that has since disowned it. spec_lint_ac_inverse_coverage catches the opposite: a system requirement that really satisfies the parent while the acceptance-criteria list silently forgot it. Reviewers sign off on a five-child decomposition while thirty children hang off the parent.
05 · The honest loss
These checks verify that the matrix is internally consistent: every asserted satisfies link is reflected on both sides and still points at real code. They say nothing about whether the requirement described the behavior you needed.
On the public jsonparser audit, a defect shipped in code that carried full structural coverage, because nobody had written the requirement for the case that broke. An unspecified partition is not in any check's denominator. A traceability matrix, re-derived or not, measures the links between the artifacts that exist. It cannot invent the requirement no one thought to write.