Any software used in a regulated environment — under 21 CFR Part 11, EU Annex 11, or GAMP 5 — must be formally qualified before it can be used to generate or sign electronic records that regulators may inspect. This applies to R packages used in clinical data analysis, regulatory submissions, or GxP quality systems just as much as it applies to validated LIMS or EDC systems.
Qualification follows a three-phase structure that has been standard in the pharmaceutical industry for decades:
- Installation Qualification (IQ) — evidence that the software is installed correctly in this specific environment, with the correct version and its dependencies intact.
- Operational Qualification (OQ) — evidence that the software operates as specified across all relevant functions, including boundary conditions, negative tests, and every control required by the applicable regulation.
- Performance Qualification (PQ) — evidence that the software performs reliably under realistic, end-to-end conditions representative of actual use.
In practice, the bottleneck is almost always the protocol authoring step. Writing IQ/OQ/PQ scripts from scratch, getting them reviewed and approved, and assembling the traceability matrix that links each test to a regulatory requirement is time-consuming work — even for straightforward packages.
regulog ships pre-written, executable qualification protocols for all three phases. They are version-controlled alongside the package, updated with every release, and produce a self-contained pass/fail record your team can retain as documented evidence of system qualification.
What the protocols cover
| Protocol | Regulatory basis | Tests | What is verified |
|---|---|---|---|
| IQ | GAMP 5 IQ phase | 10 | R version, package installation, dependency integrity (digest, jsonlite), file system access, namespace exports for all v0.2.0 functions |
| OQ | 21 CFR §11.10(a)(b)(c)(e), §11.50, §11.100, §11.200 · EU Annex 11 §9, §11 | 26 | Genesis hash integrity, chain linkage, tamper detection, user attribution, timestamps, before/after change capture, blank reason rejection, CSV/JSON export, date filtering, disk persistence, monotonic entry IDs, log_note, log_signature identity and coverage, with_log error isolation |
| PQ | 21 CFR Part 11 end-to-end · EU Annex 11 | 7 | Clinical data review workflow, signed regulatory export, multi-user session independence, 500-entry load test with full chain verification, file-level tamper detection, annotated clinical analysis with electronic signature, inspector query simulation |
The OQ maps explicitly to regulatory clauses. The full traceability matrix linking every test to its requirement is included with the package:
read.csv(system.file("validation/RTM_regulog.csv", package = "regulog"))
Running the qualification
Run each script in sequence in the target environment — the R installation that will be used for regulated work:
# Phase 1: Installation Qualification (10 tests)
source(system.file("validation/IQ_regulog.R", package = "regulog"))
# Phase 2: Operational Qualification (26 tests)
source(system.file("validation/OQ_regulog.R", package = "regulog"))
# Phase 3: Performance Qualification (7 tests)
source(system.file("validation/PQ_regulog.R", package = "regulog"))
Capturing the qualification record
The output of each run — including platform, R version, date, and pass/fail status of every test — should be retained as documented evidence. The simplest approach:
sink("IQ_execution_record.txt")
source(system.file("validation/IQ_regulog.R", package = "regulog"))
sink()
sink("OQ_execution_record.txt")
source(system.file("validation/OQ_regulog.R", package = "regulog"))
sink()
sink("PQ_execution_record.txt")
source(system.file("validation/PQ_regulog.R", package = "regulog"))
sink()
Logging the qualification itself
The qualification run is itself an activity in a regulated environment. Using regulog to audit its own qualification produces a Part 11-compliant record of who ran it, when, and the outcome:
library(regulog)
log <- regulog_init(
app = "regulog-qualification",
version = "0.2.0",
user = "val.lead",
path = "qualification/audit_trail.rlog"
)
log_action(log,
action = "qualification_start",
object = "regulog 0.2.0",
reason = "IQ/OQ/PQ qualification initiated per SOP-VAL-007"
)
source(system.file("validation/IQ_regulog.R", package = "regulog"))
log_action(log,
action = "IQ_complete",
object = "IQ_regulog.R",
reason = "10 tests passed. Proceeding to OQ."
)
source(system.file("validation/OQ_regulog.R", package = "regulog"))
log_action(log,
action = "OQ_complete",
object = "OQ_regulog.R",
reason = "26 tests passed. Proceeding to PQ."
)
source(system.file("validation/PQ_regulog.R", package = "regulog"))
log_action(log,
action = "PQ_complete",
object = "PQ_regulog.R",
reason = "7 tests passed. Qualification complete."
)
log_signature(log,
"I certify that regulog 0.2.0 has been qualified in this environment
per SOP-VAL-007 and is approved for use in regulated R workflows."
)
verify_log(log)
export_audit_trail(log,
format = "csv",
signed = TRUE,
path = "qualification/audit_trail_export.csv"
)
Re-qualification
Any significant change — a new package version, a change to the R environment, or a platform migration — requires re-qualification. Re-run the three protocols in the updated environment and retain the new execution records as evidence that the qualified state has been re-established.
Questions or corrections — hello@reprostats.org.