Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/docs-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ jobs:
# docs/conf.py imports diff_diff via sys.path from checked-out source.
# ipython provides the 'ipython3' Pygments lexer that nbsphinx uses
# for notebook code cells; without it -W fires highlighting_failure.
run: pip install "numpy>=1.20.0" "pandas>=1.3.0" "scipy>=1.10" "sphinx>=6.0" "pydata-sphinx-theme>=0.16.1" "sphinxext-opengraph>=0.9" "sphinx-sitemap>=2.5" "nbsphinx>=0.9" "matplotlib>=3.5" "ipython>=8.0"
run: pip install "numpy>=1.20.0" "pandas>=1.3.0" "scipy>=1.10" "sphinx>=6.0" "pydata-sphinx-theme>=0.16.1" "sphinxext-opengraph>=0.9" "sphinx-sitemap>=2.5" "nbsphinx>=0.9" "myst-parser>=2.0" "matplotlib>=3.5" "ipython>=8.0"

- name: Build docs with warnings as errors
# SPHINXOPTS="-W" turns every Sphinx warning into a build failure.
Expand Down Expand Up @@ -145,7 +145,7 @@ jobs:
# not run a Sphinx build (sphinx-build covers full rendering on 3.11).
# Failure here means the docs floor declared in pyproject.toml /
# .readthedocs.yaml / above is not installable on Python 3.9.
run: pip install "numpy>=1.20.0" "pandas>=1.3.0" "scipy>=1.10" "sphinx>=6.0" "pydata-sphinx-theme>=0.16.1" "sphinxext-opengraph>=0.9" "sphinx-sitemap>=2.5" "nbsphinx>=0.9" "matplotlib>=3.5" "ipython>=8.0"
run: pip install "numpy>=1.20.0" "pandas>=1.3.0" "scipy>=1.10" "sphinx>=6.0" "pydata-sphinx-theme>=0.16.1" "sphinxext-opengraph>=0.9" "sphinx-sitemap>=2.5" "nbsphinx>=0.9" "myst-parser>=2.0" "matplotlib>=3.5" "ipython>=8.0"

- name: Confirm pydata-sphinx-theme version
# Surface the resolved version in the log for future debugging.
Expand Down
2 changes: 1 addition & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ build:
#
# Keep in sync with pyproject.toml [project.dependencies]
# and [project.optional-dependencies.docs].
- pip install "numpy>=1.20.0" "pandas>=1.3.0" "scipy>=1.10" "sphinx>=6.0" "pydata-sphinx-theme>=0.16.1" "sphinxext-opengraph>=0.9" "sphinx-sitemap>=2.5" "nbsphinx>=0.9" "matplotlib>=3.5" "ipython>=8.0"
- pip install "numpy>=1.20.0" "pandas>=1.3.0" "scipy>=1.10" "sphinx>=6.0" "pydata-sphinx-theme>=0.16.1" "sphinxext-opengraph>=0.9" "sphinx-sitemap>=2.5" "nbsphinx>=0.9" "myst-parser>=2.0" "matplotlib>=3.5" "ipython>=8.0"

# Build documentation in the "docs/" directory with Sphinx
sphinx:
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
assert between the two (defense in depth).

