Skip to content

Commit 6c4ab94

Browse files
igerberclaude
andcommitted
ConleySpatialHAC methodology-review-tracker promotion + Bertanha-Imbens 2014 citation correction
Three bundled changes: 1. ConleySpatialHAC methodology-review-tracker promotion (In Progress → Complete). - METHODOLOGY_REVIEW.md L91 + L1262-1290 flipped Complete with full Verified Components / Test Coverage / R Comparison Results inline table / Corrections Made / Deviations / Outstanding Concerns structure, with Last Review = 2026-05-26. - New tests/test_methodology_conley.py (~1600 LoC; 10 classes; 60 tests, 5 of them @pytest.mark.slow). Paper-equation-numbered Verified Components walk-through covering: * Eq. 4.2 cross-sectional sandwich (pairwise-distance specialization; Eq. 3.13 is the lattice-indexed form reserved for grid coordinates) * Eq. 4.2 HC0 + rank-1 limits + K(0) = 1 diagonal contribution * Andrews (1991) HAC lag truncation matching conleyreg::time_dist.cpp * Haversine convention with Earth radius 6371.01 km (matches conleyreg::haversine_dist) * Phase 2 panel block-decomposed sandwich at atol=1e-12 (internal cross-check vs hand-coded reference + cluster time-invariance contract) * Wave A igerber#120 sparse k-d-tree numerical correctness (sparse-vs- dense bit-identity at atol=1e-10 on cross-sectional, panel, and sparse-with-cluster paths) * R conleyreg v0.1.9 parity at atol=1e-6 on 6 fixtures (3 cross-sectional + 3 panel) + sparse-forced cross-sectional + sparse-forced panel + time-asymmetric kernel literal-matching Three dedicated deviations-area classes: * TestConleyLibraryExtensions (6 tests, no R correspondence): combined spatial+cluster product kernel Wave A igerber#119 (two limit-fixture anchors), callable conley_metric validation Wave A igerber#123, sparse k-d-tree activation Wave A igerber#120, indefiniteness guard on Bartlett + uniform kernels. * TestConleyDeviationsFromR (3 tests): 1-D radial Bartlett vs paper's 2-D separable Eq. 3.14, time-label normalization, independent temporal kernel deferred. * TestConleyDeferrals (5 tests): fail-closed NotImplementedError / TypeError contracts for LinearRegression + survey_design, DiD/MPD/TWFE + survey_design (estimator-level via conley.py::_validate_conley_estimator_inputs), Conley + weights (rejected for any weight_type — pweight, aweight, fweight), SyntheticDiD + Conley (TypeError), wild_bootstrap + Conley. - tests/test_conley_vcov.py extracted 1135+ LoC out (4248 → 3113); defensive surface preserved (input validation, NaN/inf guards, dispatch-level validity, estimator-level integration smoke tests, set_params atomicity, sparse-path activation thresholds + density- gate fallback). Module docstring refreshed to describe its current defensive-regression role. 2. Stale priority-queue cleanup at METHODOLOGY_REVIEW.md L1386: - PreTrendsPower removed (already Complete since 2026-05-19). - ConleySpatialHAC removed (this PR). - Substantive-review-blocked renumbered igerber#2-igerber#5igerber#1-igerber#4. - Consolidation-pass-blocked renumbered igerber#6-igerber#8igerber#5-igerber#6. 3. Bertanha-Imbens 2014 citation correction across 16 sites: - linalg.py × 8, conley.py × 1, llms-full.txt × 2, REGISTRY.md × 4, spillover.rst × 1. - NBER w20773 is on FRD external validity, NOT weighted spatial-HAC. - The boundary is now framed as a tri-part contract: * Shipped — SpilloverDiD + Conley + survey via Wave E.1/E.2/E.3 (PR igerber#468/igerber#474/igerber#482, stratified-Conley sandwich on PSU totals with within-PSU serial Bartlett HAC for lag_cutoff > 0); TwoStageDiD + Conley + survey via Wave E.3 parity (PR igerber#485). * Deferred (generic linalg surface, any weight_type) — DiD/MPD/ TWFE/LinearRegression generic path + Conley + survey_design; LinearRegression / compute_robust_vcov Conley + weights rejected for pweight, aweight, AND fweight (weighted Conley is not implemented on the generic linalg surface). * Open methodological question (subset) — the pweight / survey_design portion of the deferral additionally lacks a canonical methodological extension of Conley (1999) for weighted spatial-HAC under probability sampling. - REGISTRY sites use canonical `**Note (open methodological question):**` label wrapper per CLAUDE.md "Documenting Deviations". - Historical CHANGELOG entries (pre-[Unreleased]) intentionally retain Bertanha-Imbens 2014 attribution as accurate records of past release claims. Verification: - pytest tests/test_methodology_conley.py: 60 tests (55 unit + 5 slow) pass. - pytest tests/test_methodology_conley.py + tests/test_conley_vcov.py: 176 pass + 5 slow deselected (preserves pre-edit baseline coverage 176 vs original 175 + 1 new uniform-kernel indefiniteness guard). - grep -rn "Bertanha" diff_diff/ docs/ benchmarks/: 0 hits. - black + ruff clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 2656e44 commit 6c4ab94

