spillover-conley: dedup serial Bartlett kernel + PSD guard helpers#489
Conversation
Extract _serial_bartlett_kernel_matrix(t_codes, L) and
_validate_meat_psd(M, *, error_msg, warning_template, stacklevel=3) to
diff_diff/conley.py. Collapses three inline kernel constructions
(conley.py panel-block, two_stage.py survey singleton-adjust,
two_stage.py survey multi-PSU) and two inline finite+eigvalsh guards
(conley.py _compute_conley_meat, two_stage.py survey orchestrator)
into shared helpers, so no-survey and survey paths cannot drift on
kernel weights, finite check, or the -1e-12 PSD threshold.
No behavior change. Methodology anchor at
tests/test_spillover.py::TestSpilloverDiDWaveE2FollowupConleySurveyLagCutoff
(21 tests) and the existing PSD-warning monkey-patch tests at
tests/test_conley_vcov.py:{654,709} still pass byte-identically
(substring "bartlett"/"uniform"/"negative eigenvalue" preserved).
Adds 9 new unit tests: 5 kernel-matrix (hand-computed L=2/L=1/L=0/
single-element + int-vs-float bit-equality contract) and 4 PSD-guard
(non-finite raises with caller's error_msg, negative eigval warns with
{eigval:.2e} substitution, PSD silent, threshold boundary at -5e-13
silent). REGISTRY one-liner at both the no-survey Conley section and
the Wave E.2 follow-up panel-block section. Drops the Bartlett-dedup
row from TODO.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds three defensive tests in TestValidateMeatPsd that lock the stacklevel contract on both helper-call surfaces: - test_stacklevel_attributes_to_caller_frame: unit test on a 2-deep wrapper proving stacklevel=3 attributes the warning to the caller's caller (outer wrapper), not to the helper frame. - test_no_survey_path_attributes_warning_to_user_code: end-to-end warning-capture via _compute_conley_vcov with a monkey-patched indefinite-bartlett kernel; asserts the warning bubbles through the three internal frames (_validate_meat_psd → _compute_conley_meat → _compute_conley_vcov) to land at user code. Locks stacklevel=4 at the no-survey call site. - test_survey_call_site_passes_stacklevel_3: static source check on _compute_stratified_conley_meat (two_stage.py) confirming it passes stacklevel=3 to _validate_meat_psd. The +1 frame shift from the helper extraction (pre-extraction was stacklevel=2 inline) means regressing this kwarg would silently re-attribute warnings to inside the helper. No source changes; tests only. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Overall Assessment ✅ Looks good Executive Summary
Methodology
Code Quality
Performance
Maintainability
Tech Debt
Security
Documentation/Tests
|
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment ✅ Looks good Executive Summary
Methodology Affected methods: Code Quality No findings. The refactor removes duplicated kernel/PSD logic without introducing new inline inference or NaN-handling anti-patterns. Performance No findings. This is a mechanical extraction of existing kernel and Maintainability No findings. Centralizing the serial Bartlett kernel and PSD guard materially reduces drift risk between the survey and no-survey implementations. Tech Debt No findings. Removing the closed Bartlett-dedup item from Security No findings. Documentation/Tests
|
…ution Adds test_survey_path_attributes_warning_to_user_code in TestValidateMeatPsd. Mirrors the existing no-survey runtime attribution pattern (monkey-patch the kernel helper to force an indefinite combined meat) but exercises the SURVEY orchestrator _compute_stratified_conley_meat with conley_lag_cutoff=1. Captures the resulting PSD UserWarning and asserts attribution lands at user code (this test file), proving stacklevel=3 correctly bubbles the warning through both the helper (conley.py) and the orchestrator (two_stage.py). CI codex flagged the prior survey-path coverage as too weak: the existing test_survey_call_site_passes_stacklevel_3 is a static inspect.getsource() substring check on `stacklevel=3`, which can false-pass if runtime attribution drifts while the literal text remains. This commit adds the missing runtime check; the static check is retained as a complementary fast-fail. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment ✅ Looks good Executive Summary
Methodology No findings. Code Quality No findings. The refactor is complete within the touched production code: I did not find leftover inline serial Bartlett matrix construction or duplicated finite-plus- Performance No findings. This is a mechanical extraction of existing dense kernel and eigenvalue work; asymptotic cost and memory behavior are unchanged. Maintainability No findings. Moving the serial Bartlett kernel and PSD guard into shared helpers materially reduces drift risk between the Conley no-survey path and the Spillover/TwoStage survey path. Tech Debt No findings. Removing the closed Bartlett-dedup row from Security No findings. Documentation/Tests No findings. The new helper coverage is adequate for the refactor surface: kernel/PSD helper tests were added at |
Summary
_serial_bartlett_kernel_matrix(t_codes, L)and_validate_meat_psd(M, *, error_msg, warning_template, stacklevel=3)todiff_diff/conley.py, collapsing 3 inline kernel constructions (conley.py panel-block + 2 two_stage.py survey branches) and 2 inline finite/eigvalsh PSD guards into shared helpers. No behavior change — the methodology lock (1 - |t-s|/(L+1)Bartlett weights, panel-wide dense time codes,< -1e-12PSD threshold) now lives behind named helpers; survey and no-survey paths cannot drift on kernel weights or diagnostics.{eigval:.2e}substitution, PSD silent, threshold boundary at -5e-13 silent), 3 stacklevel-attribution (unit test on the helper mechanic, end-to-end via_compute_conley_vcovproving warnings bubble to user code, static source check pinningstacklevel=3on the survey orchestrator call site).TODO.md(L150compute_survey_metadataextraction is a separate open item — left untouched).Methodology references (required if estimator / math changes)
ConleySpatialHAC(no-survey panel-block path) +SpilloverDiDWave E.2 follow-up survey-side stratified-Conley + serial Bartlett path.conleyreg(Düsterhöft 2021,time_dist.cpp) for the 1-D radial Bartlett deviation. All as already documented indocs/methodology/REGISTRY.md.< -1e-12PSD threshold; the REGISTRY one-liners explicitly cross-reference the no-survey and survey paths through the shared helpers.Validation
tests/test_conley_vcov.pyextended with 12 new tests (5 inTestConleyKernels, 7 in newTestValidateMeatPsdclass). Existing PSD-warning monkey-patch tests attests/test_conley_vcov.py::TestConleyDirectHelper::{test_uniform_kernel_negative_eigenvalue_warns, test_indefinite_meat_warning_fires_for_bartlett}still pass byte-identically (substring\"bartlett\"/\"uniform\"/\"negative eigenvalue\"preserved in warning messages). The methodology anchor attests/test_spillover.py::TestSpilloverDiDWaveE2FollowupConleySurveyLagCutoff(21 hand-computed Bartlett HAC tests including the L=1 anchor at L7054-7062) remains bit-equal pre/post refactor — pure refactor confirmed via 575-test green slice acrosstests/test_conley_vcov.py + tests/test_two_stage.py + tests/test_spillover.py.Security / privacy
Generated with Claude Code