### Added
- **REGISTRY.md and REPORTING.md are now published on Read the Docs.** The two
methodology markdown pages render as in-site Sphinx pages (MyST) under a new
"Methodology" toctree section, so cross-references from the API docs use `:doc:` links
instead of off-site `blob/main` GitHub URLs — stable-docs readers previously landed on
a different revision than their installed version. `myst-parser` joins the docs
dependency set (pyproject `docs` extra, RTD post_install, docs-tests workflow — kept in
sync); every other repo-internal markdown under `docs/` (performance notes, paper
reviews, roadmaps) is explicitly excluded from the build. Two latent doc defects
surfaced by the `-W` build are fixed: a broken ToC anchor in REGISTRY.md (typo'd
`#differenceinifferences`, broken on GitHub too) and a heading-level jump; the
"Diagnostics & Sensitivity" heading is retitled to "Diagnostics and Sensitivity"
because GitHub and docutils slug `&` differently (double vs collapsed hyphen). Full
local `make -C docs html SPHINXOPTS="-W"` passes with 0 warnings.
- **`ImputationDiD` leave-one-out conservative variance** (`leave_one_out`, default `False`) — the
Borusyak-Jaravel-Spiess (2024) Supplementary Appendix A.9 finite-sample refinement. The non-LOO
auxiliary aggregate `tau_tilde_g` (eq. 8) is built from the fitted `tau_hat_it` and so partially
Expand Down
1 change: 0 additions & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ generic sparse-FE, QR+SVD rank-detection redundancy, `check_finite` bypass — m
| Issue | Location | Origin | Effort | Priority |
|-------|----------|--------|--------|----------|
| SE-audit CI-lock — remaining "fiddly bits" after the second coverage batch landed (that batch pinned C2 `dof_hc2_bm`/`dof_per_coef` via CI-inversion, C3 LOO `df`, C4 estimatr HC1/CR1 intercept SE, C5 Yatchew `p`/`sigma2_lin`/`sigma2_diff`, and the G2 fixest cluster-SE band). Still deferred, each needing a golden regeneration, new computation, or a documented-deviation call — **(a) G2 hetero/cluster is DONE (2026-07-07)**: the unbalanced/heteroskedastic-DGP regen landed, the DiD-path hetero AND cluster CR1 SEs are machine-precision-locked (the plain-OLS CR1 matches fixest exactly — the DOF-convention deviation is absorbed-FE-only), and the TWFE cluster band-pin is retained for the documented non-nested-FE ssc deviation (tracked under "Needs external reference"); TWFE has no public unclustered-hetero surface (auto-cluster convention). Remaining: **(b) PlaceboTests `boundary_gap`** — a permutation randomization-inference margin NOT computed anywhere in code (a new feature + result field, not a coverage lock); **(c) StackedDiD intercept SEs** (`se_cr1/cr2_intercept`, C1) — MEASURED to diverge ~0.3% from R: a nuisance-parameter reference-cell/parameterization gap, NOT machine-precision lockable (the event-study interaction SEs already match ~2e-13; surfacing it would add an unasserted, R-divergent public field); **(d) estimatr `classical` intercept SE** — same documented `O(1/n)` projection/DOF deviation as the slope (reference-only, excluded from parity). C6 CLOSED 2026-07-08 (dr remainder measured ~6e-11 ATT / ~2e-11 rel SE on the no-cov fixture and tightened to 1e-8 with the previously-missing SE assertion added; reg/ipw ATT bands 0.02/0.05 also tightened to 1e-8; the covariate-DR 2e-3 band stays as documented small-sample numerics). C7/C8 definitions were lost with the audit session scratchpad — re-derive from a fresh loose-tolerance inventory before acting. | `benchmarks/R/generate_fixest_did_twfe_golden.R`, `tests/test_fixest_did_twfe_parity.py`, `tests/test_methodology_stacked_did.py`, `tests/test_methodology_placebo.py` | SE-audit | Mid | Low |
| Render `docs/methodology/REPORTING.md` and `REGISTRY.md` as in-site Sphinx pages so cross-refs can use `:doc:` instead of off-site `blob/main` URLs (stable-docs readers can otherwise land on a different revision than their package version). Two paths: (a) add `myst-parser` to `conf.py` + docs extras and link with `:doc:`, or (b) convert both to `.rst`. **Note:** REGISTRY.md is ~4.5k lines of LaTeX-heavy markdown — high risk under the `-W` (warnings-as-errors) Sphinx build; budget multiple rounds. | `docs/conf.py`, `docs/api/business_report.rst`, `docs/api/diagnostic_report.rst`, tutorials 18 & 19 | follow-up | Mid | Low |
| Add true half-sample BRR replicate-weight regressions per estimator family (current tests use Fay-like 0.5/1.5 perturbations; `test_survey_phase6.py` covers true BRR at the helper level). | `tests/test_replicate_weight_expansion.py` | #253 | Mid | Low |
| Port the CI `<notebook-prose>` extraction into the reviewer-eval harness so `docs/tutorials/*.ipynb` cases (currently guarded out of `verify-corpus`/`run`) can be reviewed with CI-equivalent context. | `tools/reviewer-eval/adapters/ci_prompt.py` | local-review | Mid | Low |

