Skip to content

chore(validation): shared n_bootstrap type guards + honest_did inference-df consolidation - #804

Merged
igerber merged 2 commits into
mainfrom
chore/infra-quick-sweep-1
Aug 29, 2026
Merged

chore(validation): shared n_bootstrap type guards + honest_did inference-df consolidation#804
igerber merged 2 commits into
mainfrom
chore/infra-quick-sweep-1

Conversation

@igerber

@igerber igerber commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Summary

  • Close two TODO.md Quick rows (infra sweep, PR 1 of 2):
  • n_bootstrap type guards — align the estimators the M-081 sweep deliberately carved out onto utils.validate_n_bootstrap, run BEFORE each retained floor: HeterogeneousAdoptionDiD (bool True previously ran as 1 replicate), ChaisemartinDHaultfoeuille (bool + float passed the bare < 0 check; the never-called _validate_invariants mirror aligned too so the sites cannot drift), TROP (float 2.5 passed the >= 2 floor), SyntheticDiD (guard now unconditional, closing the jackknife lane where bool/negative skipped even the floor; the pinned jackknife + n_bootstrap=1 behavior is unchanged), plus the two had_pretests.py floor sites (stute_test, stute_joint_pretest — a float like 999.5 previously floored through to np.empty(n_bootstrap)). Every estimator-specific floor and message is unchanged; all rejections verified by execution. M-081 ledger note prose + code_refs amended in the same diff (no lifecycle change).
  • honest_did inference-df consolidation — the three byte-identical precedence blocks (MPD/CS/dCDH branches) now call the shared aggregation.resolve_inference_df(); same precedence (survey df_survey → replicate 0.0 sentinel → df_inference fallback). Deliberate deltas: HonestDiDResults.df_survey is float-typed, and a fractional df_inference is preserved instead of int()-truncated. The results_base._resolve_scalar_df_survey sibling's stale docstring pointer updated (it must stay local — one-way import direction).

Methodology references (required if estimator / math changes)

  • Method name(s): N/A — validation hygiene and df-resolution refactor only; no estimator equations, weights, or variance formulas change (doc-deps REGISTRY consultation performed for all six touched sources: floors and their documented conventions — TROP >= 2, SDiD >= 2 unless jackknife, HAD >= 1, Stute >= 99 — are unchanged, so no REGISTRY edit is needed)
  • Paper / source link(s): N/A
  • Any intentional deviations from the source (and why): None

Validation

  • Tests added/updated: dCDH joins tests/test_v4_inference_policy.py's VALIDATED_CLASSES roster (floor 0); new TestFloorEstimatorTypeGuards covers TROP/SyntheticDiD (both lanes)/HAD — [1.5, True, None, -3] raise the shared message at init and via set_params with rollback, floors and the jackknife exemption pinned intact; had_pretests float/bool/None rejection tests beside both existing >= 99 floor pins; honest_did single-source oracle pins on the CS branch (float-typed, survey fit) and the dCDH branch (non-survey None + a survey fit with finite df == resolve_inference_df).
  • Backtest / simulation / notebook evidence (if applicable): execution spot-check of all rejection/floor/carve-out cases (TROP 2.5, SDiD jackknife True/−1/1, HAD True/0, dCDH 2.5/True/0) — shared message vs floor messages vs accepted exactly as documented.

Security / privacy

  • Confirm no secrets/PII in this PR: Yes

…solidation

- Align HAD/dCDH/TROP/SyntheticDiD (jackknife lane included) and the two
  had_pretests floor sites onto utils.validate_n_bootstrap: type-blind
  values (bool ran as 1 replicate; floats floored through) now raise the
  shared message; every estimator floor and message unchanged. dCDH joins
  the v4 policy roster; floor-carrying estimators get a dedicated
  type-guard test class. M-081 ledger note prose + code_refs amended (no
  lifecycle change).
- Consolidate honest_did's three duplicated inference-df precedence
  blocks onto aggregation.resolve_inference_df (df_survey now
  float-typed; fractional df_inference preserved); single-source oracle
  pins on the CS and dCDH branches; stale results_base docstring pointer
  updated.
@github-actions

Copy link
Copy Markdown

Overall Assessment

Looks good

Executive Summary

  • No P0/P1 findings.
  • Validation changes preserve documented estimator-specific bootstrap floors.
  • HonestDiD df precedence and fail-closed 0.0 sentinel match the Methodology Registry.
  • One minor release-note wording issue found.
  • Runtime tests were unavailable because pytest/numpy are not installed; changed Python files passed AST parsing.

Methodology

No findings. The affected methods are dCDH, HAD, SyntheticDiD, TROP, Stute pretests, and HonestDiD inference. No estimator equations, weights, SE formulas, or identification assumptions changed.

Code Quality

No findings.

Performance

No findings.

Maintainability

No findings. Consolidating HonestDiD onto resolve_inference_df() removes three drift-prone copies.

Tech Debt

No findings. The removed TODO rows are covered by the implemented validation and consolidation.

Security

No findings.

Documentation/Tests

P3 — Bootstrap error-message compatibility is overstated

  • Location: CHANGELOG.md:L11-L19, docs/v4-deprecations.yaml:L1042
  • Impact: Both claim every floor message is unchanged, but negative values now reach the shared validator and receive its generic message; dCDH’s former negative-value message was removed. Runtime correctness is unaffected.
  • Concrete fix: Qualify the claim: non-negative sub-floor integers retain estimator-specific messages, while negative values now use the shared validation message.

@github-actions

Copy link
Copy Markdown

🔁 AI review rerun (requested by @igerber)

Head SHA: 8b25e8eecd7d588cbdfe8ff0fdc3d2b8eca02fe3


Overall Assessment

Looks good

Executive Summary

  • No P0/P1 findings.
  • Bootstrap guards preserve all registry-defined estimator floors.
  • HonestDiD df precedence and replicate 0.0 sentinel remain correct.
  • Prior release-note P3 is resolved at CHANGELOG.md:L19-L22.

Methodology

No findings. Affected methods: dCDH, HAD, SyntheticDiD, TROP, Stute pretests, and HonestDiD inference. Changes conform to docs/methodology/REGISTRY.md.

Code Quality

No findings.

Performance

No findings.

Maintainability

No findings. Shared df resolution removes three duplicate implementations.

Tech Debt

No findings. Completed work is removed from TODO.md and recorded under M-081.

Security

No findings.

Documentation/Tests

No findings. Changed Python files and the YAML ledger parse successfully. Runtime tests could not run because pytest and numerical dependencies are unavailable in the review environment.

@igerber igerber added the ready-for-ci Triggers CI test workflows label Aug 29, 2026
@igerber
igerber merged commit 72e78b7 into main Aug 29, 2026
39 of 40 checks passed
@igerber
igerber deleted the chore/infra-quick-sweep-1 branch August 29, 2026 23:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-ci Triggers CI test workflows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant