---
title: "**Theoretical Addendum -- Block 8.5.A:**"
subtitle: "The T-learner AMM-side Causal Bridge: Canonization and Implementation"
author: "**José Mauricio Gómez Julián**"
date: "`r Sys.Date()`"
output:
  rmarkdown::html_vignette:
    toc: true
    toc_depth: 4
vignette: >
  %\VignetteIndexEntry{The T-learner AMM-side Causal Bridge}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  eval = FALSE
)
```

# **1. Purpose and position in the package**

This vignette canonizes the **T-learner AMM-side causal bridge** introduced
in Sub-phase 8.5.A. It is the operative continuation of
`vignette("v08_cate_ite_positioning")`: where v08 places AMM relative to
the CATE/ITE literature (Proposition 8A: AMM is a predictive object, CATE
is a counterfactual object), this addendum specifies the one explicit
construction that turns a *pair* of independent AMM fits into a CATE
estimator. The construction follows the **T-learner** of
Kuenzel et al. (2019), specialized to the AMM-side.

The exported entry point is the function
`gdpar_causal_bridge(fit_treat, fit_ctrl, newdata, ...)`. The function is
**not** an argument of `gdpar()`; it is a separate function that consumes
two `gdpar_fit` objects already produced by `gdpar()`. This API choice
preserves the strict separation between AMM as a generic predictive
framework and CATE as a causal-identification overlay (Proposition 8A);
it also keeps the bridge decoupled from the inference machinery so that
S-learner, X-learner, doubly-robust and double-machine-learning
extensions can be added in later sub-phases without disturbing the AMM
core.

**What this addendum is.** A formal definition of the T-learner AMM-side,
the identification assumptions it inherits from v02 plus the residual
no-confounding assumption that it introduces, the posterior-difference
estimator and its credible bounds, and the structural compatibility
contract the bridge enforces between the two fits. The minimum
reproducible example of §8 exercises the whole API; the limitations and
open questions of §9 and §10 anchor the deferred extensions in Block 9.

**What this addendum is not.** It is not a tutorial on causal inference
(Imbens-Rubin 2015 remains the canonical reference); it is not a
comparator with external meta-learners (Sub-phase 8.5.B); it is not a
guide to specifying AMM models (v00, v01, vop01-vop05 cover that).

---

# **2. Notation inherited from v08 (rapid reference)**

For full statements see `vignette("v08_cate_ite_positioning")` §2 and
Appendix A. The minimal table needed here:

| Symbol | Meaning |
|:-------|:--------|
| $T_i \in \{0, 1\}$ | Treatment indicator |
| $(Y_i(0), Y_i(1))$ | Potential outcomes (Rubin 1974) |
| $Y_i = T_i Y_i(1) + (1 - T_i) Y_i(0)$ | Observed outcome under (CONS) |
| $\mu_t(x) = \mathbb{E}[Y(t) \mid X = x]$ | Conditional potential-outcome means |
| $\tau(x) = \mu_1(x) - \mu_0(x)$ | CATE function |
| $e(x) = \Pr(T = 1 \mid X = x)$ | Propensity score |
| $\theta_i^{(t)} = \theta_{\text{ref}}^{(t)} + \Delta^{(t)}(x_i, \theta_{\text{ref}}^{(t)})$ | AMM parameter under arm $t \in \{0, 1\}$ |
| $(\text{IGN})$ | Ignorability: $(Y(0), Y(1)) \perp T \mid X$ |
| $(\text{OVL})$ | Overlap: $0 < e(x) < 1$ for $\mu$-a.e. $x$ |
| $(\text{CONS})$ | Consistency / SUTVA |

The superscript $(t)$ on AMM objects refers to the *arm* under which the
fit was produced (treatment arm $t = 1$, control arm $t = 0$). The T-learner
fits one AMM model per arm independently; the per-arm parameters
$\theta_i^{(t)}$ are different objects of estimation, and there is no
parameter shared between the two fits.

---

# **3. Definition: the T-learner AMM-side**

> **Definition 8.5.A-1 (T-learner AMM-side).** Let $\mathcal{D}_1 =
> \{(x_i, y_i) : T_i = 1\}$ and $\mathcal{D}_0 = \{(x_i, y_i) : T_i = 0\}$
> be the treatment and control sub-samples. Fix one AMM specification
> $\mathcal{A}$ (formula, family with link $g$, anchor, AMM level,
> modulating basis) and use it for both arms. The **T-learner AMM-side
> bridge** is:
>
> 1. Fit $\widehat{\theta}^{(1)} = \texttt{gdpar}(\mathcal{D}_1, \mathcal{A})$.
> 2. Fit $\widehat{\theta}^{(0)} = \texttt{gdpar}(\mathcal{D}_0, \mathcal{A})$.
> 3. For every $x \in \mathcal{X}_{\text{new}}$, define the per-arm
>    response-scale prediction
>    $\widehat\mu_t(x) = g^{-1}\!\left( \widehat\theta^{(t)}(x) \right)$
>    on the inverse link of each arm's predicted individual parameter.
> 4. The bridge estimator of the CATE at $x$ is
>    $$\widehat\tau(x) \;=\; \widehat\mu_1(x) - \widehat\mu_0(x).$$

The definition makes three architectural commitments explicit:

(a) **Structural symmetry between arms.** The two arms share the same
    AMM specification $\mathcal{A}$. The bridge does not entertain
    asymmetric specifications (treatment with one AMM level, control
    with another); such asymmetry would break the comparability of the
    two arms' predictive objects on which the T-learner depends.
    `gdpar_causal_bridge` enforces this with structural compatibility
    checks (see §5 and the function's `@details`).

(b) **No parameter sharing.** Unlike the S-learner (which fits one model
    on the pooled data with $T$ as a covariate) the T-learner fits two
    independent models. The joint posterior of
    $(\theta^{(0)}, \theta^{(1)})$ factorizes:
    $$p\!\left(\theta^{(0)}, \theta^{(1)} \mid \mathcal{D}_0 \cup
    \mathcal{D}_1\right) \;=\; p\!\left(\theta^{(0)} \mid \mathcal{D}_0\right)\,
    p\!\left(\theta^{(1)} \mid \mathcal{D}_1\right),$$
    a direct consequence of $\mathcal{D}_0 \cap \mathcal{D}_1 = \emptyset$
    and the independence of the two priors (gdpar uses the same prior
    distribution for both arms by default, but the *random* variables
    drawn from those distributions are independent across arms). This
    is the *raison d'être* of the per-draw difference of §6.

(c) **Response-scale CATE by default.** Step (3) applies the inverse
    link before the difference, so $\widehat\tau(x)$ is on the natural
    scale of the response (mean for Gaussian, rate for Poisson, success
    probability for Bernoulli, etc.). The package also exposes the
    linear-predictor scale (`type = "theta_i"`) for users who prefer to
    report differences on the link-transformed scale; the trade-off is
    that the linear-predictor difference is in units of the link, which
    are not always interpretable as treatment effects.

The bridge is **agnostic to the AMM Path**. Definition 8.5.A-1 is stated
in terms of the fitted parameter $\widehat\theta^{(t)}$ without reference
to the path that produced it; Path 1 (Bayesian) is the only path
implemented in 0.0.0.9001 (Sub-phase 8.5.A constrains the bridge to
`path = "bayes"` and aborts otherwise). Paths 2 and 3 are mapped to the
same construction in §10's open questions.

---

# **4. Identification assumptions**

The bridge inherits the **AMM identifiability hypotheses** of Block 1
(applied to each arm) and the **gnoseological validity hypotheses** of
v02 (applied to each arm). On top of those, the T-learner requires the
*classical* causal-identification hypotheses of v08 §2.1, restated here
for self-containment, plus one additional structural assumption that is
specific to the per-arm decomposition.

## **4.1. Inherited from v08**

- **(IGN) Ignorability:** $(Y(0), Y(1)) \perp T \mid X$.
- **(OVL) Overlap:** $0 < e(x) < 1$ for $\mu$-a.e. $x$.
- **(CONS) Consistency / SUTVA:** $Y_i = T_i Y_i(1) + (1 - T_i) Y_i(0)$.

Under (IGN)+(OVL)+(CONS), Imbens-Rubin (2015, Theorem 12.1) gives the
identifying formula $\mu_t(x) = \mathbb{E}[Y \mid X = x, T = t]$. The
right-hand side is the per-arm conditional expectation that each AMM
fit estimates: $\widehat\mu_t(x) = g^{-1}(\widehat\theta^{(t)}(x))$. The
identification of the CATE at $x$ thus reduces to the identification of
each arm's per-arm conditional expectation, which is exactly the AMM
identification problem of Block 1.

## **4.2. Residual no-confounding (T-learner-specific)**

The T-learner additionally requires what we call **(NCR) Residual
no-confounding within each arm**:

> **(NCR).** Within each arm $t \in \{0, 1\}$, the AMM specification
> $\mathcal{A}$ contains all covariates necessary to make the conditional
> expectation $\mathbb{E}[Y \mid X = x, T = t]$ identifiable from the
> arm's sub-sample. Equivalently, no unmeasured confounder of the
> outcome-treatment relationship is omitted from the AMM components
> $(a, b, W, x_{\text{vars}})$ at the level of each arm.

(NCR) is not a new substantive assumption beyond (IGN): if (IGN) holds
at $x$ and $X$ is fully observed, the arm-specific conditional
expectation is by definition identifiable. (NCR) merely makes the
*operational* responsibility explicit: the user must include in the AMM
specification *all the covariates whose omission would create within-arm
confounding*. A common failure mode is to omit interactions with $T$
that, under the pooled S-learner specification, would be absorbed by the
treatment-indicator coefficient; the T-learner has no treatment
indicator (each arm is fit separately), so omitted interactions
contaminate the within-arm conditional expectation directly.

The bridge does not — and cannot — verify (IGN) or (NCR) from the data
alone; they are *causal* assumptions and require domain knowledge or
design (randomization, instrumental variables, regression
discontinuities) to underwrite them. The bridge does verify the
*structural pre-conditions* that make the T-learner construction
well-defined: family, link, AMM level, anchor, covariate column
structure (see §5).

## **4.3. What the bridge does not assume**

- **No homoscedasticity across arms.** Each arm has its own posterior
  of $\sigma_y$ (Gaussian), $\phi$ (Negative Binomial), etc. The bridge
  does not assume that the two posteriors are equal.
- **No common modulating block.** Each arm has its own posterior of
  $W_{\text{raw}}$, $\sigma_W$. The bridge does not assume that the
  modulating block is the same in the two arms (treatment may amplify or
  dampen the modulation).
- **No equal sample sizes.** The bridge handles unbalanced sub-samples
  (different number of rows in $\mathcal{D}_1$ and $\mathcal{D}_0$); the
  T-learner is known to suffer from regularization-induced bias in this
  setting (§9).

---

# **5. Estimation**

The bridge is constructed by `gdpar_causal_bridge(fit_treat, fit_ctrl,
newdata, type, level)`. The structural pre-conditions enforced at
construction time are:

- **Path:** both fits have `path = "bayes"`.
- **Non-hierarchical:** both fits have `stan_data$use_groups == 0L`.
  The grouped regime of Block 6.5 introduces per-group anchors whose
  treatment under the T-learner difference is not defined in the
  canonical formulation; grouped bridges are queued for a future
  sub-phase (see §10).
- **Family and link:** both fits share `family$name` and `family$link`,
  and the per-slot family identifiers when $K > 1$.
- **Dim:** both fits share `K` and `p`.
- **AMM level and basis:** both fits share `amm$level` (or per-slot
  levels when $K > 1$) and `amm$W$type` (polynomial or B-spline).
- **Anchor:** both fits share the anchor value within a relative
  tolerance of $10^{-8}$. This is necessary because the anchor enters
  the modulating term as $\theta_{\text{ref}}^k - \mathrm{anchor}^k$; a
  mismatch changes the meaning of $\widehat\theta^{(t)}(x)$ and
  therefore of $\widehat\tau(x)$.
- **Covariate columns:** both fits share the set of variables that
  appear in `a`, `b`, and `x_vars` (per coordinate / slot when
  multi-dimensional).

Any violation aborts with `gdpar_unsupported_feature_error`. The intent
of the strict compatibility contract is to refuse meaningless bridges
loudly rather than silently produce CATE estimates whose decomposition
mixes incompatible AMM objects.

When the structural pre-conditions hold, the bridge calls
`predict.gdpar_fit(fit_treat, newdata, type, summary = "draws")` and
`predict.gdpar_fit(fit_ctrl, newdata, type, summary = "draws")`, aligns
their draws (see §6), and computes the per-draw, per-observation
difference:

$$\widehat{\tau}^{(s)}_i \;=\; \widehat{\mu}^{(s)}_{1}(x_i) \;-\;
\widehat{\mu}^{(s)}_{0}(x_i), \qquad s = 1, \ldots, S, \ i = 1, \ldots,
n_{\text{new}}.$$

The matrix $\widehat{\tau} \in \mathbb{R}^{S \times n_{\text{new}}}$ is
stored in the returned object as `cate_draws`. For multivariate
($p > 1$) or K-individual ($K > 1$) fits, `predict.gdpar_fit` returns a
3-array of shape $S \times n \times \dim$; the bridge computes the
elementwise difference and stores it as a 3-array of the same shape.

---

# **6. Inference: per-observation credible bounds and the ATE**

The two fits are sampled from disjoint sub-samples and are therefore
*posteriori* independent: the joint posterior of
$(\theta^{(0)}, \theta^{(1)})$ factorizes (§3 (b)). Any draw
$(\widehat{\theta}^{(0), s_0}, \widehat{\theta}^{(1), s_1})$ with $s_0$
and $s_1$ drawn independently from each marginal is a valid sample from
the joint. The bridge implements this by pairing the $s$-th draw of one
arm with the $s$-th draw of the other arm, which — under the Monte
Carlo exchangeability of draws within a chain — is a uniformly
distributed pairing. When the two fits have different numbers of draws
$S_t \ne S_c$, the bridge trims the longer arm to
$S = \min(S_t, S_c)$ and emits a `gdpar_diagnostic_warning`.

The per-observation posterior of the CATE at $x_i$ is summarized by:

- The empirical mean $\overline{\tau}_i = S^{-1} \sum_{s=1}^{S}
  \widehat{\tau}_i^{(s)}$, stored as `cate_mean`.
- The empirical $(\alpha/2, 1 - \alpha/2)$ quantiles with
  $\alpha = 1 - \mathrm{level}$, stored as `cate_ci` (default
  $\mathrm{level} = 0.95$).

The summary uses *empirical quantiles*, not a normal-approximation
interval, because the per-arm posteriors are not necessarily Gaussian
(small-sample, non-Gaussian families) and the difference of two
near-Gaussian distributions can have meaningfully heavy tails when the
two marginals have different scales.

**Marginal ATE.** The bridge's `summary()` method also reports the
marginal average treatment effect (ATE) over the evaluation grid:

$$\widehat{\text{ATE}} \;=\; \frac{1}{n_{\text{new}}} \sum_{i = 1}^{n_{\text{new}}}
\overline{\tau}_i.$$

The credible bounds of the ATE are computed by first averaging the
per-draw CATE over the evaluation grid (giving an
$S$-vector of per-draw ATEs) and then taking the empirical quantiles of
that vector. This ordering preserves the posterior shape of the ATE; it
is *not* equivalent to averaging the per-observation credible bounds.
The latter would underestimate the width of the ATE interval by ignoring
the cross-observation correlation introduced by parameter sharing
within each arm.

---

# **7. Identifiability per arm**

The bridge inherits the AMM identifiability machinery of Block 1 and
the (C1)-(C6) static identifiability conditions of v01. Each arm is
fitted by `gdpar()`, which runs the pre-flight identifiability check
internally and populates the `identifiability_report` slot of the
fit. The bridge records both reports as `id_check = list(treat = ...,
ctrl = ...)` in the returned object; failures in either arm propagate as
failures of the bridge construction (the upstream `gdpar()` call would
have refused to fit if (C1)-(C6) were violated).

**(C7) anti-aliasing of Block 6.5** (the grouped-anchor condition) is
*structurally moot* in Sub-phase 8.5.A because the bridge aborts on
hierarchical fits (§5, `use_groups == 0L` is required on both arms). The
design contract is documented here for forward compatibility: when a
future sub-phase extends the bridge to hierarchical fits, the canonical
treatment will invoke `gdpar:::.check_group_aliasing_c7()` on each
arm's design separately, and a violation in either arm will abort the
construction. The per-arm invocation, rather than a joint invocation, is
necessary because the two arms have independent group-anchor columns
(the per-group anchors $\theta_{\text{ref}}^{(t)}[g]$ are independent
across arms).

---

# **8. Minimum reproducible example**

The example below is a CRAN-valid demonstration of the bridge on
synthetic data. The treatment effect is heterogeneous in $x_1$
($\tau(x) = 1 + 0.5 x_1$); the example fits both arms, constructs the
bridge on a coarse evaluation grid, and prints the bridge and its
summary.

```{r dgp, eval = FALSE}
library(gdpar)
set.seed(20260524)
n_per_arm <- 300L
beta0 <- 0.2; beta1 <- 0.8
tau0  <- 1.0; tau1  <- 0.5  # true CATE: tau(x) = tau0 + tau1 * x
df_treat <- data.frame(
  x1 = rnorm(n_per_arm),
  y  = NA_real_
)
df_treat$y <- (beta0 + tau0) +
  (beta1 + tau1) * df_treat$x1 + rnorm(n_per_arm, sd = 0.4)