Expand Down
21 changes: 21 additions & 0 deletions docs/api/_autosummary/diff_diff.LPDiD.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
diff\_diff.LPDiD
================

.. currentmodule:: diff_diff

.. autoclass:: LPDiD
:no-members:


.. rubric:: Methods

.. autosummary::

~LPDiD.__init__
~LPDiD.fit
~LPDiD.get_params
~LPDiD.set_params




58 changes: 58 additions & 0 deletions docs/api/_autosummary/diff_diff.lpdid_results.LPDiDResults.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
diff\_diff.lpdid\_results.LPDiDResults
======================================

.. currentmodule:: diff_diff.lpdid_results

.. autoclass:: LPDiDResults
:no-members:


.. rubric:: Methods

.. autosummary::

~LPDiDResults.__init__
~LPDiDResults.print_summary
~LPDiDResults.summary
~LPDiDResults.to_dataframe
~LPDiDResults.to_dict




.. rubric:: Attributes

.. autosummary::

~LPDiDResults.absorb
~LPDiDResults.alpha
~LPDiDResults.att
~LPDiDResults.cluster_name
~LPDiDResults.conf_int
~LPDiDResults.covariates
~LPDiDResults.dylags
~LPDiDResults.estimand
~LPDiDResults.n_clusters
~LPDiDResults.n_psu
~LPDiDResults.n_strata
~LPDiDResults.non_absorbing
~LPDiDResults.p_value
~LPDiDResults.rank_deficient_action
~LPDiDResults.se
~LPDiDResults.stabilization_window
~LPDiDResults.survey_metadata
~LPDiDResults.t_stat
~LPDiDResults.vcov_type
~LPDiDResults.ylags
~LPDiDResults.event_study
~LPDiDResults.pooled
~LPDiDResults.n_obs
~LPDiDResults.n_treated_units
~LPDiDResults.n_control_units
~LPDiDResults.pre_window
~LPDiDResults.post_window
~LPDiDResults.control_group
~LPDiDResults.reweight
~LPDiDResults.no_composition
~LPDiDResults.pmd

6 changes: 2 additions & 4 deletions docs/api/business_report.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ pretest to opt in.

Methodology deviations (no traffic-light gates, pre-trends verdict
thresholds, power-aware phrasing, unit-translation policy, schema
stability) are documented in `docs/methodology/REPORTING.md
<https://github.com/igerber/diff-diff/blob/main/docs/methodology/REPORTING.md>`_.
stability) are documented in :doc:`/methodology/REPORTING`.

The schema carries a top-level ``target_parameter`` block
(experimental) naming what the headline scalar represents per
Expand All @@ -63,8 +62,7 @@ distinguishes the populated-surface subcase (per-horizon table
available on ``linear_trends_effects``) from the empty-surface
subcase (no horizons survived estimation; re-fit with a larger
``L_max`` or with ``trends_linear=False``). See the "Target
parameter" section of `docs/methodology/REPORTING.md
<https://github.com/igerber/diff-diff/blob/main/docs/methodology/REPORTING.md>`_
parameter" section of :doc:`/methodology/REPORTING`
for the full per-estimator dispatch table and schema shape.

Example
Expand Down
6 changes: 2 additions & 4 deletions docs/api/diagnostic_report.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,12 @@ result.

Methodology deviations (no traffic-light gates, opt-in placebo
battery, estimator-native diagnostic routing, power-aware phrasing
threshold) are documented in `docs/methodology/REPORTING.md
<https://github.com/igerber/diff-diff/blob/main/docs/methodology/REPORTING.md>`_.
threshold) are documented in :doc:`/methodology/REPORTING`.

The schema carries a top-level ``target_parameter`` block
(experimental) naming what the headline scalar represents per
estimator. See the "Target parameter" section of
`docs/methodology/REPORTING.md
<https://github.com/igerber/diff-diff/blob/main/docs/methodology/REPORTING.md>`_
:doc:`/methodology/REPORTING`
for the per-estimator dispatch and schema shape.

