Skip to content

Commit a2a28a7

Browse files
igerberclaude
andcommitted
docs(v4): complete Wooldridge aggregation-surface coverage in the ledger
Review feedback: [M-044] covered only the to_dataframe(aggregation->level) rename while the spec claimed the 'event' spelling dies library-wide - but WooldridgeDiDResults ALSO exposes an existing post-fit aggregate(type=) (emfx-style prior art for the spec section 6 pattern) and summary(aggregation=). New rows: [M-086] unifies the 'event' value spelling on aggregate(type=) ('gt' stays as a documented estimator extra), [M-087] retires summary(aggregation=) for the uniform summary(alpha=None) contract. 71-row ledger; snapshot/floor and spec sections 3.4/6/11 updated in the same diff. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017eVKbBqzenDKa5idwtexQa
1 parent 8507736 commit a2a28a7

3 files changed

Lines changed: 42 additions & 10 deletions

File tree

docs/v4-deprecations.yaml

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ rows:
512512
phase: 2
513513
warning: FutureWarning
514514
code_refs: [diff_diff/wooldridge_results.py]
515-
notes: "Every other to_dataframe selector is level=; value vocabulary unifies too ('event' -> 'event_study')."
515+
notes: "Every other to_dataframe selector is level=. Covers ONLY the to_dataframe param rename; the 'event' value vocabulary across Wooldridge's aggregation surfaces is [M-086], and the summary(aggregation=) surface is [M-087]."
516516
- id: M-045
517517
kind: param
518518
group: renames-robust-drop
@@ -842,6 +842,33 @@ rows:
842842
code_refs: [diff_diff/chaisemartin_dhaultfoeuille.py, diff_diff/__init__.py]
843843
notes: "Use ChaisemartinDHaultfoeuille."
844844

845+
- id: M-086
846+
kind: param-value
847+
group: renames-level
848+
old: "diff_diff:WooldridgeDiDResults.aggregate[type]=event"
849+
new: "diff_diff:WooldridgeDiDResults.aggregate[type]=event_study"
850+
introduced_in: "3.9"
851+
deprecated_in: "3.9"
852+
removed_in: "4.0"
853+
status: planned
854+
phase: 2
855+
warning: FutureWarning
856+
code_refs: [diff_diff/wooldridge_results.py]
857+
notes: "Wooldridge's EXISTING post-fit aggregate() (emfx-style prior art for spec section 6) accepts the drifted 'event' spelling; unifies to 'event_study' across aggregate/summary/to_dataframe value vocabularies. 'gt' stays as a documented estimator extra (group-time table), like ContinuousDiD's 'dose'."
858+
- id: M-087
859+
kind: param
860+
group: renames-level
861+
old: "diff_diff:WooldridgeDiDResults.summary[aggregation]"
862+
new: null
863+
introduced_in: "3.9"
864+
deprecated_in: "3.9"
865+
removed_in: "4.0"
866+
status: planned
867+
phase: 2
868+
warning: FutureWarning
869+
code_refs: [diff_diff/wooldridge_results.py]
870+
notes: "summary() unifies to the library-wide summary(alpha=None) signature (spec section 5); aggregation selection lives on aggregate(). The alpha param arrives additively in the same PR."
871+
845872
# ---- Behavior policies (schema-tracked, spec-governed; no reality probe) -
846873
- id: M-080
847874
kind: behavior

