REDCap logoProblem

Nobody Diffs the Codebook

Somewhere in the second year of a study, a monitoring meeting stalls on a question that should be trivial: was the systolic blood pressure field always integer-validated, or did that change after the pilot?

Nobody Diffs the Codebook

Somewhere in the second year of a study, a monitoring meeting stalls on a question that should be trivial: was the systolic blood pressure field always integer-validated, or did that change after the pilot?

What happens next is the same everywhere. Someone opens a shared folder holding nine downloads of the same data dictionary, each with a different date. Someone else pulls two of them into a spreadsheet side by side — four hundred rows, eighteen columns — and starts scrolling. Twenty minutes later the meeting has an answer that everyone treats as provisional.

REDCap hands you a Download button for the data dictionary. It does not hand you a diff button. Much of what goes wrong with a long-running project's schema traces back to that one missing capability.

The dictionary is already a schema

This is the part worth sitting with: the information is not missing from the file. A REDCap data dictionary declares, in machine-readable form, most of what a schema is supposed to declare.

Instruments are types. Variables are fields. A radio, dropdown, or checkbox choice list — written as 1, Male | 2, Female — is a controlled vocabulary with codes and labels. Required Field? = y is a not-null constraint. The first variable in the dictionary is the project's record id, which is to say its primary key. Text validation types and field types are data types under another name: integer, number, date_ymd, yesno, calc. The Identifier? column marks protected health information. Branching logic describes when a field is even asked.

All of it formal. All of it unenforced. The file gets treated as configuration because it arrives as a spreadsheet, and configuration is something you edit, not something you review.

Three edits, three different kinds of damage

A choice list moves. Someone adds a category, or retires one that was never used, or splits an ambiguous option in two. Adding a value widens what the field can mean; removing one narrows it, and quietly orphans every record already coded that way. Both are legitimate study decisions. Both change what a downstream consumer may assume. Neither announces itself.

A validation type changes. A field validated as integer is relaxed to free text because one site needed to enter "not measured." From that moment the column holds two kinds of thing, and every script that assumed a number is wrong in a way that produces results rather than errors.

A variable disappears. An instrument is restructured and a field is dropped. The analysis plan still references it. The harmonization script still selects it. Nothing fails until someone runs the export, and by then the conversation is about recovery rather than about design.

Some mistakes cannot be fixed after collection

Two are worth naming because they are silent and permanent.

A choice list can reuse a code. REDCap accepts it, the form works, and the export is faithful — two different labels arriving as the same number. Once participants have been coded against that list, no amount of later cleanup recovers which answer a given record actually gave. The data is ambiguous in a way that is not repairable.

A free-text field with no validation type accumulates "45", "45 yrs", "forty-five", and "unknown" in the same column. Every one of those is a legitimate entry against the field as defined. All of them together resist every downstream computation, and harmonizing them later is guesswork performed on someone's health record.

PHI is a column, not an inventory

The Identifier? column marks identifying fields one row at a time. That is fine as a data-entry convention and useless as an answer to the question people actually ask: which fields in this project carry PHI?

Answering it means re-reading the dictionary, every time — for a data-sharing request, for an export to a collaborator, and now for the newest consumer in the building, an AI assistant that will happily read whatever column it is handed. The information exists. It has never been assembled.

The same form, six times

Multi-site studies multiply all of this. Six sites deploy "the same" instrument; six dictionaries drift apart at six different rates. One site adds a choice, another skips a validation type, a third renames a variable so it sorts better in reports. Every deviation stays invisible until harmonization, when someone reconstructs what each site was actually collecting from exports that all claim to be the same form.

Why the obvious fix does not happen

The obvious fix — point a tool at the REDCap instance and let it watch — usually dies in the first conversation, and it should. The person who owns a study is rarely the person who administers the instance. The instance sits next to identifiable participant data. Handing a third-party service live API credentials in that setting is not a governance improvement.

So governance here has to work on the artifact and hold nothing. That is exactly how we built the CoreModels REDCap connector (vendor key redcap): the only input is the data_dictionary CSV you can already download from Project Setup, or export yourself with your own token, locally. No credentials ever reach us, and there is no live connection to your instance. Columns are matched by header keyword, so a lightly renamed export still parses.

What checking the file actually buys

Once the dictionary is a model rather than a download, the questions above stop being archaeology. Any dictionary — today's export, a proposed amendment, a collaborating site's version — can be audited against the governed model in seconds, read-only, and comes back with findings that carry stable codes rather than prose: coverage findings for instruments and fields nobody has governed yet; drift findings when a type changed or a value set narrowed or a field vanished; and REDCap conformance findings aimed at precisely the pathologies above — a PHI inventory per instrument that names the identifier fields, a flag on every free-text field with no validation type, and a warning whenever a choice list reuses a code.

An error count above zero can fail a build, which means a dictionary change can be argued about before it reaches production rather than after it reaches the data.

None of that is a new standard operating procedure, a portal integration, or a change to how your team designs instruments. It is one decision: that the most consequential file in the study deserves the same treatment a software team gives a database migration.

The REDCap quickstart in the CoreModels integration docs walks the extraction, import, and audit loop end to end.