Data-dependent checks (2x2 parallel trends on simple DiD,
Expand Down
30 changes: 29 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,38 @@
"sphinxext.opengraph",
"sphinx_sitemap",
"nbsphinx",
"myst_parser",
]

# MyST renders the two in-site methodology markdown pages (REGISTRY.md,
# REPORTING.md) so cross-refs use :doc: instead of off-site blob/main URLs
# (stable-docs readers otherwise land on a different revision than their
# package version). dollarmath/amsmath cover the registry's LaTeX;
# heading anchors to depth 4 make its GitHub-style #section links resolve.
myst_enable_extensions = ["dollarmath", "amsmath"]
myst_heading_anchors = 4


templates_path = ["_templates"]
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
# Only the two methodology pages are published; every other repo-internal
# markdown under docs/ stays out of the build (performance/benchmark notes
# are deliberately NOT on RTD — see the repo convention — and un-toctree'd
# .md files would fail the -W build as orphans).
exclude_patterns = [
"_build",
"Thumbs.db",
".DS_Store",
"business-strategy.md",
"performance-plan.md",
"performance-scenarios.md",
"practitioner-guide-evaluation.md",
"survey-roadmap.md",
"methodology/continuous-did.md",
"methodology/survey-theory.md",
# Internal paper-review notes (methodology validation artifacts).
"methodology/papers/*",
"tutorials/README.md",
]

# -- Options for autodoc -----------------------------------------------------
autodoc_default_options = {
Expand Down
8 changes: 8 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,14 @@ Quick Links

api/index

.. toctree::
:maxdepth: 1
:caption: Methodology
:hidden:

methodology/REGISTRY
methodology/REPORTING

What is Difference-in-Differences?
----------------------------------

Expand Down
8 changes: 4 additions & 4 deletions docs/methodology/REGISTRY.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This document provides the academic foundations and key implementation requireme
## Table of Contents

1. [Core DiD Estimators](#core-did-estimators)
- [DifferenceInDifferences](#differenceinifferences)
- [DifferenceInDifferences](#differenceindifferences)
- [MultiPeriodDiD](#multiperioddid)
- [TwoWayFixedEffects](#twowayfixedeffects)
2. [Modern Staggered Estimators](#modern-staggered-estimators)
Expand All @@ -28,7 +28,7 @@ This document provides the academic foundations and key implementation requireme
- [TROP](#trop)
- [HeterogeneousAdoptionDiD](#heterogeneousadoptiondid)
- [SpilloverDiD](#spilloverdid)
4. [Diagnostics & Sensitivity](#diagnostics--sensitivity)
4. [Diagnostics and Sensitivity](#diagnostics-and-sensitivity)
- [PlaceboTests](#placebotests)
- [BaconDecomposition](#bacondecomposition)
- [HonestDiD](#honestdid)
Expand Down Expand Up @@ -3449,7 +3449,7 @@ Shipped in `diff_diff/had_pretests.py` as `stute_joint_pretest()` (residuals-in

---

# Diagnostics & Sensitivity
# Diagnostics and Sensitivity

## PlaceboTests

Expand Down Expand Up @@ -4960,7 +4960,7 @@ The 8-step workflow in `diff_diff/guides/llms-practitioner.txt` is adapted from
covariates). Paper's Step 8 is "Keep learning." The mandatory with/without covariate
comparison is a diff-diff convention.

### Survey DGP (`generate_survey_did_data`)
## Survey DGP (`generate_survey_did_data`)

- **Note:** The `icc` parameter calibrates `psu_re_sd` using the full variance
decomposition `Var(Y) = sigma²_psu * (1 + psu_period_factor²) + sigma²_unit +
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ docs = [
"sphinxext-opengraph>=0.9",
"sphinx-sitemap>=2.5",
"nbsphinx>=0.9",
"myst-parser>=2.0",
"matplotlib>=3.5",
# ipython provides the 'ipython3' Pygments lexer used by nbsphinx for
# notebook code cells; without it Sphinx emits highlighting_failure
Expand Down