docs/v4-design.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,9 @@ signatures. Lifecycle facts live in the cited rows.
141141
[M-040]..[M-042].
142142
- `StackedDiD(control_group=...)` - `clean_control` renamed [M-043].
143143
- `WooldridgeDiDResults.to_dataframe(level=...)` - `aggregation` -> `level`
144-
[M-044].
144+
[M-044]; the `"event"` value spelling unifies across its existing
145+
`aggregate(type=)` surface [M-086] and `summary(aggregation=)` is retired
146+
for the uniform `summary(alpha=None)` [M-087].
145147
- `robust` constructor param dropped everywhere it exists
146148
[M-045]..[M-047] - fully redundant with `vcov_type`, and its default even
147149
differed across estimators (True/True/False).
@@ -310,9 +312,12 @@ strongest norm (`did::aggte`, `etwfe::emfx`, Stata `estat aggregation`).
310312
**Vocabulary.** Closed set: `"simple"`, `"event_study"`, `"group"`,
311313
`"calendar"`, plus per-estimator documented extras where the estimand demands
312314
them (ContinuousDiD adds `"dose"` [M-025]; HAD's `"overall"` maps to
313-
`"simple"` [M-027]). The drifted spellings die with their fit-params:
314-
`"eventstudy"` (ContinuousDiD), `"event"` (Wooldridge, via [M-044]'s value
315-
vocabulary).
315+
`"simple"` [M-027]; Wooldridge's `"gt"` group-time table stays as a
316+
documented extra). The drifted spellings die across ALL their surfaces:
317+
`"eventstudy"` (ContinuousDiD [M-025]); Wooldridge's `"event"` on its
318+
EXISTING post-fit `aggregate(type=)` - the emfx-style prior art for this
319+
section's pattern - plus `summary(aggregation=)` and
320+
`to_dataframe(aggregation=)` [M-044] [M-086] [M-087].
316321

317322
**Semantics.** `aggregate()` re-aggregates WITHOUT refitting, from influence
318323
functions / bootstrap draws retained on the results object (CallawaySantAnna
@@ -514,7 +519,7 @@ forever - a removed symbol resurrecting is a test failure.
514519
the same object as its target, so the deprecation warning rides the parent
515520
class row (schema-enforced). Top-level `diff_diff:Name` class/function rows
516521
and alias rows also assert `__all__` membership consistent with their
517-
status (stale `import *` entries fail). The initial 69 row ids are a
522+
status (stale `import *` entries fail). The initial 71 row ids are a
518523
committed snapshot in the enforcement test: ids are never deleted or
519524
reused, and the test fails if any snapshot id disappears.
520525

tests/test_v4_matrix.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,14 @@
105105
_FIELD_RE = re.compile(r"^ ([a-z_]+):\s*(.*?)\s*$")
106106
_MD_TOKEN_RE = re.compile(r"\[(M-\d{3})\]")
107107

108-
# Row-count floor: exactly the 69 rows shipped at Phase 1. Ids are never reused and terminal
108+
# Row-count floor: exactly the 71 rows shipped at Phase 1. Ids are never reused and terminal
109109
# rows are never deleted, so the ledger only grows - raise the floor when rows are added; a
110110
# lower parse count means scanner/format drift or an illegal row deletion.
111-
ROW_COUNT_FLOOR = 69
111+
ROW_COUNT_FLOOR = 71
112112

113113
# Committed snapshot of the Phase 1 id set ("ids are never deleted or reused" contract - a
114114
# delete-one-add-one edit keeps the count above the floor but trips this). Extend, never edit.
115-
_INITIAL_ID_RANGES = [(1, 8), (10, 16), (20, 27), (30, 47), (50, 58), (60, 64), (70, 77), (80, 85)]
115+
_INITIAL_ID_RANGES = [(1, 8), (10, 16), (20, 27), (30, 47), (50, 58), (60, 64), (70, 77), (80, 87)]
116116
EXPECTED_INITIAL_IDS = frozenset(
117117
f"M-{n:03d}" for lo, hi in _INITIAL_ID_RANGES for n in range(lo, hi + 1)
118118
)
@@ -501,7 +501,7 @@ def test_initial_ids_never_deleted():
501501
ROW_COUNT_FLOOR alone would let a delete-one-add-one edit pass; this snapshot cannot."""
502502
missing = sorted(EXPECTED_INITIAL_IDS - set(_ROW_IDS))
503503
assert not missing, f"ledger rows deleted (ids are permanent): {missing}"
504-
assert len(EXPECTED_INITIAL_IDS) == 69
504+
assert len(EXPECTED_INITIAL_IDS) == 71
505505

506506

507507
def test_version_tuple_pads_to_three_components():

0 commit comments

Comments
 (0)