Skip to contents

Suites are named collections of DGP IDs. They make repeated benchmark setup convenient, but membership is not evidence that a DGP is stable or that every aggregate is scientifically meaningful. Inspect registry status and each DGP report before designing a study.

library(CausalStress)
library(dplyr)
library(ggplot2)

board_path <- tempfile("causalstress-suite-")
dir.create(board_path)
board <- pins::board_folder(board_path)

Discover suites

cs_suite_registry() |>
  select(suite_id, description)
# A tibble: 5 × 2
  suite_id  description
  <chr>     <chr>
1 placebo   All placebo (sharp-null) DGPs
2 heavytail Heavy-tail signal and placebo heavy-tail DGPs
3 signal    Signal-focused DGPs (baseline, QTE heterogeneity, nonlinear heteros…
4 stress    Stress-test DGPs (overlap and tilt stressors)
5 all       All available synthetic DGPs                                        
cs_get_suite("placebo")
[1] "synth_placebo_tau0"        "synth_placebo_nonlinear"
[3] "synth_placebo_heavytail"   "synth_placebo_tilted"
[5] "synth_placebo_tilted"      "synth_placebo_kangschafer"

The placebo suite currently contains experimental DGPs. The call below requests that status explicitly and uses a small bootstrap only to make interval plots executable. Increase the number of seeds and bootstrap replicates for scientific work.

placebo_runs <- cs_run_suite(
  suite_id = "placebo",
  estimator_ids = "lm_att",
  n = 150,
  seeds = 1:2,
  status = "experimental",
  bootstrap = TRUE,
  B = 20,
  board = board,
  show_progress = FALSE
)

placebo_tidy <- cs_tidy(placebo_runs)
cs_collect_scores(placebo_runs) |>
  count(estimator_id, estimand_target_id, score_status)
# A tibble: 1 × 4
  estimator_id estimand_target_id score_status     n
  <chr>        <chr>              <chr>        <int>
1 lm_att       att                scored          12

Visualize ATT evidence

cs_plot_placebo() shows each placebo ATT estimate and interval; color records whether the interval covers the sharp-null target. cs_plot_att_error() shows the finite set of per-run ATT deviations.

cs_plot_placebo(placebo_tidy) +
  ggtitle("Placebo ATT intervals")

cs_plot_att_error(placebo_tidy) +
  ggtitle("ATT deviations in the example runs")

Interpret the gatekeeper components

cs_summarise_gatekeeper() returns separate target-specific components. The ATT component compares interval coverage with threshold. ATE remains structurally present but unverified pending recalibration. For QST, a run fails when more than 10% of its tau intervals exclude the placebo truth, and an estimator fails when more than 10% of verified runs fail. Missing intervals produce UNVERIFIED, not a pass.

gate <- cs_summarise_gatekeeper(placebo_runs, threshold = 0.90)
✖ lm_att: coverage = 0.67 (threshold 0.90)
ℹ Culprits (below threshold):
- lm_att on synth_placebo_kangschafer: coverage = 0.00
- lm_att on synth_placebo_nonlinear: coverage = 0.50
- lm_att on synth_placebo_tau0: coverage = 0.50
ℹ QST Gatekeeper (10/10 rule):
! lm_att: run failure rate = NA (threshold 0.10) [UNVERIFIED]
gate$att_verdict
# A tibble: 1 × 4
  estimator_id n_verified coverage_rate status
  <chr>             <int>         <dbl> <chr>
1 lm_att               12         0.667 FAIL  
gate$att_culprits
# A tibble: 3 × 4
  dgp_id                    estimator_id n_verified dgp_coverage
  <chr>                     <chr>             <int>        <dbl>
1 synth_placebo_kangschafer lm_att                2          0
2 synth_placebo_nonlinear   lm_att                2          0.5
3 synth_placebo_tau0        lm_att                2          0.5
gate$ate_verdict
# A tibble: 1 × 8
  estimand_target_id estimator_id n_verified coverage_rate threshold status
  <chr>              <chr>             <int>         <dbl>     <dbl> <chr>
1 ate                lm_att                0            NA        NA UNVERIFIED
# ℹ 2 more variables: policy_status <chr>, registry_consequence <chr>
gate$qst_verdict
# A tibble: 1 × 4
  estimator_id n_verified run_fail_rate status
  <chr>             <int>         <dbl> <chr>
1 lm_att                0            NA UNVERIFIED

The two seeds above demonstrate the API; they are far too few to support a scientific gatekeeper decision.

Inspect execution metadata and persisted evidence

placebo_tidy |>
  select(
    dgp_id, estimator_id, seed,
    run_time_dgp, run_time_est, run_time_total
  ) |>
  arrange(desc(run_time_total))
# A tibble: 12 × 6
   dgp_id            estimator_id  seed run_time_dgp run_time_est run_time_total
   <chr>             <chr>        <int>        <dbl>        <dbl>          <dbl>
 1 synth_placebo_no… lm_att           1      0.00418       0.0322         0.0738
 2 synth_placebo_ta… lm_att           1      0.00446       0.0353         0.0650
 3 synth_placebo_he… lm_att           2      0.00421       0.0346         0.0626
 4 synth_placebo_no… lm_att           2      0.00421       0.0341         0.0616
 5 synth_placebo_he… lm_att           1      0.00414       0.0338         0.0609
 6 synth_placebo_ta… lm_att           2      0.00438       0.0312         0.0600
 7 synth_placebo_ti… lm_att           1      0.00420       0.0323         0.0598
 8 synth_placebo_ti… lm_att           2      0.00421       0.0311         0.0590
 9 synth_placebo_ti… lm_att           2      0.00404       0.0317         0.0589
10 synth_placebo_ti… lm_att           1      0.00415       0.0308         0.0581
11 synth_placebo_ka… lm_att           1      0.00404       0.0286         0.0556
12 synth_placebo_ka… lm_att           2      0.00394       0.0287         0.0555
cs_audit(board) |>
  select(dgp_id, estimator_id, seed, fit_fingerprints)
# A tibble: 10 × 4
   dgp_id                    estimator_id  seed fit_fingerprints
   <chr>                     <chr>        <int> <list>
 1 synth_placebo_heavytail   lm_att           1 <chr [1]>
 2 synth_placebo_heavytail   lm_att           2 <chr [1]>
 3 synth_placebo_kangschafer lm_att           1 <chr [1]>
 4 synth_placebo_kangschafer lm_att           2 <chr [1]>
 5 synth_placebo_nonlinear   lm_att           1 <chr [1]>
 6 synth_placebo_nonlinear   lm_att           2 <chr [1]>
 7 synth_placebo_tau0        lm_att           1 <chr [1]>
 8 synth_placebo_tau0        lm_att           2 <chr [1]>
 9 synth_placebo_tilted      lm_att           1 <chr [1]>
10 synth_placebo_tilted      lm_att           2 <chr [1]>       

Timing fields are provenance, not scientific identities. Persisted results are written only because this example supplied board; skip_existing = TRUE is a separate opt-in for strict fingerprint-checked resume.