tests/testthat/test-oracle-provenance.R

# Oracle-provenance guard (M57).
#
# Mechanizes CLAUDE.md Invariant 8 ("no unsourced or unreproducible reference
# value ships") at the fixture layer: every committed test fixture must carry a
# structured top-level `provenance` attr that names its `data-raw/` generator and
# its source. This is the automated "bar" a future un-sourced fixture cannot slip
# past. The registry that classifies every oracle is cairn/ORACLES.md.
#
# NB: data-raw/ is .Rbuildignore'd, so the generator scripts are absent at
# R CMD check time. The guard therefore checks that provenance NAMES a data-raw
# generator (the reproducible recipe), not that the file exists on disk.

.provenance_ok <- function(path) {
  obj <- readRDS(path)
  p <- attr(obj, "provenance")
  is.list(p) &&
    is.character(p$generator) && length(p$generator) == 1L && nzchar(p$generator) &&
    grepl("^data-raw/.*\\.R$", p$generator) &&
    is.character(p$source) && length(p$source) == 1L && nzchar(p$source)
}

test_that("every fixture carries a structured provenance attr (generator + source)", {
  fixtures <- list.files(test_path("fixtures"), pattern = "\\.rds$", full.names = TRUE)
  expect_gt(length(fixtures), 0L)
  for (f in fixtures) {
    expect_true(.provenance_ok(f), label = paste0("provenance for ", basename(f)))
  }
})

test_that("the provenance guard has teeth (rejects unsourced / partial fixtures)", {
  scratch <- tempfile(fileext = ".rds")
  on.exit(unlink(scratch), add = TRUE)

  # No provenance attr at all -> rejected.
  saveRDS(list(x = 1), scratch)
  expect_false(.provenance_ok(scratch))

  # Generator present but source missing -> still rejected.
  saveRDS(structure(list(x = 1), provenance = list(generator = "data-raw/x.R")), scratch)
  expect_false(.provenance_ok(scratch))

  # A generator that is not a data-raw/*.R recipe -> rejected.
  saveRDS(
    structure(list(x = 1), provenance = list(generator = "made it up", source = "trust me")),
    scratch
  )
  expect_false(.provenance_ok(scratch))
})

Try the ackwards package in your browser

Any scripts or data that you put into this service are public.

ackwards documentation built on July 25, 2026, 1:08 a.m.