Traceability from CRF to table, and the three places it breaks
Traceability is the property that lets someone take a number in a table and walk it back to the value a site typed into a form. Everyone designs for it. Under audit it tends to hold cleanly from CRF to SDTM, hold reasonably from SDTM to ADaM, and then thin out at three specific joints.
One: the derivation that reaches sideways
ADaM's traceability model assumes a derived value can be traced to its predecessor records. That works for derivations that operate within a subject and within a domain. It works less well for derivations that reach across domains or across subjects.
A baseline defined as the last non missing value before first dose depends on exposure data to establish the dose date, on the vital signs domain for the values, and on a rule about what counts as non missing. The resulting record carries a predecessor pointing at one of those, and the other two inputs are documented in prose somewhere else. Walk it back and the chain forks in a way the metadata does not describe.
The fix is not complicated but it is deliberate: derived records carry the supporting variables that were actually used in the derivation, not only the one that supplied the value. It costs some width in the dataset and it removes the fork.
Two: the population flag nobody re derives
Population flags are set once, usually early, sometimes partly by hand after a data review meeting. They then propagate into every table as a subset condition, and they are rarely recomputed after later data cleaning.
This creates a specific and awkward situation. A subject's data changes after the flags were set, the change would have altered their population membership, and the flag still says what it said in March. Every table using that flag now has a subject in or out for a reason that is no longer supported by the data. The number is defensible only by reference to a meeting minute.
Recomputing flags from the current data on every run, and reporting differences against the previously agreed set, turns this from an invisible inconsistency into a short list somebody signs off.
Anything set by human judgement and then frozen needs a recompute and a diff, or it silently stops matching the data it describes.
Three: the last step into the table
The chain from raw to SDTM to ADaM is usually well documented. The step from ADaM to the number printed in a table is often the least documented step of all, and it is the one the reviewer sees first.
Table programs apply filters, handle rounding, decide how to present missing categories, and choose denominators. Those decisions are real analytical choices, and they typically live only in the table program and a line of shell text. A percentage in a table can differ from what a reader calculates from the ADaM dataset purely because the denominator excluded something the reader included.
Carrying those choices into the analysis dataset, so the table program does as little as possible beyond formatting, removes most of this. Where a decision has to live in the table program, it belongs in the metadata for that output rather than in the code alone.
Testing whether it holds
The most useful audit rehearsal we know is also the cheapest. Take three numbers from three different tables, chosen by someone who did not build them, and ask the team to trace each one back to the source record without reading the code. Give them an hour.
Where it takes ten minutes, traceability is real. Where it needs the programmer who wrote it, what exists is familiarity rather than traceability, and the two are easy to confuse right up until the person leaves.