test: anchor ImputationDiD leave-one-out SE against Stata did_imputation (2nd Stata arm)#712
Conversation
Overall assessment✅ Looks good — no unmitigated P0 or P1 findings. Executive summary
MethodologyNo defects. The benchmark matches the Registry’s documented LOO residual rescaling and Stata convention ( Code QualityNo findings. PerformanceNo findings. The module-scoped fixture limits execution to two estimator fits. MaintainabilityNo findings. SSC package drift is explicitly documented and recorded in the golden metadata. Tech Debt
SecurityNo findings. No secrets or unexpected runtime network operations were introduced. Documentation/TestsNo findings. Tests cover overall and all six horizons for point estimates, LOO SEs, and non-LOO SEs ( |
1089fcc to
de9a997
Compare
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall assessment✅ Looks good — no unmitigated P0 or P1 findings. Executive summary
MethodologyNo findings. The affected method is Code QualityNo findings. PerformanceNo findings. Module-scoped fixtures limit execution to two estimator fits. MaintainabilityNo findings. SSC versions are recorded in the golden for drift detection. Tech Debt
SecurityNo findings. No secrets or unexpected runtime network operations were introduced. Documentation/Tests
JSON, YAML, and Python syntax validated. Full pytest execution was unavailable because the environment lacks pytest and scientific Python dependencies. |
…ion (2nd Stata arm, 1st SSC-dependent) The Borusyak-Jaravel-Spiess (2024) Supplementary Appendix A.9 leave-one-out finite-sample variance (opt-in `leave_one_out=True`) is a shipped, user-facing option that no independent implementation had ever confirmed: R `didimputation` omits LOO, so REGISTRY validated it only by an internal psi-identity + hand-calc + MC coverage. The authors' own Stata `did_imputation` ships the same option (`leaveout`); this turns that into a measured anchor. benchmarks/stata/generate_imputation_loo_golden.do runs `did_imputation y unit time Ei, [horizons(0/5)] leaveout avgeffectsby(Ei t) cluster(unit)` on the committed R-arm panel didimputation_test_panel.csv (no clean-sample reconstruction; the only mapping is Ei = first_treat, missing for never-treated). Agreement is cross-implementation (did_imputation goes through reghdfe, the library through its own sparse IF solver): the LOO SE matches to ~1e-9 and the point to ~2e-8 across the overall ATT and all 6 event-study horizons; the parity test gates at abs=1e-7. The non-LOO cluster SE is confirmed three-way (library = R = Stata on the same panel), overall and per horizon. First SSC-dependent arm (LPDiD used native teffects). The chain did_imputation -> reghdfe -> require + ftools is not pinned by `version 19` (SSC has no version history), so: the generator does NOT auto-install (that would fetch latest every run, breaking byte-identical regeneration) - install once via benchmarks/stata/requirements.do - and it records each package's version/date in meta.ssc_versions (asserted to be a real version line, not a description) for drift detection. avgeffectsby(Ei t) is pinned explicitly (== library aux_partition="cohort_horizon", also did_imputation's current default) to keep the estimand self-describing and robust to a future default change. tests/test_imputation_loo_stata_parity.py (29 cases) gates per horizon + overall at abs=1e-7, rel=0 (the repo's imputation SE-parity tolerance): point, LOO SE anchor, non-LOO SE, non-LOO three-way vs R (overall + per horizon), and a no-A.9-singleton-warning gate proving the LOO rescale is genuinely exercised. No diff_diff/ source changed. Docs: REGISTRY LOO note (inferred -> measured), borusyak review, benchmarks.rst (+ SSC prerequisites), benchmarks/README, benchmarks/stata/README, doc-deps (register the Stata README under imputation.py), CHANGELOG, TODO.md (coarser aux_partition follow-up). Stata is node-locked so - exactly like the R arm - the golden is committed and the test skips when absent. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X9m4hRxwqRnEJsv5ZhHY3i
de9a997 to
ed1f0a4
Compare
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall assessment✅ Looks good — no unmitigated P0 or P1 findings. Executive summary
MethodologyNo findings. Code QualityNo findings. PerformanceNo findings. Module-scoped fixtures limit execution to two estimator fits. MaintainabilityNo findings. SSC versions are captured and validated during regeneration ( Tech Debt
SecurityNo findings. No secrets or automatic runtime package installation were introduced. Documentation/TestsNo findings. The previous Gate 4 coverage issue is resolved by per-horizon R/Stata checks ( Python AST, JSON schema, panel shape, and numerical sanity checks passed. Full pytest execution was unavailable because the environment lacks pytest and scientific Python dependencies. |
Summary
ImputationDiD(leave_one_out=True)— the Borusyak-Jaravel-Spiess (2024) Supp. App. A.9 leave-one-out variance — which had no runnable R reference (Rdidimputationomits LOO) and was validated only by an internal psi-identity + hand-calc + MC coverage.benchmarks/stata/generate_imputation_loo_golden.doruns the authors' owndid_imputation ..., leaveout avgeffectsby(Ei t) cluster(unit)on the committed R-arm paneldidimputation_test_panel.csv(no clean-sample reconstruction; the only mapping isEi = first_treat, missing for never-treated).did_imputationgoes throughreghdfe, the library through its own sparse IF solver; the point to ~2e-8) across the overall ATT and all 6 event-study horizons. The non-LOO cluster SE is confirmed three-way (library = R = Stata on the same panel).did_imputation → reghdfe → require + ftoolsis not pinned byversion 19(SSC has no version history), so the generator does not auto-install (that would fetch latest every run) — install once viabenchmarks/stata/requirements.do— and it records each package's version/date inmeta.ssc_versions(asserted to be a real version line) for drift detection.diff_diff/source changed.Methodology references
ImputationDiDleave-one-out finite-sample variance (leave_one_out=True).did_imputation, leaveout(Borusyak, SSC).avgeffectsby(Ei t)is pinned explicitly (==aux_partition="cohort_horizon", alsodid_imputation's current default) to keep the estimand self-describing and robust to a future default change.Validation
tests/test_imputation_loo_stata_parity.py(23 cases) — per horizon + overall atabs=1e-7, rel=0(the repo's imputation SE-parity tolerance): point, LOO SE anchor, non-LOO SE, non-LOO three-way vs R, and a no-A.9-singleton-warning gate proving the LOO rescale is genuinely exercised.TestB2024AppendixA9LeaveOneOut) and doc-IA / doc-deps / refresh gates all pass. Stata is node-locked so — like the R arm — the golden is committed and the test skips when absent.Security / privacy
🤖 Generated with Claude Code
https://claude.ai/code/session_01X9m4hRxwqRnEJsv5ZhHY3i