Skip to content

feat(v4): semantic rename wave - post/control_group/vcov-only/level shims + missed-rename amendments (2(c)-ii PR-B, 15 rows) - #743

Merged
igerber merged 3 commits into
mainfrom
feat/v4-rename-semantic
Aug 2, 2026
Merged

feat(v4): semantic rename wave - post/control_group/vcov-only/level shims + missed-rename amendments (2(c)-ii PR-B, 15 rows)#743
igerber merged 3 commits into
mainfrom
feat/v4-rename-semantic

Conversation

@igerber

@igerber igerber commented Aug 2, 2026

Copy link
Copy Markdown
Owner

Summary

  • Second and final 2(c)-ii rename-sweep PR (v4-design §9 item 4, the semantic wave): flips 12 ledger rows plannedshimmed — [M-030]/[M-031] (time=post= on the 2x2/2x2x2 post dummy), [M-043]/[M-095] (clean_controlcontrol_group, estimator + results field), [M-044]/[M-086]/[M-087] (the Wooldridge level/event_study/summary triple), [M-045]..[M-047]/[M-115] (the robust drop, all four sites), [M-084] (ContinuousDiD covariates moves to fit()) — and adds three missed-rename amendment rows [M-136]..[M-138] (LPDiD level="event" value; the two post-dummy diagnostics params), born shimmed with ledger + v4-design §3.4/§8/§9 edited in the same diff (EXPECTED_INITIAL_IDS/ROW_COUNT_FLOOR → 117).
  • All shims ride the PR-A _deprecation.py machinery: single FutureWarning with the uniform migration message, both-spellings ValueError, positional binding preserved, deprecated paths route to bit-identical numbers. M-031's warning notes time= becomes calendar-only at 4.0 ([M-085]).
  • BaseEstimator interplay per the approved plan: robust keeps the RESOLVED legacy bool on the public attr while get_params() returns the raw sentinel-era arg (silent clone round-trips; configured instances re-warn on probe re-init, documented); StackedDiD's lossless shim carries _DERIVED_CONFIG_ATTRS + a both-directions _normalize_set_params hook + a deprecated estimator-attr property (guard-allowlisted).
  • Consumer migrations (rule 11): _reporting_helpers/business_report read the renamed field with dual serialized keys through 3.9; power.py's survey gate is now estimator-scoped so a default StackedDiD stays accepted (bit-exact with the pre-rename gate); the four newly-shimmed diagnostics forwards migrated (the except Exception wrapper paths pinned zero-warning + non-error-dict); DiD/DDD power builders migrated while TWFE builders stay on time= ([M-082] is phase 3).
  • The run_placebo_test/run_all_placebo_tests wrappers keep their genuinely OVERLOADED time (calendar for timing/group tests, post dummy for the renamed callees) — a rename cannot express dual semantics; the signature redesign is a TODO.md row with honest guard-allowlist reasons.
  • WooldridgeDiDResults.summary adopts the library-wide §5 contract: alpha (keyword-only during 3.9) RAISES on a value different from the stored one — no label-only relabeling of stored intervals.

