Commit 4be416a
Wave D fail-closed HC1/CR1 multiplier on saturated stage-2 designs
When the kept stage-2 design saturates the sample (n_obs == effective_rank
after rank-deficient drops), the HC1 multiplier n/(n-p) and the CR1
multiplier (n-1)/(n-p) are mathematically undefined. The original Wave D
helper used `max(n - p_2, 1)` to clamp the denominator, which silently
fabricated finite multipliers on underdetermined fits — `result.se` and
per-coefficient SEs could stay finite even when only `t_stat`/`p_value`/CI
were NaN-gated via `df_resid=0`. That violates the no-silent-failures
contract.
Fix: when n - p_2 <= 0, return NaN meat with an explicit UserWarning
so the SE surface NaN-propagates consistently with the inference fields.
The Conley path is unaffected (no finite-sample multiplier on that
branch by convention).
Tests: new `test_saturated_design_yields_nan_se_not_finite` in
TestSpilloverDiDWaveDPublicVarianceContract exercises both the HC1 and
CR1 paths on a synthetic n=p_2=4 Psi fixture; asserts NaN meat AND
the saturation warning fires.
Docs: replaced "Wave B MVP limitations" section heading at
docs/api/spillover.rst with "Restrictions and follow-ups" (the
section now describes the shipped Wave D variance + remaining
limitations); updated the SpilloverDiD vs TwoStageDiD comparison table
to label the Conley and cluster rows "(Wave D GMM-corrected sandwich)"
instead of "(via solve_ols at stage 2)".
All 224 spillover tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent cb1ad09 commit 4be416a
3 files changed
Lines changed: 85 additions & 9 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
208 | 208 | | |
209 | 209 | | |
210 | 210 | | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
211 | 226 | | |
212 | | - | |
| 227 | + | |
213 | 228 | | |
214 | 229 | | |
215 | 230 | | |
| |||
223 | 238 | | |
224 | 239 | | |
225 | 240 | | |
226 | | - | |
| 241 | + | |
227 | 242 | | |
228 | 243 | | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
229 | 257 | | |
230 | 258 | | |
231 | 259 | | |
232 | 260 | | |
233 | 261 | | |
234 | 262 | | |
235 | | - | |
| 263 | + | |
236 | 264 | | |
237 | 265 | | |
238 | 266 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
160 | 160 | | |
161 | 161 | | |
162 | 162 | | |
163 | | - | |
| 163 | + | |
164 | 164 | | |
165 | 165 | | |
166 | 166 | | |
167 | | - | |
| 167 | + | |
168 | 168 | | |
169 | 169 | | |
170 | 170 | | |
171 | | - | |
172 | | - | |
| 171 | + | |
| 172 | + | |
173 | 173 | | |
174 | | - | |
175 | | - | |
| 174 | + | |
| 175 | + | |
176 | 176 | | |
177 | 177 | | |
178 | 178 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4458 | 4458 | | |
4459 | 4459 | | |
4460 | 4460 | | |
| 4461 | + | |
| 4462 | + | |
| 4463 | + | |
| 4464 | + | |
| 4465 | + | |
| 4466 | + | |
| 4467 | + | |
| 4468 | + | |
| 4469 | + | |
| 4470 | + | |
| 4471 | + | |
| 4472 | + | |
| 4473 | + | |
| 4474 | + | |
| 4475 | + | |
| 4476 | + | |
| 4477 | + | |
| 4478 | + | |
| 4479 | + | |
| 4480 | + | |
| 4481 | + | |
| 4482 | + | |
| 4483 | + | |
| 4484 | + | |
| 4485 | + | |
| 4486 | + | |
| 4487 | + | |
| 4488 | + | |
| 4489 | + | |
| 4490 | + | |
| 4491 | + | |
| 4492 | + | |
| 4493 | + | |
| 4494 | + | |
| 4495 | + | |
| 4496 | + | |
| 4497 | + | |
| 4498 | + | |
| 4499 | + | |
| 4500 | + | |
| 4501 | + | |
| 4502 | + | |
| 4503 | + | |
| 4504 | + | |
| 4505 | + | |
| 4506 | + | |
| 4507 | + | |
| 4508 | + | |
4461 | 4509 | | |
4462 | 4510 | | |
4463 | 4511 | | |
| |||
0 commit comments