dsROCrate 0.2.4
Bug fixes
- Fixed
safe_output() reading Opal log timestamps in the
local time zone instead of UTC. Opal returns UTC timestamps in ISO 8601
format (e.g., 2026-10-13T04:26:14.076Z); they are now
parsed as UTC, including fractional seconds and
Z/+hh:mm offsets. Previously, on machines
whose time zone was not UTC, the
logs_from/logs_to window could drop recent log
entries (or include old ones).
- Fixed
safe_project() overwriting the user
attribute stored in the returned RO-Crate: a loop variable shadowed the
user argument.
- Fixed table lineage links (
isBasedOn) between tables
and resources being written to rocrate$graph instead of
rocrate$`@graph`, so they are now recorded in the RO-Crate
graph.
- Fixed the symbol registry lookup so it always returns a single row
when several symbols share the same
created_at timestamp
(dplyr::slice_max() now uses
with_ties = FALSE).
report() (path method) now forwards
max_line_length and ... to the RO-Crate
method; previously max_line_length was silently
ignored.
- The error shown when the report directory does not exist now
suggests
mkdir -p (was mkdir -r).
audit() and extract_safe_project() (opal
method) now read project names with $name, so they work
whether backend_projects() returns a data frame or a
tibble.
Changes
- Timestamps written by
safe_output() (the audit log
tibble, the _mappings.csv file, and
as.data.frame() of safe_call objects) are now
ISO 8601 in UTC with a trailing Z (e.g.,
2026-07-01T10:00:00Z). Code that compares these values as
strings will need to be updated.
safe_output(): logs_from and
logs_to accept POSIXct values or date-time
strings, with or without a Z/UTC offset. Strings without an
offset are interpreted as UTC, and Inf/-Inf
still mean “no limit”.
report() for a list of RO-Crates no longer has the
unused study_name argument.
Documentation
- Split the
getting-started vignette into three.
getting-started now covers connecting,
check_permissions(), audit() and
report(); the new building-crates vignette
shows the step-by-step workflow with init() and the
safe_*() functions (including saving the RO-Crate); and the
new auditing-studies vignette shows how to audit several
servers as one study.
audit-permissions vignette: explains how the permission
check works, lists the common error messages with their likely causes,
and gives the minimum Opal version (5.7.2).
deploy-local-datashield-server-with-opal vignette:
corrected the clone directory, added the demo accounts, the Opal version
requirement, an audit example and instructions to stop the server, and
removed unused code.
- Vignettes now only run their examples when the public Opal demo
server can be reached; otherwise the code is shown but not
evaluated.
- README: added the supported-backend and requirements table, a guide
on which function to use,
check_permissions() in the quick
start, and a list of all vignettes.
- Reference documentation: the description of
... is now
defined once (shared_params) and inherited by the
functions, the documented default of user_id_suffix was
corrected ("#person:"), the Opal-specific wording was
removed from the profile argument, and stray formatting in
the audit() documentation was fixed.
- Updated spell-check
WORDLIST.
Internal Changes
- Added
parse_utc(), parse_utc_limit(),
format_utc() and fmt_limit()
(utils-date.R) so that all timestamps are parsed and
formatted the same way. They replace
is_valid_posixct().
backend_logs() (opal method) now returns
@timestamp as POSIXct (UTC) and suppresses the
progress messages printed by opalr. Other backends are
expected to return POSIXct timestamps.
- Added tests for
parse_utc(), run under a non-UTC time
zone.
safe_output() tests covering
RESOLVE/ASSIGN operations now set
logs_from and logs_to explicitly, so they no
longer depend on the time they are run.
- Test mocks now use
type = "group" for group
permissions, matching the values returned by Opal, and the
report() tests no longer pass study_name.
- Rebuilt the vignettes against the current Opal demo server
(6.0.1).
dsROCrate 0.2.3
New Features
safe_output() now preserves Opal 6.0
RESOLVE operations independently of ASSIGN
operations, including the resolved symbol and source table/resource for
provenance. RESOLVE entries are retained even when no
matching ASSIGN follows (e.g., a failed resolution). This
is only enabled when the server reports Opal >= 6.0.
- Every entry in the audit log tibble returned via
safe_output() (and written to the
_mappings.csv file) now has a unique id
(UUID), and the tibble gains a column field recording the
column referenced by a function call argument
(e.g. D$LAB_TSC), where applicable.
Improvements
- Function-call arguments supplied as R expressions
(e.g.
D$LAB_TSC) are now resolved back to the single
registered symbol they reference, along with the referenced column.
Expressions that reference several symbols, or none that are registered,
are returned unchanged.
- Audit log entries are now ordered by their original log-entry order
and then timestamp, and operation IDs are regenerated as UUIDs.
- Symbol IDs generated by
safe_symbol() are now plain
UUIDs, without the previous "symbol-" prefix.
Bug fixes
- Fixed
safe_output() failing when an audit session
contains no ASSIGN operations: an empty, correctly typed
symbols table is now used.
- Fixed
safe_output() failing when no function calls
could be reconstructed from the logs: an empty, correctly typed calls
table is now used.
safe_output() no longer injects a placeholder row
(ds_profile = "-999999") into the parsed logs; a zero-row
typed tibble is used to guarantee the ds_profile column
exists instead.
- Fixed
resolve_dependencies() failing on an empty symbol
registry, and resolve_provenance() failing when given an
NA symbol ID. Both now return an empty tibble.
validate_backend_version() (opal method) no longer
emits warnings from utils::compareVersion().
Internal Changes
- Added tests covering
safe_output() with
RESOLVE and ASSIGN operations, and
RESOLVE operations without ASSIGN; updated
as.data.frame.safe_call() test for the new id
column.
- Declared additional local bindings in
safe_output() to
silence R CMD check notes about undefined global
variables.
- Updated roxygen2 documentation for
enrich_argument()
and safe_call(); regenerated with roxygen2 8.1.0.
dsROCrate 0.2.2
Bug fixes
- Fixed an issue in
safe_output() where Opal audit logs
containing no AGGREGATE events could cause the audit
pipeline to fail when constructing the calls table.
safe_output() now handles audit sessions with logs but
no AGGREGATE calls gracefully, returning an empty calls
table rather than attempting to operate on NULL.
- Fixed an issue where an RO-Crate without an explicit Opal profile
attribute could cause safe_output() to fail when filtering audit logs.
The default “default” Opal profile is now used when no profile is
supplied.
- Improved robustness of provenance extraction for audit sessions with
incomplete or limited audit activity.
dsROCrate 0.2.1
Bug Fixes
- Removed a duplicate, conflicting definition of
as.data.frame.safe_call() (two files each defined this S3
method with different output columns; only one could ever take effect,
silently). The safe-call.R version — timestamp, user,
r_cmd, fx, args, session, profile — is now the sole implementation.
- Fixed
print.safe_symbol() referencing stale
column/parent fields left over from before the
0.2.0 symbol-model refactor; it now correctly displays the symbol’s
asset, expr, and session
(guarding on both NULL and NA, since these
fields default to NA_character_).
- Fixed
as.data.frame.symbol_registry(), which previously
iterated over the columns of the underlying tibble instead of its rows
(via lapply() on a data frame), causing it to error
whenever called on a non-empty registry. It also referenced non-existent
parent/column fields. The method now simply
returns x$symbols coerced to a data frame, which already
carries the correct columns.
- Fixed
register_symbol() erroring on a brand-new, empty
registry (the very first symbol registered in any session): the
emptiness check compared nrow() of a plain, pre-tibble
list() before checking length(), producing a
zero-length logical passed to ||. The length()
check is now evaluated first, so it short-circuits correctly.
- Fixed
as.data.frame.safe_call()’s args
column having an unstable name and shape depending on how many arguments
the underlying call had (a single-argument call collapsed the column
into one named after that argument, e.g. x; multiple
arguments spread into several columns instead of one). The argument list
is now wrapped with I(list(...)) so it always appears as a
single, reliably-named args list-column.
- Added regression tests for
safe_call()/as.data.frame.safe_call(),
print.safe_symbol(), and
register_symbol()/as.data.frame.symbol_registry(),
none of which previously had any test coverage.
Internal Changes
- Removed unused internal helpers:
has_symbol()/has_symbol.symbol_registry() (and
its S3 export) and
safe_symbol_reference()/new_safe_symbol_reference(),
none of which were called anywhere in the package.
- Removed leftover commented-out code from
safe_symbol()
and print.safe_call().
- Added roxygen2 documentation (
@param,
@returns, @keywords internal,
@noRd) and explanatory comments to the internal
symbol-tracking functions introduced in 0.2.0 (safe_call(),
safe_symbol(), safe_reference(),
symbol_registry(), and their supporting utilities), with no
change in behaviour.
- Updated spell-check
WORDLIST.
- Re-rendered vignettes to refresh example output.
dsROCrate 0.2.0
Breaking Changes
- The audit log tibble returned via
safe_output() no
longer includes a table column. It has been replaced by
three more granular columns: kind (whether the tracked
object is a table, resource or
expression), asset (the resolved
table/resource name) and expr (the associated R expression,
when applicable). Code that reads the table column directly
will need to be updated.
New Features
- Added a symbol registry and call-tracking system
(
safe_symbol(), safe_call(),
safe_reference(), symbol_registry()) that
replaces regex-based parsing of Opal logs, modelling assignments and
aggregate function calls as objects and resolving arguments back to the
symbols/tables they reference.
- Added a generic backend abstraction layer
(
backend_logs(), backend_options(),
backend_users(), backend_projects(),
backend_sys_perms(), and others) so internal code no longer
calls opalr:: directly, paving the way for additional
backends.
- Added early Armadillo backend scaffolding:
check_permissions(), init(),
report(), safe_data(),
safe_output(), safe_people() and
safe_setting() now all have
ArmadilloCredentials methods, returning clear “not yet
implemented” errors ahead of full support.
- Added
default S3 methods for audit(),
audit_engine() and check_permissions(), giving
clearer errors when an unsupported connection object is supplied.
- Added a
verbose argument to
check_permissions() (opal method) to optionally print a
success message when permissions are sufficient.
- Added
print.safe_call() and
print.safe_symbol() methods, plus
as.data.frame() methods for safe_call and
symbol_registry objects, for readable inspection of the new
internal tracking objects.
Improvements
safe_people() now determines admin/auditor status from
actual system permissions and group membership, rather than a hardcoded
name check against "admin"/"administrator",
improving compatibility with deployments that use differently named
privileged accounts.
- Permission lookup failures during
safe_people() now
fall back gracefully to an empty result instead of aborting the whole
audit.
- Consolidated backend-version and connection-validation logic into
the new generic backend framework, reducing duplication between
Opal-specific code paths.
Documentation
- Removed a vignette section demonstrating direct calls to internal
helper functions, which have since been renamed as part of the backend
abstraction work.
- Updated documentation to reflect that
init(),
safe_data(), report() and related functions
now accept either opal or ArmadilloCredentials
connections.
Internal Changes
- Added test coverage for
audit(),
audit_engine() and check_permissions(), along
with a mock-connection test helper, reducing reliance on a live demo
Opal server.
- Added
uuid to Imports, used to generate
unique IDs for tracked symbols.
- Bumped the
testthat version requirement in
Suggests from >= 3.0.0 to
>= 3.1.4.
dsROCrate 0.1.0
New Features
- Added
check_permissions() support for backend
connections, allowing users to verify whether a connection has
sufficient privileges to run safe_* auditing functions
before execution (#15).
- Permission validation now provides actionable feedback, including
guidance on how to configure Opal users and roles when required
permissions are missing (#15).
- Added Opal version validation during backend checks to ensure
compatibility with APIs required for auditing and permission
verification workflows (#22).
Improvements
- Refactored backend validation into an extensible S3 framework,
providing a cleaner architecture for supporting additional backends in
future releases (#23).
- Introduced a unified backend validation workflow that standardises
connection, version and permission checks across auditing functions
(#23).
- Replaced use of
opalr::opal.datasources() with
opalr::opal.projects(), reducing the permissions required
for metadata extraction and improving compatibility with auditor
accounts (#21).
- Updated auditing workflows to support Opal’s Audit
System role, reducing the need for administrator-level accounts
when generating RO-Crates and audit reports (#20).
Bug Fixes
- Fixed generation of orphaned permission entities in RO-Crates by
excluding administrator and auditor permissions from dataset permission
records where corresponding user entities are not included (#19).
- Improved consistency between
safe_data() and
safe_people() permission handling (#19).
Documentation
- Updated deployment vignette to reference the
FederatedMethods-maintained DataSHIELD Docker deployment resources and
repository structure (#16).
- Updated user documentation to reflect support for Opal’s
Audit System role and revised permission requirements
(#20).
- Reviewed documentation for internal helper functions and adjusted
visibility of internal APIs where appropriate (#17).
- Added documentation and examples for backend permission validation
workflows (#15).
Internal Changes
- Improved separation of concerns between connection validation,
backend capability checks and permission validation (#22, #23).
- Refined internal validation infrastructure to simplify future
backend integrations.
- General maintenance, testing and documentation updates.
dsROCrate 0.0.2
- This patch addresses an issue with the vignettes. The
safe_output.opal() S3 generic now uses
overwrite = TRUE to update the root (./)
entity.
dsROCrate 0.0.1
- Initial CRAN submission.
- This version contains standard functions for auditing
(
audit()), reporting (report()) and extracting
five safe principle components (safe_*()).
- This version currently only supports OBiBa’s Opal as the
backend.