skills/requirements/traceability-matrix-generator/SKILL.md
Builds a bidirectional traceability matrix linking requirements to design elements, code, and tests — so every requirement traces forward to its implementation and every test traces back to its justification. Use for compliance audits, when answering why a piece of code exists, or when checking that nothing was built without a reason.
npx skillsauth add santosomar/general-secure-coding-agent-skills traceability-matrix-generatorInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Traceability answers two questions: "What implements this requirement?" (forward) and "Why does this code exist?" (backward). The matrix is the answer in table form.
Requirement ──► Design element ──► Code ──► Test
▲ │
└─────────────────────────────────────────┘
(test verifies req)
Every link is a traceable edge. Gaps are rows with empty cells.
| Req ID | Requirement (brief) | Design | Code | Test | Status |
| ------ | ------------------- | ------ | ---- | ---- | ------ |
| REQ-1.1 | Rate limit: 100/min/user | RateLimiter component | middleware/ratelimit.py | test_ratelimit_100_per_min | ✓ |
| REQ-1.2 | Return 429 on limit | — | ratelimit.py:L45 | test_ratelimit_returns_429 | ✓ |
| REQ-2.1 | Audit all writes | AuditLogger | audit.py | — | ⚠ No test |
| REQ-3.4 | Support IPv6 | — | — | — | ❌ Gap |
requirement-coverage-checker techniques: grep for IDs, grep for domain terms, structural search.pytest --cov) tell you which tests hit which lines.Forward trace finds unimplemented requirements. Backward trace finds unrequired code:
| Trace type | Strength | Maintenance cost |
| ----------------------------------- | -------- | ----------------------------- |
| Explicit ID in code/test | Strong | Low — grep finds it |
| @covers("REQ-1.1") decorator | Strong | Low — machine-checkable |
| Mention in docstring | Medium | Medium — can drift |
| Structural match (inferred) | Weak | High — re-derive every audit |
For auditable systems: use explicit IDs. # REQ-1.1 in the code, @pytest.mark.req("1.1") on the test. Then the matrix is a grep, not an archaeology dig.
Convention in this codebase: tests carry @pytest.mark.req("X.Y"); code has # REQ-X.Y comments.
# middleware/ratelimit.py
# REQ-1.1, REQ-1.2
@app.middleware("http")
async def ratelimit(request, call_next):
...
# tests/test_ratelimit.py
@pytest.mark.req("1.1")
def test_ratelimit_allows_100_per_minute(): ...
@pytest.mark.req("1.2")
def test_ratelimit_returns_429_on_excess(): ...
Matrix generation (scripted):
import re, ast, pathlib
reqs = load_requirements("spec.md") # {id: text}
code_traces = {} # {req_id: [file:line, ...]}
test_traces = {} # {req_id: [test_name, ...]}
for f in pathlib.Path("src").rglob("*.py"):
for lineno, line in enumerate(f.read_text().splitlines(), 1):
for rid in re.findall(r"REQ-(\d+\.\d+)", line):
code_traces.setdefault(rid, []).append(f"{f}:{lineno}")
for f in pathlib.Path("tests").rglob("*.py"):
tree = ast.parse(f.read_text())
for node in ast.walk(tree):
if isinstance(node, ast.FunctionDef):
for dec in node.decorator_list:
# match @pytest.mark.req("X.Y")
if (isinstance(dec, ast.Call) and ast.unparse(dec.func) == "pytest.mark.req"):
rid = dec.args[0].value
test_traces.setdefault(rid, []).append(f"{f.name}::{node.name}")
# Emit matrix
for rid, text in reqs.items():
code = code_traces.get(rid, [])
tests = test_traces.get(rid, [])
status = "✓" if code and tests else ("⚠" if code else "❌")
print(f"| {rid} | {text[:40]} | {', '.join(code) or '—'} | {', '.join(tests) or '—'} | {status} |")
Mechanical, reproducible, runs in CI.
auth.py implements 30 requirements — that's not a trace, that's a guess. Trace to functions or regions.## Matrix
| Req ID | Requirement | Design | Code | Test | Status |
| ------ | ----------- | ------ | ---- | ---- | ------ |
## Gaps (forward — unimplemented)
| Req ID | Missing | Action |
| ------ | ------- | ------ |
## Orphans (backward — unjustified code)
| Code | Classification | Action |
| ---- | -------------- | ------ |
| <func> | Implicit infra | None — expected |
| <func> | Undocumented req | Add REQ-X.Y to spec |
| <func> | Speculative | Consider removal |
## Trace strength
Explicit (tagged): <N> Inferred: <M> — lower M by tagging
## Regeneration
<command to rebuild this matrix — goes in CI>
development
Extracts human-readable pseudocode from a verified formal artifact (Dafny, Lean, TLA+) while preserving the verified properties as annotations, so the proof-carrying logic can be reimplemented in a production language. Use when porting verified code to an unverified target, when documenting what a formal spec actually does, or when handing a verified algorithm to an implementer.
development
Translates natural-language or pseudocode descriptions of concurrent and distributed systems into TLA+ specifications ready for the TLC model checker. Identifies state variables, actions, type invariants, safety properties, and liveness properties from the description. Use when formalizing a protocol, when the user describes a distributed algorithm to verify, when designing a consensus or locking scheme, or when starting formal verification of a concurrent system.
testing
Reduces a TLA+ model so TLC can actually check it — shrinks constants, adds state constraints, abstracts data, or applies symmetry — when the state space is too large to enumerate. Use when TLC runs out of memory, when checking takes hours, or when a spec works at N=2 and you need confidence at larger scale.
development
TLA+-specific instance of model-guided repair — reads a TLC error trace, identifies the enabling condition that should have been false, strengthens the corresponding action, and maps the fix to source code. Use when TLC reports an invariant violation or deadlock and you have the code-to-TLA+ mapping from extraction.