DGP Dossier: synth_placebo_tau0

1. Identity & Status

DGP ID synth_placebo_tau0
Version 1.3.0
Status experimental
Difficulty (1/5)
Stress Profile  overlap: moderatenoise: gaussianlinearity: lineareffect: constanttarget: both

2. What This DGP Stresses (Intent)

Intent: The “Calibration Check.” This is the baseline placebo design. It generates data under ideal conditions: linear confounding, Gaussian noise, and a sharp null effect (\(\tau(X) \equiv 0\)).

The Scientific Question: “Does the estimator respect the Null Hypothesis under ideal conditions?” Any estimator that fails here suffers from fundamental coding errors, extreme bias, or improper tuning. It serves as the control group for the stress suite.

3. Identification Assumptions (Explicit)

  • Selection on observables holds.
  • Overlap is moderate (propensity bounded).
  • SUTVA holds.
  • Sharp Null: \(Y_1 \equiv Y_0\).

4. Mathematical Specification

Covariates: \(X_1, X_2, X_3, X_4, X_5 \sim \mathcal{N}(0, 1^2)\) independently.

Outcome (control): \[\mu_0(X) = 1 + X_1 + 0.5 X_2\]

Propensity: \[p(X) = \text{expit}(0.5 X_1 - 0.5 X_2)\]

Treatment effect (sharp null): \[\tau(X) \equiv 0\]

Noise is Gaussian: \(\varepsilon \sim \mathcal{N}(0, 0.5^2)\) and \(Y_1 \equiv Y_0\) pathwise.

5. Oracle Truth Definition

  • True ATT is zero by construction.
  • True QST is identically zero on the canonical grid.

6. Visual Diagnostics (n = 5000)

7. Empirical Validation

We validate only the oracle estimator to keep builds fast.

Oracle validation (n=1000, seeds=1:20)
mean_bias rmse
0 0

8. Failure Mode Summary

  • Bias: Deviation from zero indicates fundamental estimator flaws (e.g., regularization bias in simple settings).
  • Variance: Extremely wide CIs suggest poor data efficiency even in ideal settings.

9. Implementation Reference

  • Code: R/dgp-synth-placebo-tau0.R (v1.3.0)
  • Registry: cs_dgp_registry() entry for synth_placebo_tau0
  • Oracle: true_att = 0, true_qst = 0

10. Validation Checklist

11. Changelog

  • v1.0 dossier: Initial placebo dossier

Appendix: Implementation

Source code for: dgp_synth_placebo_tau0_v130

function (n, seed = NULL, include_truth = TRUE, oracle_only = FALSE) 
{
    if (!is.null(seed)) {
        cs_set_rng(seed)
    }
    X1 <- stats::rnorm(n, mean = 0, sd = 1)
    X2 <- stats::rnorm(n, mean = 0, sd = 1)
    X3 <- stats::rnorm(n, mean = 0, sd = 1)
    X4 <- stats::rnorm(n, mean = 0, sd = 1)
    X5 <- stats::rnorm(n, mean = 0, sd = 1)
    mu0 <- 1 + X1 + 0.5 * X2
    tau <- rep(0, n)
    p <- stats::plogis(0.5 * X1 - 0.5 * X2)
    w <- stats::rbinom(n, size = 1, prob = p)
    eps <- stats::rnorm(n, mean = 0, sd = 0.5)
    y0 <- mu0 + eps
    y1 <- y0
    if (isTRUE(oracle_only)) {
        return(list(df = tibble::tibble(w = w, y0 = y0, y1 = y1)))
    }
    y <- ifelse(w == 1L, y1, y0)
    true_att <- cs_true_att(structural_te = tau, w = w)
    true_qst <- if (isTRUE(include_truth)) 
        cs_get_oracle_qst("synth_placebo_tau0", version = "1.3.0")
    else NULL
    out <- list(df = tibble::tibble(y = y, w = w, y0 = y0, y1 = y1, 
        p = p, structural_te = tau, X1 = X1, X2 = X2, X3 = X3, 
        X4 = X4, X5 = X5), true_att = true_att, true_qst = true_qst, 
        meta = list(dgp_id = "synth_placebo_tau0", version = "1.3.0", 
            type = "synthetic", params = list(n = n, seed = seed), 
            structural_te = tau))
    cs_check_dgp_synthetic(out)
    out
}
<bytecode: 0x5611dd6e2980>
<environment: namespace:CausalStress>