Skip to contents

ledgr_strategy_preflight() statically inspects a function(ctx, params) strategy before execution. It classifies the strategy into ledgr's reproducibility tiers:

Usage

ledgr_strategy_preflight(strategy)

Arguments

strategy

A function with signature function(ctx, params).

Value

A ledgr_strategy_preflight object with fields tier, allowed, reason, unresolved_symbols, package_dependencies, qualified_package_dependencies, attached_package_dependencies, worker_dependencies, ambient_rng_symbols, and notes.

Details

  • tier_1: self-contained strategy logic using only explicit params, base/recommended R references, and ledgr's exported public namespace.

  • tier_2: inspectable strategy logic that also uses package-qualified calls outside the active R distribution, such as pkg::fn(), or resolved immutable non-function closure objects that ledgr does not store as standalone replayable artifacts.

  • tier_3: strategy logic with unresolved free symbols, user helpers, forbidden nondeterministic calls, or global assignment that ledgr cannot recover from stored run metadata.

The preflight is static analysis, not proof of semantic reproducibility. Dynamic dispatch, mutable captured environments, and dynamically constructed code remain user responsibilities.

Tier 3 strategies fail before execution with condition classes ledgr_strategy_tier3 and ledgr_strategy_preflight_error; there is no force = TRUE override on ledgr_run() or ledgr_sweep(). Covered forbidden calls include direct wall-clock/process-environment calls such as Sys.time(), Sys.Date(), and Sys.getenv(), visible indirection such as do.call("Sys.time", list()), dynamic lookup/evaluation helpers such as get(), eval(), and assign(), global assignment with <<-, and visible context mutation such as attr(ctx, "secret") <- 1.

Ambient strategy RNG calls such as runif(1) are Tier 2 under the execution seed contract for ordinary sequential runs, but they are not certified for resume or parallel equivalence. Strategies that need pulse-specific stochastic inputs in those paths should derive them from ctx$pulse_seed without reading ambient .Random.seed. Custom indicator generation has a stricter deterministic feature contract; do not infer indicator RNG policy from strategy preflight.

Articles

Reproducibility model: vignette("reproducibility", package = "ledgr") system.file("doc", "reproducibility.html", package = "ledgr")

Examples

strategy <- function(ctx, params) {
  targets <- ctx$flat()
  targets
}
ledgr_strategy_preflight(strategy)
#> ledgr Strategy Preflight
#> =========================
#> 
#> Tier:    tier_1
#> Allowed: TRUE
#> Reason:  Strategy is self-contained under ledgr's static preflight rules.