Concept
Requirements traceability, forward and backward
How code links back to a business decision, and how a business decision links forward to a test.
Last updated
Without recorded traceability, teams must reconstruct why code exists from developers’ memories and past conversations. That evidence can disappear when people leave.
A Code Node links a source file or symbol to the acceptance criteria it implements. Each criterion
links to a user story, each story to a requirement, and each requirement to a business decision.
rcf trace follows these links from a source path in one command.
What is requirements traceability for AI coding agents?
Requirements traceability for AI coding agents is the ability to walk from any line of code back to the business decision that put it there, and forward from any decision to every test that proves it ships. The mechanics are identical to traceability in any other context. The reason it matters more now is that AI agents will happily generate code with no anchor to intent. Traceability is what supplies the anchor.
How do you keep AI-generated code from drifting?
You keep AI-generated code from drifting by giving the agent a contract it has to satisfy and a chain that records the satisfaction. Acceptance criteria written ahead of code. Test cases that pin one-to-one to those criteria, inside a test suite on the parent user story. Build stages that commit in order. Traceability records the relationships between those checks. Without it, the agent has nothing to drift away from and nothing that catches the drift when it happens.
Two directions, both load-bearing
Traceability runs in both directions, and each direction answers a different kind of question.
Forward. Start at the top of the chain and walk down. Given requirement REQ-019, what user stories does it have? Given those stories, what acceptance criteria? Given those criteria, what test suites? Given those suites, are they green? Forward tracing answers questions like is this requirement actually shipped, which tests do I need to run if this requirement changes, and what part of the product would I lose if I cut this requirement.
Backward. Start at a leaf and walk up. Given this failing test, what acceptance criterion does it cover? Given that criterion, what story does it belong to? Given the story, what requirement? Given the requirement, why does it exist in the PRD? Backward tracing answers questions like why does this code exist, which customer commitment does this test protect, and what business decision was being made when this constraint went in.
Forward tracing is what product owners and stakeholders ask. Backward tracing is what engineers and reviewers ask. The chain serves both. The cost of serving both, once the chain is in place, is roughly zero.
How the chain physically supports this
Every artefact in the chain carries an opaque string ID. PRD-001. REQ-019. US-088. AC-088-02. TAD-001. FBS-051. TS-088-02. The IDs are stable: never renumbered, never reused, never reissued. Each artefact carries pointers to its neighbours: stories point at their parent requirement, ACs point at their parent story, suites point at their AC.
Traceability uses stable IDs and reference fields. Maintaining it requires two rules: never reuse an ID and never allow a reference to become stale.
A test suite references its AC ID in its name or metadata. Code annotations previously provided a searchable reference, but nothing checked whether the referenced file or function still existed after a rename, move or deletion.
A Code Node records a source path, optionally with a #symbol, and the acceptance
criteria it implements. rcf validate checks the file and named symbol against the
working tree. Missing source produces a located staleCode error that a one-field edit
can resolve.
What forward tracing actually looks like
Imagine a product owner asks: show me that user data export is implemented. With the chain in place, this is a three-step query.
Step one. Find the requirement. The PRD’s requirements list shows REQ-019, “Users can export their data,” functional, must-have, domain: privacy.
Step two. Pull every story for REQ-019. There’s one: US-088, “As a user I want to download my data so that I can take it elsewhere.”
Step three. Pull every AC on US-088, and find their test suites. AC-088-01 (happy path), AC-088-02 (size cap), AC-088-03 (format). Three suites, all green on the last CI run.
The product owner receives a one-page account of coverage, current as of the last build. The team does not need a meeting to reconstruct the export feature from code.
What backward tracing actually looks like
A test suite goes red after a refactor. The test is TS-088-03, and the engineer who broke it didn’t write it and doesn’t remember what it’s for. With the chain in place, the question “why does this test exist” is a four-hop query.
TS-088-03 implements AC-088-03. AC-088-03 says exports must be in CSV or JSON, never proprietary formats. AC-088-03 belongs to US-088. US-088 is part of REQ-019. REQ-019 is in the PRD as a privacy must-have.
The test protects a customer privacy commitment that the refactor has broken. Restore the format guarantee in the implementation. The chain provides the evidence for that decision.
What changes when a requirement changes
A requirement change can affect several stories, acceptance criteria and suites.
Without traceability, the team must estimate which stories and tests are affected. Missed dependencies can cause regressions in related features.
Trace every story under the changed requirement, every AC under those stories and every suite for those ACs. This identifies the affected work. Some suites need new cases, some need deletion and some need their underlying AC restated.
What changes when an AC changes
ACs change too, often more than requirements do. The mechanics are the same. An AC pins to exactly one test case. Change the AC, that case needs updating, and the change is contained.
The discipline matters here. When an AC changes, the test case should be updated first, then the implementation. Update the case to reflect the new criterion (which probably makes it fail). Make the implementation pass against the new case. Commit both. This order keeps verification aligned with the criterion. Update the implementation first and you risk shipping code that satisfies the old AC while the new AC is still aspirational.
The limits of traceability
Traceability establishes a chain from a business decision to a passing test. It cannot prove that the test is adequate. Weak criteria produce weak suites, even when every link is valid.
Traceability also doesn’t cover side effects. A line of code that satisfies its AC may also touch something it shouldn’t. The build cycle catches some of that in the Test stage, when the whole suite runs and unrelated tests catch the bleed. Some of it gets caught in code review. Some of it gets caught in production. The chain narrows the search; it doesn’t eliminate the work.
A refactor can preserve passing tests while breaking a specification reference. If a module moves or
a symbol is renamed, an outdated Code Node fails validation with a staleCode error. The
test suite may not detect that broken link.
A Code Node verifies that a path and named symbol exist. It does not verify their behaviour.
Removing a guard clause while keeping the function name can leave rcf validate passing.
Tests and reviewers must detect that semantic change.
Maintaining the links is essential. Renumbering an ID breaks its references. A story without a requirement is an orphan, and an AC without a suite lacks verification. RCF projects use validators on commit to detect these failures.
What traceability cashes out as, day to day
The chain preserves decisions as the project ages. It helps prevent duplicate work, supplies evidence for product owners and identifies the tests and customer commitments affected by deprecation.
These questions can be answered by querying recorded relationships instead of relying on memory or seniority.