df_ctrl <- data.frame(
  x1 = rnorm(n_per_arm),
  y  = NA_real_
)
df_ctrl$y <- beta0 + beta1 * df_ctrl$x1 + rnorm(n_per_arm, sd = 0.4)
```

```{r fits, eval = FALSE}
fit_treat <- gdpar(
  formula       = y ~ x1,
  family        = gdpar_family("gaussian"),
  amm           = amm_spec(a = ~ x1),
  data          = df_treat,
  chains        = 2L,
  iter_warmup   = 500L,
  iter_sampling = 500L,
  refresh       = 0L,
  verbose       = FALSE
)
fit_ctrl <- gdpar(
  formula       = y ~ x1,
  family        = gdpar_family("gaussian"),
  amm           = amm_spec(a = ~ x1),
  data          = df_ctrl,
  chains        = 2L,
  iter_warmup   = 500L,
  iter_sampling = 500L,
  refresh       = 0L,
  verbose       = FALSE
)
```

```{r bridge, eval = FALSE}
grid <- data.frame(x1 = seq(-2, 2, length.out = 21L))
bridge <- gdpar_causal_bridge(fit_treat, fit_ctrl, newdata = grid)
print(bridge)
summary(bridge)
```

The expected output is a `gdpar_causal_bridge` object whose
per-observation `cate_mean` traces the linear function $1 + 0.5 \cdot x_1$
to within posterior credible bounds. The marginal ATE on the symmetric
grid $[-2, 2]$ is close to $1.0$ (the constant term of the heterogeneous
CATE).

To re-evaluate the bridge on a fresh grid without re-running the
compatibility checks, use `predict.gdpar_causal_bridge`:

```{r repredict, eval = FALSE}
grid2 <- data.frame(x1 = seq(-1, 1, length.out = 11L))
re <- predict(bridge, newdata = grid2)
str(re, max.level = 1L)
```

---

# **9. Limitations of the T-learner**

The T-learner is the most direct meta-learner from a structural
standpoint (one arm equals one fit equals one model), but it is not
universally optimal. The principal limitations are well-known
(Kuenzel et al. 2019 §3.4):

(a) **Regularization-induced bias in unbalanced samples.** When one arm
    is much larger than the other, the smaller arm's posterior is more
    diffuse and the bridge's CATE estimate inherits that diffusion
    asymmetrically. The T-learner has no mechanism to borrow strength
    across arms; the S-learner and X-learner do (the former by pooling
    in a single model, the latter by an explicit cross-arm correction).
    The diffusion is faithfully transmitted to the credible bounds, so
    the bridge does not understate uncertainty — but the *point*
    estimate may be biased toward the more diffuse arm's prior.

(b) **No common feature representation.** The two arms have independent
    AMM fits and therefore independent posterior estimates of the basis
    coefficients $a$, $c_b$, $W_{\text{raw}}$. Any feature that is
    informative *only* in combination with treatment is not modeled
    as such (the treatment indicator is absent from each arm's
    specification by construction); the two arms simply do not have a
    common feature space at the parameter level.

(c) **Sensitivity to mis-specification of the conditional mean.**
    Like all conditional-mean estimators, the T-learner relies on the
    correct specification of $\mu_t(x)$. AMM mitigates this via the
    explicit additive-multiplicative-modulated decomposition and the
    identifiability diagnostics of Block 2, but the underlying
    sensitivity remains: a mis-specified AMM in either arm produces a
    biased CATE.

**Deferred alternatives.** S-learner, X-learner, doubly-robust (DR), and
double-machine-learning (DML) constructions are queued for Block 9.
They will be added as separate functions (`gdpar_causal_s_learner`,
`gdpar_causal_x_learner`, `gdpar_causal_dr`, etc.) following the same
S3-friendly pattern as `gdpar_causal_bridge`, never as arguments of
`gdpar()`; the principle of strict separation between AMM as predictive
framework and CATE as causal overlay (§1) is preserved across all the
deferred constructions.

---

# **10. Open questions (O*-CATE)**

The following questions are deferred to Block 9 sub-phases or to
Sub-phase 8.5.B. Each is anchored to a specific Path or external
dependency.

> **(O1-CATE) Paths 2 and 3.** Extension of the T-learner AMM-side to
> the varying-coefficient model (Path 2) and the amortized hypernetwork
> (Path 3). The construction of Definition 8.5.A-1 is path-agnostic at
> the level of the fitted parameter $\widehat\theta^{(t)}(x)$, but the
> posterior of $\theta$ in Paths 2 and 3 is structurally different
> (penalized-spline posterior in Path 2; amortized variational
> posterior in Path 3) and the credible bounds of §6 need adaptation.
> Queued for Block 9.

> **(O2-CATE) Hierarchical bridges.** Extension to fits with
> `use_groups == 1L`. The canonical treatment will invoke
> `.check_group_aliasing_c7()` per arm (§7) and decompose the CATE into
> a between-group and a within-group component. The decomposition is
> non-trivial because the per-group anchors $\theta_{\text{ref}}^{(t)}[g]$
> are correlated across observations within the same group but
> independent across arms.

> **(O3-CATE) Comparator against external meta-learners.** Sub-phase
> 8.5.B will add `gdpar_compare_meta_learners` as an opt-in benchmark
> against `grf`, `causalForest`, and EconML (via `reticulate`). The
> charter of 8.5.B is opened only after 8.5.A closes; the dependency
> on Python (EconML) is the principal architectural reason for the
> sub-division.

> **(O4-CATE) S-learner and X-learner AMM-side.** Both meta-learners
> map naturally to the AMM pipeline: S-learner adds $T$ as a covariate
> in a single AMM specification and reads the CATE from the contrast
> between $T = 1$ and $T = 0$; X-learner imputes counterfactual
> outcomes by cross-arm prediction and refits. Both are queued for
> Block 9. The functions will be `gdpar_causal_s_learner` and
> `gdpar_causal_x_learner`.

> **(O5-CATE) Doubly-robust and double-machine-learning AMM-side.** DR
> and DML add a propensity-score model that the T-learner does not
> require. The propensity-score model can be a separate `gdpar` fit on
> the binary outcome $T_i$, or an external estimator passed via an
> argument. Queued for Block 9.

> **(O6-CATE) Diagnostics for the bridge.** A bridge-specific diagnostic
> battery (overlap plots, posterior-predictive checks per arm, ATE
> sensitivity to leave-one-out exclusion) would complement the existing
> per-fit diagnostics. The diagnostic module would consume a
> `gdpar_causal_bridge` object. Queued for Block 9.

---

# **Appendix A. Notational correspondence with Kuenzel et al. (2019)**

For readers familiar with the meta-learner literature, the following
table maps Kuenzel et al.'s notation to the AMM-side construction of
this addendum. Items marked "n/a" are concepts of Kuenzel et al. that
have no direct AMM-side analog or that are deferred to a later
sub-phase.

| Kuenzel et al. (2019) | This addendum (gdpar) |
|:----------------------|:----------------------|
| Base learner $M_t$ | `fit_treat` and `fit_ctrl` (a pair of `gdpar_fit` objects) |
| T-learner construction $\widehat\tau_T(x) = M_1(x) - M_0(x)$ | `gdpar_causal_bridge(fit_treat, fit_ctrl, newdata)` |
| Plug-in CATE estimate | `bridge$cate_mean` |
| Bootstrap or asymptotic CI for CATE | Posterior credible bounds `bridge$cate_ci` (per-observation), `summary(bridge)$ate_ci` (marginal ATE) |
| Cross-arm imputation (X-learner) | n/a in 8.5.A; queued as (O4-CATE) |
| Propensity-score model | n/a in 8.5.A; queued as (O5-CATE) for DR/DML |
| Treatment indicator $W_i$ (in their Section 2) | Determined extensionally by membership in `fit_treat$data` or `fit_ctrl$data`; the bridge does not see a treatment indicator |

The correspondence is structural, not numerical: the per-arm point
estimates of $M_t(x)$ depend on the base learner used (Kuenzel et al.
use random forests; this addendum uses AMM via gdpar); when the base
learners coincide the two formulations agree on the CATE.

---

# **Appendix B. Implementation notes for future external comparators (8.5.B preview)**

The bridge is decoupled from any external meta-learner. The principal
integration points for Sub-phase 8.5.B will be:

(i) **A common evaluation grid.** External meta-learners consume the
    same `newdata` data frame as `gdpar_causal_bridge` and return a
    per-observation CATE estimate (typically a vector of length
    $n_{\text{new}}$ with optional CIs). The 8.5.B comparator wraps
    each meta-learner in an adapter that returns a list with
    `cate_mean`, `cate_ci`, and a `method` tag.

(ii) **No assumption on the comparator's posterior.** Most external
     meta-learners do not produce a posterior; their CIs are obtained
     by bootstrap or by asymptotic approximation. The 8.5.B comparator
     does not equate `cate_ci` across methods of different inferential
     origin; the comparator reports the discrepancy in `cate_mean` and
     in `cate_ci` separately, leaving the interpretation to the user.

(iii) **No Python dependency in 8.5.A.** The optional EconML integration
      requires `reticulate` and a working Python environment with
      EconML installed. The dependency is isolated in Sub-phase 8.5.B's
      `Suggests` block and does not contaminate the core package
      `Depends` / `Imports`.

---

# **References cited in this addendum**

- **Holland, P. W.** (1986). Statistics and causal inference.
  *Journal of the American Statistical Association*, 81(396), 945-960.
- **Imbens, G. W., and Rubin, D. B.** (2015). *Causal Inference for
  Statistics, Social, and Biomedical Sciences: An Introduction*.
  Cambridge University Press.
- **Kuenzel, S. R., Sekhon, J. S., Bickel, P. J., and Yu, B.** (2019).
  Metalearners for estimating heterogeneous treatment effects using
  machine learning. *Proceedings of the National Academy of Sciences*,
  116(10), 4156-4165.
- **Rubin, D. B.** (1974). Estimating causal effects of treatments in
  randomized and non-randomized studies. *Journal of Educational
  Psychology*, 66(5), 688-701.

---

*End of Theoretical Addendum -- Block 8.5.A.*