9 files changed

Lines changed: 1962 additions & 1289 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
- **ConleySpatialHAC methodology-review-tracker promotion: In Progress → Complete.** Closes the Conley (1999) *Journal of Econometrics* 92(1) primary-source review on the methodology-review tracker. The paper review on file at `docs/methodology/papers/conley-1999-review.md` was previously merged (2026-05-09); this PR is the F.L.I.P. consolidation — new `tests/test_methodology_conley.py` with paper-equation-numbered Verified Components walk-through (~1600 LoC; 10 classes; 60 tests, 5 of them `@pytest.mark.slow`). Coverage: Eq. 4.2 cross-sectional sandwich (pairwise-distance specialization; the project's paper review identifies Eq. 4.2 page 18 as the real-valued/pairwise form, with Eq. 3.13 reserved for the lattice-indexed form), Eq. 4.2 HC0 + rank-1 limits, Andrews (1991) HAC lag truncation matching `conleyreg::time_dist.cpp`, haversine convention with Earth radius 6371.01 km, Phase 2 panel block-decomposed sandwich at `atol=1e-12`, sparse k-d-tree dense-vs-sparse bit-identity (Wave A #120 numerical correctness), and R `conleyreg` v0.1.9 parity at `atol=1e-6` on 6 fixtures (3 cross-sectional + 3 panel) plus the sparse-forced and time-asymmetric kernel parity contracts. Three dedicated deviations-area classes: `TestConleyLibraryExtensions` (Wave A library extensions — combined spatial+cluster product kernel #119, callable conley_metric validation #123, sparse k-d-tree activation #120, indefiniteness guard), `TestConleyDeviationsFromR` (1-D radial Bartlett vs paper's 2-D separable Eq. 3.14, time-label normalization via `np.unique`, independent temporal kernel deferred), and `TestConleyDeferrals` (5 fail-closed `NotImplementedError`/`TypeError` contracts: LinearRegression + survey_design, DiD/MPD/TWFE + survey_design, Conley + weights, SyntheticDiD + Conley, wild_bootstrap + Conley). Methodology-anchored tests extracted from `tests/test_conley_vcov.py`: full classes `TestConleyDirectHelper`, `TestConleyReductions`, `TestConleyReductionsAddendum`, `TestConleyParityR`, `TestConleyParitySpacetime`, `TestConleyPanelHelper`, `TestConleySparseRParityForced`; plus methodology-anchored tests from `TestConleyKernels`, `TestConleyDistanceMetrics`, `TestConleySparse`. File drops 4248 → 3113 lines after extraction. Defensive surface preserved: input validation, NaN/inf guards, dispatch-level validity, estimator-level integration smoke tests, set_params atomicity, sparse-path activation thresholds + density-gate fallback. `METHODOLOGY_REVIEW.md` row L91 promoted to **Complete** with `Last Review = 2026-05-26`; detail block rewritten with Verified Components / Test Coverage / R Comparison Results inline table / Corrections Made / Deviations / Outstanding Concerns. Priority queue at L1386 pruned: PreTrendsPower removed (already Complete since 2026-05-19) and ConleySpatialHAC removed (this PR); substantive-review-blocked renumbered #2-#5 → #1-#4 and consolidation-pass-blocked renumbered #6-#8 → #5-#6.
12+
1013
### Added / Changed
1114
- **EfficientDiD `vcov_type` threading + Results metadata harmonization (Phase 1b interstitial #4, permanently narrow).** `EfficientDiD(vcov_type=...)` now accepts `{"hc1"}` only (default). Analytical-sandwich families `{classical, hc2, hc2_bm}` and `conley` are REJECTED at `__init__` / `set_params` with methodology-rooted messages — EfficientDiD uses influence-function-based variance per Chen-Sant'Anna-Xie (2025) achieving the semiparametric efficiency bound; the per-unit EIF aggregation has no single design matrix on which hat-matrix leverage or Bell-McCaffrey Satterthwaite DOF can be defined. `cluster=` (Liang-Zeger CR1 on cluster-aggregated EIF) and `survey_design=` (TSL on combined IF) paths are unchanged. **BC break on `EfficientDiDResults`:** the `cluster` field renamed to `cluster_name`; new `n_clusters` + `vcov_type` fields added; `to_dict()` method added (mirrors TripleDifferenceResults). `DiagnosticReport._pt_hausman` updated to read the renamed `cluster_name` field for the Hausman pretest replay (`diff_diff/diagnostic_report.py:2444`). `EfficientDiD.set_params(vcov_type=bad)` raises immediately rather than deferring to `fit()` — intentional eager-validation pattern matching EfficientDiD's existing handling of `pt_assumption`/`control_group` etc, diverging from `ImputationDiD`/`TripleDifference`/`CallawaySantAnna` (which use sklearn mutate-then-validate-at-use). Survey-PSU bootstrap path returns NaN SE when fewer than 2 independent PSUs are available (was ≈0 SE from BLAS roundoff). New summary block: `Variance estimator: <label>` line rendered after the survey block when not under bootstrap; suppressed under bootstrap (replaced with `Inference method: bootstrap` + `Bootstrap replications: <n>`). Default `cluster=None` (no survey) renders "HC1 heteroskedasticity-robust" — methodologically correct because the per-unit EIF SE `sqrt(mean(EIF²)/n)` is HC1-style (no Liang-Zeger G/(G-1) finite-sample correction); diverges from `ImputationDiD` which auto-clusters at unit per BJS Theorem 3.
1215

16+
### Fixed
17+
- **Bertanha-Imbens 2014 citation correction (16 sites across 5 files).** A verification spike confirmed the citation across `diff_diff/linalg.py` (×8), `diff_diff/conley.py` (×1), `diff_diff/guides/llms-full.txt` (×2), `docs/methodology/REGISTRY.md` (×4), and `docs/api/spillover.rst` (×1) was incorrect — NBER w20773 *External Validity in Fuzzy Regression Discontinuity Designs* (JBES 2020, 38(3):593-612) by Bertanha & Imbens covers fuzzy RD external validity, NOT weighted spatial-HAC under sampling weights. Replaced across all 16 sites with the open-problem framing: "weighted spatial-HAC under probability sampling is an open methodological question; no canonical extension of Conley (1999) exists for the combination." At the four `REGISTRY.md` sites the replacement is wrapped in the canonical `**Note (open methodological question):**` label per CLAUDE.md "Documenting Deviations (AI Review Compatibility)". REGISTRY ConleySpatialHAC section gains a new `**Note (deferral status, 2026-05-26):**` splitting the boundary into three parts: **Shipped** — SpilloverDiD + Conley + survey via Wave E.1/E.2/E.3 (PR #468/#474/#482), TwoStageDiD + Conley + survey via Wave E.3 parity (PR #485). **Deferred (generic linalg surface, any `weight_type`)** — DiD/MPD/TWFE/LinearRegression generic path + Conley + `survey_design=`; `LinearRegression` / `compute_robust_vcov` Conley + `weights=` rejected for `pweight`, `aweight`, AND `fweight` (weighted Conley is not implemented on the generic linalg surface). **Open methodological question (subset)** — the `pweight` / `survey_design` portion of the deferral additionally lacks a canonical methodological extension of Conley (1999) for weighted spatial-HAC under probability sampling. **No source-code logic changes:** verified via diff-in-diff pytest output before and after the citation strip (175 passed + 14 warnings, bit-identical pass set on `tests/test_conley_vcov.py`). **Historical CHANGELOG entries (pre-[Unreleased]) intentionally retain the Bertanha-Imbens 2014 attribution** as accurate records of what was claimed at the time of each release; the [Unreleased] entry above supersedes those rationales going forward.
18+
1319
## [3.4.2] - 2026-05-25
1420

1521
### Fixed

0 commit comments

Comments
 (0)