| Title: | Evidence, Privacy, and Lifecycle Controls for Physiological Records |
|---|---|
| Description: | Provides deterministic, tamper-evident audit trails, externally authenticated electronic signatures, explicit de-identification policies, project-owned lifecycle and risk-document templates, normalized requirement-risk-control-test traceability, objective-evidence verification, and read-only ecosystem engineering-readiness checks for PhysioExperiment records and packages. Reports expose structural, linkage, record-state, signature, privacy, traceability, and package-readiness findings without repairing stored evidence. These technical controls and documentation aids do not determine device status, assign risk acceptability, authorize release, or establish conformity with a regulatory framework or standard. |
| Authors: | Yusuke Matsui [aut, cre] |
| Maintainer: | Yusuke Matsui <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.4.2 |
| Built: | 2026-10-11 11:44:15 UTC |
| Source: | https://github.com/x-biosignal/PhysioCompliance |
Appends an event to a valid audit chain. A changed record may be appended when its historical chain remains valid; the new event then establishes the changed record as the current audited state.
appendAuditEvent( x, action, actor, reason, details = list(), timestamp = Sys.time() )appendAuditEvent( x, action, actor, reason, details = list(), timestamp = Sys.time() )
x |
An initialized PhysioExperiment::PhysioExperiment object. |
action |
Non-empty domain action. Names beginning with
|
actor |
Non-empty identifier for the responsible actor. |
reason |
Non-empty reason for the action. |
details |
A recursively named plain list containing supported atomic values. Named lists are sorted before hashing. |
timestamp |
One finite |
A modified copy of x with one additional event.
x <- PhysioExperiment::PhysioExperiment( assays = list(raw = matrix(1:6, nrow = 3)), samplingRate = 100 ) x <- initializeAuditTrail(x, actor = "operator-01") x <- appendAuditEvent( x, action = "quality_control", actor = "operator-01", reason = "reviewed acquisition quality" ) verifyAuditTrail(x)x <- PhysioExperiment::PhysioExperiment( assays = list(raw = matrix(1:6, nrow = 3)), samplingRate = 100 ) x <- initializeAuditTrail(x, actor = "operator-01") x <- appendAuditEvent( x, action = "quality_control", actor = "operator-01", reason = "reviewed acquisition quality" ) verifyAuditTrail(x)
Rescans supported metadata and validates the stored report. A passing result means that this checker found no configured residual identifier; it is not a HIPAA, GDPR, Safe Harbor, or file-format compliance determination.
auditDeidentification(x, policy = NULL)auditDeidentification(x, policy = NULL)
x |
A supported de-identified PhysioCore record. |
policy |
Optional effective policy. When omitted, a built-in policy matching the stored label is used. |
A list containing status, findings, severity counts, and check time.
x <- PhysioExperiment::PhysioExperiment( assays = list(raw = matrix(1:6, nrow = 3)), colData = S4Vectors::DataFrame(patient_name = c("A", "B")), samplingRate = 100 ) clean <- deidentify(x, safeHarborPolicy()) # A pass means no configured residual identifier was found; it is not a # HIPAA, GDPR, or Safe Harbor determination. auditDeidentification(clean)$statusx <- PhysioExperiment::PhysioExperiment( assays = list(raw = matrix(1:6, nrow = 3)), colData = S4Vectors::DataFrame(patient_name = c("A", "B")), samplingRate = 100 ) clean <- deidentify(x, safeHarborPolicy()) # A pass means no configured residual identifier was found; it is not a # HIPAA, GDPR, or Safe Harbor determination. auditDeidentification(clean)$status
Extract the compliance audit trail
auditTrail(x)auditTrail(x)
x |
A PhysioExperiment::PhysioExperiment object. |
An audit_trail data frame with a details list-column. An
uninitialized object returns a zero-row trail.
x <- PhysioExperiment::PhysioExperiment( assays = list(raw = matrix(1:6, nrow = 3)), samplingRate = 100 ) x <- initializeAuditTrail(x, actor = "operator-01") auditTrail(x)x <- PhysioExperiment::PhysioExperiment( assays = list(raw = matrix(1:6, nrow = 3)), samplingRate = 100 ) x <- initializeAuditTrail(x, actor = "operator-01") auditTrail(x)
This function statically parses package metadata and source. It does not load namespaces, execute package code, run tests, or launch external tools.
conformanceCheck( root, packages = NULL, criteria = conformanceCriteria(), coverage = NULL, external_results = NULL, applicability = NULL, checked_at = Sys.time() )conformanceCheck( root, packages = NULL, criteria = conformanceCriteria(), coverage = NULL, external_results = NULL, applicability = NULL, checked_at = Sys.time() )
root |
Repository or package root. |
packages |
Optional exact package-name filter. |
criteria |
Project criteria from |
coverage |
Caller-supplied coverage evidence or |
external_results |
Caller-supplied external check evidence or |
applicability |
Reviewed applicability decisions or |
checked_at |
Fixed check timestamp. |
A deterministic conformance_report.
Thresholds are project policies for an engineering-readiness check. They are not regulatory thresholds or clauses of a standard.
conformanceCriteria(example_floor = 0.5, coverage_floor = 0.8)conformanceCriteria(example_floor = 0.5, coverage_floor = 0.8)
example_floor |
Minimum fraction of documented exports with examples. |
coverage_floor |
Minimum caller-supplied line coverage. |
A conformance_criteria data frame.
criteria <- conformanceCriteria() criteria[, c("criterion_id", "default_applicability", "threshold")]criteria <- conformanceCriteria() criteria[, c("criterion_id", "default_applicability", "threshold")]
Builds a no-content plan before authorization. Applying the plan changes only the returned in-memory collection; it does not delete files, databases, backups, replicas, caches, or remote systems. Identity verification, applicable legal bases, Article 17 exceptions, retention obligations, and operational deletion remain controller responsibilities.
dataSubjectErase( records, subject_id, locate, authorize, retain = NULL, reason, mode = c("plan", "apply") )dataSubjectErase( records, subject_id, locate, authorize, retain = NULL, reason, mode = c("plan", "apply") )
records |
A named plain list of records. |
subject_id |
One requested subject identifier. |
locate |
A callback called exactly once per record. |
authorize |
A callback invoked exactly once in apply mode with the plan. |
retain |
Optional callback returning a non-empty retention reason or
|
reason |
Non-empty operational reason. It must not contain the subject identifier. |
mode |
Build a no-op plan or apply an authorized plan. |
A data_subject_erasure plan or applied result.
records <- list( visit_01 = list(subject = "S1"), visit_02 = list(subject = "S2") ) # Plan mode builds a no-content plan and performs no deletion; apply mode # changes only the returned in-memory collection, never files or backups. plan <- dataSubjectErase( records, "S1", locate = function(record) record$subject, authorize = function(plan) TRUE, reason = "verified erasure request", mode = "plan" ) plan$planrecords <- list( visit_01 = list(subject = "S1"), visit_02 = list(subject = "S2") ) # Plan mode builds a no-content plan and performs no deletion; apply mode # changes only the returned in-memory collection, never files or backups. plan <- dataSubjectErase( records, "S1", locate = function(record) record$subject, authorize = function(plan) TRUE, reason = "verified erasure request", mode = "plan" ) plan$plan
Selects records through a caller-owned identity matcher and returns deep copies with a content manifest. Identity verification, the scope and format of an Article 15 response, third-party rights, and secure delivery remain controller responsibilities.
dataSubjectExport(records, subject_id, locate)dataSubjectExport(records, subject_id, locate)
records |
A named plain list of records. |
subject_id |
One requested subject identifier. |
locate |
A callback called exactly once per record. It returns one
subject identifier or |
A data_subject_export object.
records <- list( visit_01 = list(subject = "S1", note = "baseline"), visit_02 = list(subject = "S2", note = "baseline") ) # `locate` is a caller-owned identity matcher called once per record. dataSubjectExport(records, "S1", locate = function(record) record$subject)records <- list( visit_01 = list(subject = "S1", note = "baseline"), visit_02 = list(subject = "S2", note = "baseline") ) # `locate` is a caller-owned identity matcher called once per record. dataSubjectExport(records, "S1", locate = function(record) record$subject)
Derives one deterministic integer-day offset per subject using keyed HMAC-SHA-256. Exact elapsed intervals are preserved. Full shifted dates are pseudonymized personal data, not a HIPAA Safe Harbor output.
dateShift( dates, subject_id, key, range_days = c(-3650L, 3650L), inverse = FALSE )dateShift( dates, subject_id, key, range_days = c(-3650L, 3650L), inverse = FALSE )
dates |
A |
subject_id |
One subject ID or a vector aligned to |
key |
Raw vector of at least 32 cryptographically random bytes. |
range_days |
Inclusive integer offset range. |
inverse |
Apply the exact negative keyed offset. |
A vector with the same length and date class.
key <- openssl::rand_bytes(32) visits <- as.Date(c("2026-01-05", "2026-02-02", "2026-03-09")) # One deterministic per-subject offset; exact intervals are preserved. shifted <- dateShift(visits, subject_id = "subject-a", key = key) all(diff(shifted) == diff(visits))key <- openssl::rand_bytes(32) visits <- as.Date(c("2026-01-05", "2026-02-02", "2026-03-09")) # One deterministic per-subject offset; exact intervals are preserved. shifted <- dateShift(visits, subject_id = "subject-a", key = key) all(diff(shifted) == diff(visits))
Applies an explicit field policy while preserving the input S4 class. Assays are never inspected for identifying signal content; retained assays are therefore listed for manual review. Reports contain paths and counts, never removed values, keys, or re-identification material.
deidentify( x, policy = safeHarborPolicy(), subject_id = NULL, pseudonymization = NULL, date_key = NULL, audit_actor = NULL, audit_reason = "record de-identified" )deidentify( x, policy = safeHarborPolicy(), subject_id = NULL, pseudonymization = NULL, date_key = NULL, audit_actor = NULL, audit_reason = "record de-identified" )
x |
A |
policy |
A policy from |
subject_id |
A scalar or field-aligned subject identifier used only for keyed date shifting. |
pseudonymization |
A protected result from |
date_key |
A caller-owned raw key of at least 32 bytes. |
audit_actor |
Responsible actor when an input audit trail is initialized. |
audit_reason |
Non-empty reason stored in linked audit events. |
MultiPhysioExperiment and PhysioLongitudinal do not provide a
metadata slot. Their aggregate report is stored as a serializable
deidentification attribute, while every child PhysioExperiment keeps its
report in metadata(). Existing audit trails are linked per child.
A modified object of the same S4 class.
x <- PhysioExperiment::PhysioExperiment( assays = list(raw = matrix(1:6, nrow = 3)), colData = S4Vectors::DataFrame(patient_name = c("A", "B")), samplingRate = 100 ) # Changes only the returned in-memory object; stored evidence is not repaired. clean <- deidentify(x, safeHarborPolicy()) auditDeidentification(clean)$statusx <- PhysioExperiment::PhysioExperiment( assays = list(raw = matrix(1:6, nrow = 3)), colData = S4Vectors::DataFrame(patient_name = c("A", "B")), samplingRate = 100 ) # Changes only the returned in-memory object; stored evidence is not repaired. clean <- deidentify(x, safeHarborPolicy()) auditDeidentification(clean)$status
The callback is responsible for authenticating and authorizing the signer. It is called exactly once with canonical challenge bytes and a sanitized public credential descriptor. The package never accepts passwords, private keys, API tokens, or reusable secrets.
eSign(x, signer, meaning, credential, sign, timestamp = Sys.time())eSign(x, signer, meaning, credential, sign, timestamp = Sys.time())
x |
An initialized, currently valid PhysioExperiment::PhysioExperiment. |
signer |
Non-empty signer identity. |
meaning |
Non-empty signature meaning. |
credential |
Named list containing |
sign |
Function called once as |
timestamp |
One finite |
The callback's algorithm and credential service determine cryptographic strength, identity assurance, and non-repudiation properties. This function is a technical control and does not itself establish regulatory compliance.
A modified copy of x with one signature and one cross-linked audit
event.
x <- PhysioExperiment::PhysioExperiment( assays = list(raw = matrix(1:6, nrow = 3)), samplingRate = 100 ) x <- initializeAuditTrail(x, actor = "operator-01") # Signing is delegated to a caller-supplied callback. This illustrative one # hashes the challenge; a real deployment authenticates the signer and uses # its own credential service. The package stores no secrets. credential <- list(id = "credential-01", algorithm = "demo-sha256", fingerprint = "01:23:45:67") sign <- function(challenge, credential) { digest::digest(c(challenge, serialize(credential, NULL, version = 3)), algo = "sha256", serialize = FALSE, raw = TRUE) } x <- eSign(x, signer = "reviewer-02", meaning = "reviewed", credential = credential, sign = sign) verifyAuditTrail(x)$n_signaturesx <- PhysioExperiment::PhysioExperiment( assays = list(raw = matrix(1:6, nrow = 3)), samplingRate = 100 ) x <- initializeAuditTrail(x, actor = "operator-01") # Signing is delegated to a caller-supplied callback. This illustrative one # hashes the challenge; a real deployment authenticates the signer and uses # its own credential service. The package stores no secrets. credential <- list(id = "credential-01", algorithm = "demo-sha256", fingerprint = "01:23:45:67") sign <- function(challenge, credential) { digest::digest(c(challenge, serialize(credential, NULL, version = 3)), algo = "sha256", serialize = FALSE, raw = TRUE) } x <- eSign(x, signer = "reviewer-02", meaning = "reviewed", credential = credential, sign = sign) verifyAuditTrail(x)$n_signatures
Scrubs a named structured header without parsing or rewriting a binary file. The DICOM-adjacent mode implements a documented conservative subset, not a DICOM PS3.15 conformance statement. DICOM private attributes, pixels, overlays, and burned-in annotations always remain manual-review items.
headerScrub( header, format = c("auto", "edf", "brainvision", "snirf", "dicom"), subject_token = NULL, date_key = NULL, subject_id = NULL, free_text = c("error", "drop") )headerScrub( header, format = c("auto", "edf", "brainvision", "snirf", "dicom"), subject_token = NULL, date_key = NULL, subject_id = NULL, free_text = c("error", "drop") )
header |
A named plain list, data frame, or |
format |
Explicit format, or |
subject_token |
Optional safe replacement token. |
date_key |
Caller-owned raw date-shifting key. |
subject_id |
Subject identifier used only to derive a date offset. |
free_text |
Refuse or drop detected free-text fields. |
A header_scrub object containing the scrubbed header and reports.
header <- list( patient_id = "source-patient", recording_id = "source-recording", start_date = as.Date("2024-02-29"), comments = "free text note", signal_headers = list(label = c("ECG", "EMG"), unit = c("mV", "mV")) ) # Scrubs a parsed header only; it does not read or rewrite the binary file. result <- headerScrub(header, "edf", subject_token = "psn_safe", free_text = "drop") result$header$patient_id resultheader <- list( patient_id = "source-patient", recording_id = "source-recording", start_date = as.Date("2024-02-29"), comments = "free text note", signal_headers = list(label = c("ECG", "EMG"), unit = c("mV", "mV")) ) # Scrubs a parsed header only; it does not read or rewrite the binary file. result <- headerScrub(header, "edf", subject_token = "psn_safe", free_text = "drop") result$header$patient_id result
Initializes a versioned SHA-256 audit chain over the complete
PhysioExperiment record. The genesis event snapshots the existing
PhysioCore provenance log. Existing compliance metadata is never replaced.
initializeAuditTrail( x, actor, reason = "audit trail initialized", timestamp = Sys.time() )initializeAuditTrail( x, actor, reason = "audit trail initialized", timestamp = Sys.time() )
x |
A PhysioExperiment::PhysioExperiment object. |
actor |
Non-empty identifier for the responsible actor. |
reason |
Non-empty reason for initialization. |
timestamp |
One finite |
A modified copy of x with a genesis audit event.
x <- PhysioExperiment::PhysioExperiment( assays = list(raw = matrix(1:6, nrow = 3)), samplingRate = 100 ) x <- initializeAuditTrail(x, actor = "operator-01") verifyAuditTrail(x)x <- PhysioExperiment::PhysioExperiment( assays = list(raw = matrix(1:6, nrow = 3)), samplingRate = 100 ) x <- initializeAuditTrail(x, actor = "operator-01") verifyAuditTrail(x)
Render a project-owned software lifecycle template set
lifecycleTemplate( out_dir, project, intended_use, software_safety_class = c("unclassified", "A", "B", "C"), owner, effective_date = Sys.Date(), source_editions = standardsSources(), overwrite = FALSE )lifecycleTemplate( out_dir, project, intended_use, software_safety_class = c("unclassified", "A", "B", "C"), owner, effective_date = Sys.Date(), source_editions = standardsSources(), overwrite = FALSE )
out_dir |
Destination child directory. |
project |
Project name. Path separators are not allowed. |
intended_use |
Intended-use statement supplied by the project. |
software_safety_class |
Project-supplied class or |
owner |
Recorded document owner. |
effective_date |
Effective date to render. |
source_editions |
Metadata returned by |
overwrite |
Whether to replace an existing destination atomically. |
A lifecycle_template manifest.
parent <- file.path(tempdir(), "pc-lifecycle-demo") dir.create(parent, showWarnings = FALSE) tmpl <- lifecycleTemplate( out_dir = file.path(parent, "lifecycle"), project = "Example Project", intended_use = "Research data processing", owner = "project-owner", effective_date = as.Date("2026-07-28") ) tmpl unlink(parent, recursive = TRUE)parent <- file.path(tempdir(), "pc-lifecycle-demo") dir.create(parent, showWarnings = FALSE) tmpl <- lifecycleTemplate( out_dir = file.path(parent, "lifecycle"), project = "Example Project", intended_use = "Research data processing", owner = "project-owner", effective_date = as.Date("2026-07-28") ) tmpl unlink(parent, recursive = TRUE)
Creates deterministic HMAC-derived or random 128-bit tokens and stores the one-to-one re-identification map in an authenticated encrypted envelope. The encrypted map remains sensitive additional information and should be stored separately from pseudonymized records with deployment-level access controls.
pseudonymize( identifiers, key, namespace, method = c("hmac_sha256", "random"), encrypted_map = NULL )pseudonymize( identifiers, key, namespace, method = c("hmac_sha256", "random"), encrypted_map = NULL )
identifiers |
Character vector. |
key |
Raw vector of at least 32 cryptographically random bytes. |
namespace |
Non-empty deployment-specific namespace. |
method |
Token method. |
encrypted_map |
Optional prior |
This is a pseudonymization primitive, not a declaration of anonymization, HIPAA Safe Harbor status, or GDPR compliance.
A pseudonymization object containing tokens and an authenticated
encrypted map, but no plaintext identifier map or key.
key <- openssl::rand_bytes(32) p <- pseudonymize(c("subject-a", "subject-b", "subject-a"), key, namespace = "study-example") p identical(reidentify(p, key), c("subject-a", "subject-b", "subject-a"))key <- openssl::rand_bytes(32) p <- pseudonymize(c("subject-a", "subject-b", "subject-a"), key, namespace = "study-example") p identical(reidentify(p, key), c("subject-a", "subject-b", "subject-a"))
Recover identifiers from a protected pseudonymization map
reidentify(x, key)reidentify(x, key)
x |
A |
key |
The caller-owned raw key used to create the map. |
Character vector aligned to x$values.
key <- openssl::rand_bytes(32) p <- pseudonymize(c("subject-a", "subject-b"), key, namespace = "study-example") reidentify(p, key)key <- openssl::rand_bytes(32) p <- pseudonymize(c("subject-a", "subject-b"), key, namespace = "study-example") reidentify(p, key)
Render a project-owned risk-management template set
riskManagementTemplate( out_dir, project, intended_use, owner, effective_date = Sys.Date(), risk_matrix = NULL, source_editions = standardsSources(), overwrite = FALSE )riskManagementTemplate( out_dir, project, intended_use, owner, effective_date = Sys.Date(), risk_matrix = NULL, source_editions = standardsSources(), overwrite = FALSE )
out_dir |
Destination child directory. |
project |
Project name. Path separators are not allowed. |
intended_use |
Intended-use statement supplied by the project. |
owner |
Recorded document owner. |
effective_date |
Effective date to render. |
risk_matrix |
Optional project-owned |
source_editions |
Metadata returned by |
overwrite |
Whether to replace an existing destination atomically. |
A lifecycle_template manifest.
parent <- file.path(tempdir(), "pc-risk-demo") dir.create(parent, showWarnings = FALSE) tmpl <- riskManagementTemplate( out_dir = file.path(parent, "risk"), project = "Example Project", intended_use = "Research data processing", owner = "project-owner", effective_date = as.Date("2026-07-28") ) tmpl unlink(parent, recursive = TRUE)parent <- file.path(tempdir(), "pc-risk-demo") dir.create(parent, showWarnings = FALSE) tmpl <- riskManagementTemplate( out_dir = file.path(parent, "risk"), project = "Example Project", intended_use = "Research data processing", owner = "project-owner", effective_date = as.Date("2026-07-28") ) tmpl unlink(parent, recursive = TRUE)
The constructor records caller-supplied ordinal levels and one explicit decision for every severity/probability pair. It does not multiply ranks or infer a risk-acceptability policy.
riskMatrix(severity, probability, decisions, matrix_id, version, rationale)riskMatrix(severity, probability, decisions, matrix_id, version, rationale)
severity |
Severity levels with |
probability |
Probability levels with the same columns. |
decisions |
One explicit decision for every Cartesian level pair. |
matrix_id, version, rationale
|
Non-empty project identifiers and policy rationale. |
A deterministic risk_matrix object.
severity <- data.frame( level_id = c("S1", "S2"), rank = 1:2, label = c("Minor", "Serious"), definition = c("Limited impact", "Significant impact"), stringsAsFactors = FALSE ) probability <- data.frame( level_id = c("P1", "P2"), rank = 1:2, label = c("Unlikely", "Likely"), definition = c("Rarely occurs", "Often occurs"), stringsAsFactors = FALSE ) decisions <- expand.grid( severity_id = severity$level_id, probability_id = probability$level_id, stringsAsFactors = FALSE ) # One explicit project decision for every pair; ranks are never multiplied # and no universal acceptability threshold is supplied. decisions$decision <- c("acceptable", "review_required", "review_required", "unacceptable") decisions$rationale <- paste0("POLICY-", seq_len(nrow(decisions))) riskMatrix(severity, probability, decisions, matrix_id = "RM01", version = "1.0", rationale = "Project-owned decision policy")severity <- data.frame( level_id = c("S1", "S2"), rank = 1:2, label = c("Minor", "Serious"), definition = c("Limited impact", "Significant impact"), stringsAsFactors = FALSE ) probability <- data.frame( level_id = c("P1", "P2"), rank = 1:2, label = c("Unlikely", "Likely"), definition = c("Rarely occurs", "Often occurs"), stringsAsFactors = FALSE ) decisions <- expand.grid( severity_id = severity$level_id, probability_id = probability$level_id, stringsAsFactors = FALSE ) # One explicit project decision for every pair; ranks are never multiplied # and no universal acceptability threshold is supplied. decisions$decision <- c("acceptable", "review_required", "review_required", "unacceptable") decisions$rationale <- paste0("POLICY-", seq_len(nrow(decisions))) riskMatrix(severity, probability, decisions, matrix_id = "RM01", version = "1.0", rationale = "Project-owned decision policy")
Constructs a versioned field policy. These policies are technical controls,
not legal determinations. A safe_harbor_candidate still requires the
no-actual-knowledge and organizational review required by the applicable
workflow. Pseudonymized data remain personal data when separately held
information permits re-identification.
safeHarborPolicy( additional_fields = list(), date_action = c("year", "remove"), free_text = c("error", "drop"), biometric_data = c("error", "drop") ) pseudonymizedPolicy( additional_fields = list(), free_text = c("error", "drop", "retain") )safeHarborPolicy( additional_fields = list(), date_action = c("year", "remove"), free_text = c("error", "drop"), biometric_data = c("error", "drop") ) pseudonymizedPolicy( additional_fields = list(), free_text = c("error", "drop", "retain") )
additional_fields |
A named plain list mapping canonical category IDs to deployment-specific aliases. |
date_action |
Replace person-related dates with year-only values or remove them. |
free_text |
Refuse, drop, or (for pseudonymized data only) retain detected free text. |
biometric_data |
Refuse or drop detected biometric/image content. |
A deidentification_policy data frame.
# A conservative field policy. The `safe_harbor_candidate` label is a # configured-field result, not a legal de-identification determination. policy <- safeHarborPolicy(free_text = "drop", biometric_data = "drop") head(policy[, c("category", "action")]) # The pseudonymized variant shifts dates instead of reducing them to a year. head(pseudonymizedPolicy(free_text = "drop")[, c("category", "action")])# A conservative field policy. The `safe_harbor_candidate` label is a # configured-field result, not a legal de-identification determination. policy <- safeHarborPolicy(free_text = "drop", biometric_data = "drop") head(policy[, c("category", "action")]) # The pseudonymized variant shifts dates instead of reducing them to a year. head(pseudonymizedPolicy(free_text = "drop")[, c("category", "action")])
Reads edition metadata recorded when this package was built. It performs no network request and does not determine whether a source remains applicable to a project.
standardsSources(max_age_days = 365L, as_of = Sys.Date())standardsSources(max_age_days = 365L, as_of = Sys.Date())
max_age_days |
Non-negative integer age after which source metadata is marked for review. |
as_of |
Date used to calculate metadata age. |
A standards_sources data frame.
# Reads edition metadata recorded at build time; performs no network request. sources <- standardsSources(as_of = as.Date("2026-07-28")) sources[, c("source_id", "edition", "review_status")]# Reads edition metadata recorded at build time; performs no network request. sources <- standardsSources(as_of = as.Date("2026-07-28")) sources[, c("source_id", "edition", "review_status")]
Construct a normalized requirement-risk-control-test traceability graph
traceabilityMatrix( requirements, risks, controls, tests, links, evidence_root = NULL, risk_matrix = NULL )traceabilityMatrix( requirements, risks, controls, tests, links, evidence_root = NULL, risk_matrix = NULL )
requirements, risks, controls, tests, links
|
Plain data frames using the
schemas documented in |
evidence_root |
Optional evidence directory. Evidence URIs remain relative to this root. |
risk_matrix |
Optional project-owned |
A deterministic traceability_matrix object.
Verify traceability structure, completeness, and objective evidence
validateTraceability(x, verify_evidence = TRUE)validateTraceability(x, verify_evidence = TRUE)
x |
A |
verify_evidence |
Whether to hash evidence files under the recorded evidence root. |
A traceability_verification object.
Verification reports tampering and malformed storage without modifying, truncating, repairing, or rehashing the supplied object.
verifyAuditTrail(x)verifyAuditTrail(x)
x |
A PhysioExperiment::PhysioExperiment object. |
A self-contained object cannot distinguish an internally consistent earlier
copy from the record as it existed at that time. Detect whole-object rollback
or removal of the current tail event by retaining each verified head_hash
in a validated external append-only store and comparing it on retrieval.
A compliance_verification object containing validity, deterministic
issues, the verified head hash, current record hash, and event counts.
x <- PhysioExperiment::PhysioExperiment( assays = list(raw = matrix(1:6, nrow = 3)), samplingRate = 100 ) x <- initializeAuditTrail(x, actor = "operator-01") verifyAuditTrail(x)x <- PhysioExperiment::PhysioExperiment( assays = list(raw = matrix(1:6, nrow = 3)), samplingRate = 100 ) x <- initializeAuditTrail(x, actor = "operator-01") verifyAuditTrail(x)
Reconstructs each canonical challenge and delegates cryptographic and credential verification to a caller-supplied callback. Provider errors are reported without storing or exposing provider diagnostics.
verifyESignatures(x, verify)verifyESignatures(x, verify)
x |
A PhysioExperiment::PhysioExperiment object. |
verify |
Function called once for each structurally valid signature as
|
A compliance_verification object containing audit and signature
issues.
x <- PhysioExperiment::PhysioExperiment( assays = list(raw = matrix(1:6, nrow = 3)), samplingRate = 100 ) x <- initializeAuditTrail(x, actor = "operator-01") credential <- list(id = "credential-01", algorithm = "demo-sha256", fingerprint = "01:23:45:67") bytes <- function(challenge, credential) { digest::digest(c(challenge, serialize(credential, NULL, version = 3)), algo = "sha256", serialize = FALSE, raw = TRUE) } x <- eSign(x, signer = "reviewer-02", meaning = "reviewed", credential = credential, sign = bytes) # The verifier recomputes the same bytes; a real one checks a cryptographic # signature against the signer's credential. verifyESignatures(x, verify = function(challenge, signature, credential) { identical(signature, bytes(challenge, credential)) })$validx <- PhysioExperiment::PhysioExperiment( assays = list(raw = matrix(1:6, nrow = 3)), samplingRate = 100 ) x <- initializeAuditTrail(x, actor = "operator-01") credential <- list(id = "credential-01", algorithm = "demo-sha256", fingerprint = "01:23:45:67") bytes <- function(challenge, credential) { digest::digest(c(challenge, serialize(credential, NULL, version = 3)), algo = "sha256", serialize = FALSE, raw = TRUE) } x <- eSign(x, signer = "reviewer-02", meaning = "reviewed", credential = credential, sign = bytes) # The verifier recomputes the same bytes; a real one checks a cryptographic # signature against the signer's credential. verifyESignatures(x, verify = function(challenge, signature, credential) { identical(signature, bytes(challenge, credential)) })$valid
Write a deterministic conformance report
writeConformanceReport( x, path, format = c("json", "csv", "markdown"), overwrite = FALSE )writeConformanceReport( x, path, format = c("json", "csv", "markdown"), overwrite = FALSE )
x |
A |
path |
Destination path. |
format |
JSON, CSV, or Markdown output. |
overwrite |
Whether to replace existing output atomically. |
Normalized output path or paths, invisibly.