CJE Playbook: Audits, Drift Response, and Label Budgeting
July 7, 2026 · View on GitHub
This is the operational runbook for:
- running transport audits,
- deciding what to do when audits pass vs fail,
- planning oracle label budgets.
It is written against the current CJE API in this repo. CJE 0.4.0+ is Direct-mode only; this runbook is the whole operating loop. (Off-policy IPS/DR workflows live on the frozen 0.3.x line: pip install "cje-eval==0.3.*".)
Canonical Operational Loop
The recommended loop is:
- Design metrics (choose/adjust
SandY) - Sample (judge scores + oracle labels)
- Fit judge→oracle mapping with uncertainty
- Precision gate: precise enough?
- No -> collect more
Ylabels, return to Step 2 - Yes -> deploy
- No -> collect more
- Deploy
- Monitor with new oracle labels and residuals
- Drift gate: CI on mean residual excludes 0?
- No -> keep monitoring (Step 6)
- Yes -> inspect failure patterns, improve judge/oracle, then return to Step 1
Two-loop framing:
- Inner calibration loop: Steps 1-4
- Outer monitoring loop: Steps 5-7
This playbook’s sections below implement those same steps using CJE APIs.
1) Baseline Evaluation Run
Run your main analysis with bootstrap inference (default in Direct mode).
from cje import analyze_dataset
results = analyze_dataset(
fresh_draws_dir="responses/current_batch",
estimator="direct",
estimator_config={
"inference_method": "bootstrap",
"n_bootstrap": 2000,
"use_augmented_estimator": True,
},
)
print(results.estimates)
print(results.standard_errors)
Notes:
bootstrap+use_augmented_estimator=Trueis the production default.
Pairwise comparisons
Use results.compare_policies(i, j) for any "is A better than B?" claim — never eyeballed
CI overlap. On the bootstrap path it performs paired inference over the (B × P) replicate
matrix (method: "paired_bootstrap" in the returned dict), so the difference SE includes
calibrator-refit noise; pre-0.5.1 influence-function difference SEs were anti-conservative
on near-tie pairs (~90% false significance in the pre-registered benchmark). For many-pair
sweeps use results.compare_all_policies(adjust="bh") (Benjamini-Hochberg-adjusted
p-values).
2) Run a Transport Audit (Probe Protocol)
Use a small oracle-labeled probe slice (typically 40-60 rows) on the target policy/group. results.calibrator is the fitted calibration model returned by analyze_dataset in Section 1.
import json
from cje.diagnostics import audit_transportability
probe = [json.loads(line) for line in open("probes/policy_gpt56mini.jsonl")]
diag = audit_transportability(
calibrator=results.calibrator,
probe_samples=probe,
group_label="policy:gpt-5.6-mini",
)
print(diag.summary())
# Transport: PASS/WARN/FAIL | Group: ... | N=... | δ̂: ... | Action: ...
Audit Thresholds
The classifier uses:
PASS:0is inside the 95% CI forδ̂ = E[Y - f(S)]WARN: CI excludes 0, andabs(δ̂) < 0.05FAIL: CI excludes 0, andabs(δ̂) >= 0.05
3) Decision Policy After Audit
PASS
Interpretation:
- No statistically detectable mean bias on the probe group (
0inside CI).
Action:
- Reuse calibrator for current cycle (equivalent to Step 7 "No drift").
- Keep normal monitoring cadence.
- Optionally merge probe labels into calibration history for the next cycle.
WARN
Interpretation:
- Detectable but small bias.
Action:
- Increase probe size next cycle.
- Inspect residual structure by decile.
- Consider anchoring updates through pooled recalibration if WARN persists.
FAIL
Interpretation:
- Clear bias; do not rely on unchanged calibrator for high-stakes decisions.
Action:
- Follow the correction protocol in Section 5 (collect labels → EIF correction → escalate to refit if needed).
- Treat this as Step 7 "drift detected" → return to Step 1 of the loop.
4) Incorporate New Audit Data When Audits PASS
When probe results pass, treat probe labels as additional calibration signal for future runs.
Recommended pattern:
- Append validated probe labels to a maintained calibration dataset.
- Re-run the Section 1 analysis adding
calibration_data_path="data/oracle_history.jsonl"andcombine_oracle_sources=Trueto pool all high-quality labels.
5) Correct for Failed Audits
Step A: Collect more target-policy oracle labels
- Sample 100-200 labels across score deciles (not only difficult prompts).
- Keep labeling random within strata to preserve ignorability.
Step B: Apply policy-specific EIF correction (default)
Re-run analyze_dataset with the expanded oracle labels pooled in (same pattern as Section 4). The augmented estimator (use_augmented_estimator=True) automatically applies per-policy residual correction using the new labels — this fixes mean drift without refitting the calibrator.
Step C: Escalate to refit if residuals show structural drift
If decile residuals trend with score or covariates (not just a level shift), refit with include_response_length=True and/or calibration_covariates.
How to decide: Plot Y - f_old(S) by score decile. Flat = Step B suffices. Trending = Step C needed.
For the full analysis of correction strategies, see Post-Audit Drift Correction.
6) Label Budgeting (How Many Oracle Labels?)
Budgeting uses the planning model:
- total variance
= sigma2_eval / n + sigma2_cal / m - costs
B = c_S * n + c_Y * m - optimize with square-root allocation law.
from cje.data.fresh_draws import load_fresh_draws_auto
from cje.diagnostics import CostModel, fit_variance_model, plan_evaluation, plan_for_mde
# Fit variance model from pilot data (recommended)
base_pilot = load_fresh_draws_auto("responses/pilot", "base")
variance_model = fit_variance_model(
base_pilot,
n_replicates=150, # extra-stable fit, ~20s since 0.5.1; the default (50) gives R2~0.85 in a few seconds
verbose=True,
)
# No pilot yet? Use simulation instead:
# from cje.diagnostics import simulate_variance_model
# variance_model = simulate_variance_model(r2=0.7, verbose=True)
cost = CostModel(surrogate_cost=0.01, oracle_cost=0.16)
# Fixed budget -> achievable sensitivity
plan = plan_evaluation(budget=5000, variance_model=variance_model, cost_model=cost)
print(plan.summary())
print(plan.n_samples, plan.m_oracle, plan.mde)
# Target sensitivity -> required budget
plan_target = plan_for_mde(
target_mde=0.01,
variance_model=variance_model,
cost_model=cost,
)
print(plan_target.total_cost)
Label budgeting rules
- Always sample oracle labels randomly (or randomly within strata).
- Use real dollar costs in
CostModel. - Refit the variance model periodically with new pilot/production evidence.
- If audit FAIL frequency rises, increase planned
m_oracleand rerun planning.
Planning caveats (read before trusting the numbers)
- MDE assumes independent policies; paired evals on a shared prompt set typically detect smaller differences (plans are conservative).
- Variance components are measured with the analytic cluster-robust + OUA instrument, which tracked the realized SE of the production estimator within ~5% at every allocation in a pilot-scale validation grid (instrument experiment 2026-07-07, R=400 replicates/cell). Budgets planned with pre-0.5.1 versions used a bootstrap instrument that ran 15-29% hot at pilot-sized label counts — those older budgets were inflated upper bounds; re-running planning on the same pilot will typically return ~15-20% smaller budgets.
7) Suggested Operational Cadence
Per evaluation cycle:
- Run
analyze_dataset(...)with bootstrap inference. - Run transport audit on each deployment-relevant target policy.
- Route by PASS/WARN/FAIL using Section 3.
- Merge accepted audit labels into calibration history.
- Re-run planning quarterly (or after judge/oracle regime changes).
8) Minimal Checklist
- Inference:
inference_method="bootstrap",n_bootstrap=2000 - Debiasing:
use_augmented_estimator=True - Probe size: 40-60 oracle labels per target group
- FAIL response: collect 100-200 target labels, re-run with pooled labels (EIF correction is automatic); escalate to refit if residuals are score-conditional
- Planning:
fit_variance_model+plan_evaluation/plan_for_mde