library(CausalStress)
library(pins)
library(dplyr)
board_path <- tempfile("causalstress-resume-")
dir.create(board_path)
board <- board_folder(board_path)CausalStress can persist each completed seed to a pins board and later reuse exactly matching artifacts. Persistence and resume are both opt-in. They reduce the amount of completed work repeated after interruption; they cannot preserve an estimator call that had not finished and been written.
Persist completed seeds
Supplying board writes completed results as RDS-backed pins. Without a board, the same runner returns results only.
first_pass <- cs_run_seeds(
dgp_id = "synth_baseline",
estimator_id = "lm_att",
n = 100,
seeds = 1:2,
board = board,
show_progress = FALSE
)
cs_audit(board) |>
select(dgp_id, estimator_id, n, seed, fit_fingerprints)# A tibble: 2 × 5
dgp_id estimator_id n seed fit_fingerprints
<chr> <chr> <int> <int> <list>
1 synth_baseline lm_att 100 1 <chr [1]>
2 synth_baseline lm_att 100 2 <chr [1]>
Resume with exact configuration identity
skip_existing = TRUE asks the runner to reuse completed schema-4 pins. For each existing seed, it recomputes the expected configuration fingerprint and requires an exact match. It then runs only seeds without a matching artifact and returns all requested seeds in deterministic order.
resumed <- cs_run_seeds(
dgp_id = "synth_baseline",
estimator_id = "lm_att",
n = 100,
seeds = 1:3,
board = board,
skip_existing = TRUE,
show_progress = FALSE
)
resumed |>
select(seed, config_fingerprint)# A tibble: 3 × 2
seed config_fingerprint
<int> <chr>
1 1 005682ef6f615ad437eb1d5076cc267e618d78fb66f458aaae59f6e7c0c29128
2 2 4df7fb05a19bc0ba4fa0a2774b852edf69f9d3438b5aa7188e1291fc287b4de6
3 3 b96d1cbcfe6621980118db707f33741de4051f4d310e3910c70fff8d0b3c33ed
Reading cached artifacts still has filesystem cost; “reused” does not mean literally zero elapsed time. The important guarantee is that matching completed seeds are not re-estimated.
Configuration changes fail closed
Changing bootstrap settings, sample size, tau, estimator configuration, versions, or another fingerprinted input means the old evidence is not the requested evidence. Resume rejects the mismatch. Missing fingerprints and historical fingerprint schemas are also rejected rather than silently migrated.
mismatch <- tryCatch(
cs_run_seeds(
dgp_id = "synth_baseline",
estimator_id = "lm_att",
n = 100,
seeds = 1:3,
bootstrap = TRUE,
B = 20,
board = board,
skip_existing = TRUE,
show_progress = FALSE
),
error = function(error) conditionMessage(error)
)
mismatch[1] "Configuration fingerprint mismatch for synth_baseline x lm_att seed 1. (Stored: 005682ef6f615ad437eb1d5076cc267e618d78fb66f458aaae59f6e7c0c29128, Current: 9780ae56a61f44c12a52caced5e08e4fab2340f8dcbf4b24c5ebe2cb3bb109b5). To overwrite this run with new settings, set force = TRUE or skip_existing = FALSE."
This fail-closed check prevents an accidental mixed campaign under resume. It does not claim that arbitrary artifacts outside the runner or deliberate manual board edits can never be mixed.
Recompute deliberately
Use force = TRUE or leave skip_existing = FALSE when replacement is intentional. Existing matching pins are removed before the new result is written.
recomputed <- cs_run_seeds(
dgp_id = "synth_baseline",
estimator_id = "lm_att",
n = 100,
seeds = 1:3,
bootstrap = TRUE,
B = 20,
board = board,
force = TRUE,
show_progress = FALSE
)
recomputed |>
select(seed, att_ci_width)# A tibble: 3 × 2
seed att_ci_width
<int> <dbl>
1 1 0.273
2 2 0.380
3 3 0.419
Deletion helpers are available when removing evidence is the actual intent:
cs_delete_result(
board,
dgp_id = "synth_baseline",
estimator_id = "lm_att",
n = 100,
seed = 1
)
cs_delete_campaign(board, "synth_baseline", "lm_att")Parallel staging is a separate boundary
Experimental parallel workers do not write directly to a shared board. They write RDS staging files, and the controlling process gathers them through a single-writer path. This protects the board-write boundary and enables recovery of completed staged results; it is not a transaction over a whole campaign.
| Intent | Setting |
|---|---|
| Return results without persistence | omit board
|
| Persist newly completed results | board = my_board |
| Reuse exactly matching schema-4 results | skip_existing = TRUE |
| Recompute and replace requested results | force = TRUE |
| Inspect persisted records | cs_audit(my_board) |