Requirements Traceability¶
This directory holds the generated requirements-traceability matrix and its manual
curation. The matrix mechanically links every software requirement
(REQ-<GROUP>-NNN, defined in ../requirements/) to the test,
implementation, and commit evidence that it is realized — the REQ ↔ test /
REQ ↔ code leg of the traceability chain described in the
verification plan.
Files¶
| File | Purpose |
|---|---|
matrix.md |
Generated snapshot. One table per requirement group plus status counts, prominent GAP / implemented-untested lists, and the PQ-journey provenance block. Do not hand-edit. |
overrides.tsv |
Manual curation: declares requirements that are legitimately not code-traced yet (future by plan, not-applicable, or an accepted gap) so they are not reported as raw gaps. |
How statuses are derived¶
For each requirement, in this precedence order:
superseded— the requirement row is struck through (~~…~~) with a successor annotation (e.g.REQ-LC-005 → REQ-LC-016). Superseded always wins.- override (
future/not-applicable/accepted-gap) — an entry inoverrides.tsvmatches the id. An exact-id entry beats a prefix wildcard. verified— the id is cited in a test source (backend/*/src/test/**/*.kt,backend/api/src/main/webui/e2e/**).implemented-untested— the id is cited only in implementation sources (backend/*/src/main/**/*.kt, Flyway migrations,backend/api/src/main/webui/src/**).GAP— no citation and no override. These are the actionable traceability gaps.
Commit citations (from git log) are collected per requirement and shown for context,
but they do not by themselves confer verified / implemented status — only the
code scan does.
The two evidence columns: isolated tests and the PQ walk¶
The matrix carries two evidence columns, and the distinction is the one a customer's auditor makes:
- Test evidence — the tests that check the requirement IN ISOLATION (GAMP's operational qualification register). Derived from the id citations described above; it is what drives the status column.
- PQ evidence — the station of the executable validation journey (ADR-0101) in which the
same requirement was exercised as part of the WHOLE workflow, rendered as
PQ: station 7 (…). Performance qualification: not "the feature works", but "the intended use works, and this requirement held while it did".
The PQ column is derived from the journey's OWN output — a run declares per station which
requirement ids its assertions exercised and writes them into its evidence bundle as
journey-requirements.json; the generator reads the newest bundle it can find, preferring nothing
and inventing nothing:
| Where | What it is |
|---|---|
backend/api/build/validation-journey/<version>-<run stamp>/ |
The latest local run (build output, not committed). |
docs/validation/journeys/<version>/ |
A bundle promoted for a release — the durable reference (see ../validation/journeys/README.md). |
The newest run by its recorded timestamp wins. When no bundle exists at all, the matrix says
"No PQ run recorded" in its own section: an empty PQ column must never be mistakable for a walk
that found nothing. A requirement id a bundle names but the requirement tables do not contain is
reported in that section too, never silently dropped. PQ evidence never changes a requirement's
status — the status column stays the OQ derivation, so the PQ column can be read as the independent
second opinion it is.
The overrides file¶
overrides.tsv is tab-separated: pattern<TAB>status<TAB>reason.
- pattern — an exact id (
REQ-TRN-001) or a prefix wildcard (REQ-TRN-*). - status — one of
future,not-applicable,accepted-gap. - reason — why this is not a real gap, pointing at the release plan, an ADR, or
docs/ai/STATUS.md(e.g. "layer 2 per ADR-0006").
Add an override only for a requirement with no code citation (run the scanner first);
anything unimplemented that cannot be justified from the design docs stays a raw GAP
rather than being papered over.
How and when to regenerate¶
python3 scripts/generate-traceability.py # rewrite matrix.md
python3 scripts/generate-traceability.py --summary # print counts + GAP list (no write)
The generator uses the Python 3 standard library only and produces deterministic output;
the sole non-reproducible datum is the generated from commit <short-sha> line derived
from git HEAD. It is a report, not a gate: gaps never cause a non-zero exit (only a
malformed requirement table or overrides file does). CI runs --summary for visibility
without ever failing the build on gaps; if the CI checkout is shallow, the commit-evidence
column reflects only the available history and the matrix header says so.
Regenerate and commit matrix.md:
- at every requirements baseline bump (a new
requirements-vX.Ytag), and - before audits and stakeholder demos.
The matrix is a point-in-time snapshot; the git history of matrix.md shows how the
verification status of each requirement evolved across baselines.