Methodology references (required if estimator / math changes)

  • Method name(s): N/A - API renames only; every shim resolves into the pre-existing body-local variable before estimation, and per-surface routing-parity tests pin old-path == new-path numbers. No estimand, weighting, comparison-group, variance, or inference change.
  • Paper / source link(s): naming rules per docs/v4-design.md §8 (rule 1 post vs calendar time, rule 6 control_group, §7's robust retirement, rule 10 public-function completeness, the missed-rename clause for [M-136]..[M-138]).
  • Any intentional deviations from the source (and why): None. Calendar time= surfaces (TWFE, CS, MPD, dCDH, SDID's own fit, CiC/QDiD) are deliberately untouched; CS-family cohort vocabulary unchanged.

Validation

  • Tests added/updated: new tests/test_v4_rename_semantic.py (47 pins incl. warning contracts, routing parity, field trio + pickle + dual keys, probe re-warn counts, wrapper zero-warning assertions, the power survey-gate regression, and the summary-alpha reject contract); ~600 test call sites migrated to canonical names (scope-aware AST rewriter + hand triage; deliberate alias-semantics tests keep exercising deprecated spellings under pytest.warns); tests/test_v4_matrix.py + tests/test_naming_guard.py green with all 15 rows and the amendment bookkeeping.
  • Backtest / simulation / notebook evidence (if applicable): the ten touched tutorials (01, 03, 04, 08, 09, 13, 16-survey, 16-wooldridge, 17, 27) execute end-to-end via nbmake; 16_wooldridge_etwfe's stored outputs re-executed in place after its display calls changed. Numbers unchanged (rename-only routing).

Security / privacy

  • Confirm no secrets/PII in this PR: Yes

…hims + missed-rename amendments (2(c)-ii PR-B, 15 rows)

Second and final 2(c)-ii rename-sweep PR (v4-design section 9 item 4).
Flips 12 ledger rows planned -> shimmed - M-030/M-031, M-043/M-095,
M-044/M-086/M-087, M-045..M-047/M-115, M-084 - and adds the three
missed-rename amendments M-136..M-138 (born shimmed; ledger + v4-design
section 3.4/8/9 edited in the same diff; EXPECTED_INITIAL_IDS and
ROW_COUNT_FLOOR raised to 117).

- time -> post (the 2x2 0/1 post dummy; rule 1): DifferenceInDifferences.fit
  [M-030] and TripleDifference.fit [M-031] (whose warning notes time=
  becomes calendar-only at 4.0 via M-085); the permutation_test /
  leave_one_out_test diagnostics follow [M-137] [M-138] with docstrings
  corrected from the wrong "Time period column". Calendar time= surfaces
  (TWFE per M-082, CS, MPD, dCDH, SDID's own fit, CiC, ...) are untouched.
  Internal migrations: the 7 AST-verified DiD.fit sites + the 4
  newly-shimmed wrapper forwards in diagnostics.py (the
  run_all_placebo_tests calls sit inside except-Exception blocks that
  would swallow warnings-as-errors - pinned by explicit zero-warning +
  non-error-dict tests), the DiD/DDD power fit-kwargs builders (TWFE
  builders stay), the triple_difference() wrapper forward, and the
  in-source emitters (practitioner/agent_workflow/datasets/prep_dgp
  snippets). The run_placebo_test/run_all_placebo_tests wrappers keep
  their genuinely OVERLOADED time (calendar for timing/group tests, post
  dummy for the two renamed callees) - a rename cannot express dual
  semantics; redesign tracked in TODO.md with honest guard allowlist
  reasons.
- robust dropped everywhere it exists [M-045..M-047] [M-115]
  (DiD + inherited TWFE/MPD, TripleDifference, HAD with its legacy False
  default, LinearRegression): warn-and-route to the existing
  resolve_vcov_type (now sentinel-aware with a legacy_default hook). The
  PUBLIC .robust attr keeps the RESOLVED legacy bool through 3.9 (existing
  attribute readers and default-construction pins keep passing) while
  get_params returns the raw sentinel-era arg via _PARAM_ATTR_ALIASES +
  _DERIVED_CONFIG_ATTRS, so clone round-trips stay silent; a
  robust=-configured instance re-warns on set_params probe re-init
  (documented). Internal forwards dropped (synthetic_did super().__init__,
  sun_abraham's LinearRegression call).
- StackedDiD clean_control -> control_group [M-043]: lossless
  sentinel+alias shim with _DERIVED_CONFIG_ATTRS ("control_group",) so
  set_params updates the fit-time config, a _normalize_set_params hook
  that lets either spelling migrate an instance in place, and a
  deprecated warning-property for external attribute readers. Results
  field clean_control -> control_group [M-095] (alias property,
  __setstate__ pickle migration, dual to_dict keys through 3.9, summary
  label "Control group:"). Consumers migrated per rule 11
  (_reporting_helpers, business_report incl. the dual block keys and
  narration prose, practitioner guidance); power.py's survey_config gate
  is now ESTIMATOR-SCOPED so a default StackedDiD stays accepted
  (bit-exact with the pre-rename gate, which rejected only strict).
- Wooldridge triple: aggregate type "event" -> "event_study" [M-086]
  (aggregation_weights carries both keys through 3.9 + a __setstate__
  mirror for old pickles); to_dataframe(aggregation=) ->
  to_dataframe(level=) [M-044] with a sentinel default resolving to
  "event_study"; summary(aggregation=) deprecated [M-087] - the
  transitional summary(aggregation=SENTINEL, *, alpha=None) shape adopts
  the library-wide section-5 contract (alpha != stored alpha RAISES; no
  label-only relabeling), with the uniform positional summary(alpha=None)
  arriving at 4.0. LPDiDResults.to_dataframe level "event" ->
  "event_study" [M-136] (default flips; identical frame).
- ContinuousDiD covariates moves from __init__ to fit() [M-084]
  (raw-keep ctor shim; both-supplied ValueError; the lowest_dose
  NotImplementedError guard replicated for fit-level values).

tests/test_v4_rename_semantic.py pins all 15 rows (warning messages,
canonical/positional silence, both-supplied rejection, bit-exact routing
parity, field trio + pickle + dual keys, probe re-warn counts, the
wrapper zero-warning contract, and the power survey-gate regression).
~600 test call sites migrated to canonical names via a scope-aware
AST rewriter plus hand triage (deliberate alias-semantics tests keep
exercising the deprecated spellings, now wrapped in pytest.warns where
they construct outside warning-capture blocks); guides/rst/notebooks
swept with the CI-pinned llms-full signature blocks keeping annotated
deprecated tails; the ten touched tutorials execute end-to-end and
16_wooldridge_etwfe's stored outputs were refreshed in place. CHANGELOG
names the full row inventory.
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown

Overall assessment

Looks good — no unmitigated P0 or P1 findings.

Executive summary

  • Estimator math, weighting, identification, and variance formulas remain unchanged.
  • Rename shims preserve positional calls, defaults, serialization, cloning, and old/new routing parity.
  • The overloaded placebo-wrapper parameter is explicitly tracked in TODO.md.
  • One nonblocking P2 documentation issue remains: several docstrings still present deprecated spellings as current.
  • Tests could not be executed because the review environment lacks pytest and numerical dependencies.

Methodology

No defects found.

Cross-checking against docs/methodology/REGISTRY.md confirmed preservation of:

  • 2×2 DiD and TripleDifference estimands and variance behavior.
  • Wing–Freedman–Hollingsworth StackedDiD clean-control definitions.
  • ContinuousDiD conditional-parallel-trends covariate path, including bootstrap propagation.
  • Wooldridge ETWFE cell/cohort-share weighting and inference.
  • The documented randomization-inference exception for permutation_test’s inline t-statistic.

Code Quality

No findings. The shared rename resolver and safe_inference() are used consistently; invalid dual spellings fail explicitly.

Performance

No findings. Changes add only constant-time argument resolution and compatibility bookkeeping.

Maintainability

No findings. Raw versus resolved constructor state and bidirectional set_params() handling are explicit and tested.

Tech Debt

  • Severity: P3 — informational, tracked
  • Impact: run_placebo_test and run_all_placebo_tests retain an overloaded time argument whose meaning varies by delegated diagnostic.
  • Concrete fix: Implement the signature split already recorded at TODO.md:L24. Per the deferred-work policy, this is not a blocker.

Security

No findings. No secrets, credentials, unsafe evaluation, or new external-input execution paths were identified.

Documentation/Tests

  • Severity: P2
  • Impact: Public docstrings still describe deprecated parameters and values as current, encouraging calls that now emit FutureWarning. Examples include ContinuousDiD(covariates=) at diff_diff/continuous_did.py:L91-L97, robust= at diff_diff/estimators.py:L67-L71, diff_diff/triple_diff.py:L410-L414, diff_diff/had.py:L2725-L2731, diff_diff/linalg.py:L4303-L4308, and diff_diff/twfe.py:L43-L44. The Wooldridge weighting documentation also still says type="event" at diff_diff/wooldridge_results.py:L264-L272.
  • Concrete fix: Mark robust= as deprecated with the vcov_type= replacement, describe ContinuousDiD covariates under fit(), and replace canonical Wooldridge examples with event_study.

The new compatibility tests cover warnings, dual-name rejection, positional stability, routing parity, pickle migration, and parameter round-trips by inspection.

@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown

🔁 AI review rerun (requested by @igerber)

Head SHA: 447e57e189a5f8344822331e407368b07d2b31f9


Overall assessment

Looks good — no unmitigated P0 or P1 findings.

Executive summary

  • Estimands, weighting, control groups, variance, and inference formulas are unchanged.
  • Rename shims preserve legacy routing, positional calls, cloning, and serialization.
  • The previous P2 docstring finding is resolved.
  • The overloaded placebo-wrapper parameter is tracked in TODO.md.
  • Static syntax checks passed; pytest is unavailable in the review environment.

Methodology

No findings.

Affected methods were checked against their Registry entries: DiD, TripleDifference, ContinuousDiD, StackedDiD, Wooldridge ETWFE, LPDiD result formatting, and placebo diagnostics (docs/methodology/REGISTRY.md:L47, L1199, L1946, L2091, L2857, L4442). The changes do not alter their mathematical or inferential contracts.

The inline permutation t-stat remains the documented randomization-inference exception at docs/methodology/REGISTRY.md:L4453-L4459.

Code Quality

No findings. Deprecated aliases consistently reject dual spellings and resolve to canonical body-local values.

Performance

No findings. The shims add only constant-time argument and compatibility handling.

Maintainability

No findings.

Keeping triple_difference(time=) unchanged is intentional: the wrapper is removed under M-075 (docs/v4-deprecations.yaml:L856-L867), and removal-bound wrappers are explicitly exempt from rename propagation (docs/v4-design.md:L573-L581).

Tech Debt

  • Severity: P3 — informational, tracked
  • Impact: run_placebo_test and run_all_placebo_tests retain an overloaded time parameter.
  • Concrete fix: Implement the signature split recorded at TODO.md:L24. No action is required for this PR.

Security

No findings. No secrets, unsafe evaluation, or new external-input execution paths were identified.

Documentation/Tests

No findings.

The previous documentation issue is resolved: deprecated robust=, constructor-level ContinuousDiD covariates=, and Wooldridge "event" now identify their canonical replacements.

AST syntax validation passed for all 60 changed Python/test files inspected. Runtime tests could not be executed because pytest is not installed.

@igerber igerber added the ready-for-ci Triggers CI test workflows label Aug 2, 2026
…trol_group (M-095)

The two failing legs' tests build minimal stub result objects and were
still setting the pre-rename clean_control attribute; the M-095 field
rename made describe_target_parameter read control_group (no fallback -
__setstate__ guarantees the field on real results), so the stubs fell
through to the default not-yet-treated clause. Stubs, parametrize name,
and docstring migrated to the canonical name.
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown

🔁 AI review rerun (requested by @igerber)

Head SHA: e4f0164f325ca6ed2d35bf9cd69209d79c83c129


Overall assessment

Looks good — no unmitigated P0 or P1 findings.

Executive summary

  • Rename shims do not alter estimands, weighting, controls, variance, or inference.
  • The latest commit correctly migrates StackedDiD test stubs to control_group.
  • The previous documentation finding remains resolved.
  • The overloaded placebo-wrapper parameter is tracked in TODO.md.
  • Static parsing passed; runtime tests were unavailable because NumPy and pytest are absent.

Methodology

No actionable findings.

Affected methods were cross-checked against the Registry: DifferenceInDifferences, ContinuousDiD, StackedDiD, Wooldridge ETWFE, LPDiD, TripleDifference, and placebo diagnostics (docs/methodology/REGISTRY.md:L47, L1199, L1946, L2091, L2277, L2857, L4429).

  • Severity: P3 — informational
  • Impact: The inline permutation t-stat at diff_diff/diagnostics.py:L716 is an intentional randomization-inference exception, documented at docs/methodology/REGISTRY.md:L4453-L4470.
  • Concrete fix: None required.

Code Quality

No findings. Canonical StackedDiD reporting now consistently reads control_group at diff_diff/_reporting_helpers.py:L199-L215.

Performance

No findings. Compatibility shims add only constant-time argument handling.

Maintainability

No findings. The re-review delta consistently replaces obsolete test-stub fields across all control-group branches.

Tech Debt

  • Severity: P3 — informational, tracked
  • Impact: Placebo wrappers retain an overloaded time parameter.
  • Concrete fix: Implement the signature split recorded at TODO.md:L24; no action is required for this PR.

Security

No findings. No new unsafe execution paths, secrets, or sensitive data were identified.

Documentation/Tests

No findings.

The follow-up commit correctly exercises control_group at tests/test_target_parameter.py:L94-L100 and all three supported branches at tests/test_target_parameter.py:L382-L395. All Python files under diff_diff/ and tests/ passed AST parsing.

@igerber
igerber merged commit a70d652 into main Aug 2, 2026
31 checks passed
@igerber
igerber deleted the feat/v4-rename-semantic branch August 2, 2026 17:58
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