Skip to content
Merged
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
22 changes: 22 additions & 0 deletions .claude/commands/docs-check.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,28 @@ For each major feature, verify a tutorial covers it:

Check each tutorial file exists and is non-empty.

### 5b. Docs IA Registration Check (post-#703 information architecture)

The site navigation contract is CI-enforced by `tests/test_docs_ia.py` (docs-tests
workflow). Run it directly for immediate feedback:

```bash
PYTHONPATH=. DIFF_DIFF_BACKEND=python pytest tests/test_docs_ia.py -q
```

What it pins (fix at the source listed, never by widening the test):
1. `docs/index.rst` has ONE toctree = the 5 section landing pages. New top-level
pages join a section landing page (`getting_started` / `practitioners` /
`tutorials/index` / `user_guide` / `api/index`), never the root.
2. Every `docs/tutorials/*.ipynb` is registered in `docs/tutorials/index.rst`
twice: a short-labeled toctree entry (`Label <stem>`, <= 40 chars) in its
group AND a `grid-item-card` with `:link: <stem>`.
3. Homepage "Supported Estimators" table rows match the `api/index.rst`
Estimators autosummary 1:1 - new estimators need BOTH.
4. Any `autoclass` documented with `:no-index:` on a module page needs a
canonical autosummary entry in `api/index.rst`, else `:class:` xrefs to it
render as dead text.

### 6. Cross-Reference Check

For estimators added to the codebase, verify they have:
Expand Down
10 changes: 10 additions & 0 deletions .github/workflows/docs-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
- 'diff_diff/**'
- 'tests/test_doc_snippets.py'
- 'tests/test_doc_deps_integrity.py'
- 'tests/test_docs_ia.py'
- 'tests/test_v4_matrix.py'
# tests/conftest.py is auto-loaded by pytest for the snippet
# test run and mutates sys.path + MPLBACKEND (conftest.py:14, 18);
Expand All @@ -27,6 +28,7 @@ on:
- 'diff_diff/**'
- 'tests/test_doc_snippets.py'
- 'tests/test_doc_deps_integrity.py'
- 'tests/test_docs_ia.py'
- 'tests/test_v4_matrix.py'
- 'tests/conftest.py'
- 'pyproject.toml'
Expand Down Expand Up @@ -81,6 +83,14 @@ jobs:
# step does not install diff_diff.
run: PYTHONPATH=. DIFF_DIFF_BACKEND=python pytest tests/test_doc_deps_integrity.py -v

- name: Run docs IA structural guards
# Pins the #703 information architecture: single 5-section root
# toctree, tutorial dual-registration (short-label toctree entry +
# landing-page card), homepage estimator-table parity with the API
# catalog, and no :no-index:-only classes (dead cross-references).
# All four are valid-Sphinx states the -W build cannot catch.
run: PYTHONPATH=. DIFF_DIFF_BACKEND=python pytest tests/test_docs_ia.py -v

- name: Run v4 deprecation-matrix enforcement
# Asserts every docs/v4-deprecations.yaml row's status against reality
# at HEAD (schema: docs/v4-design.md section 11). Runs here so
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
purpose-phrasing, restoring the case as a genuinely clean negative control.

### Added
- **Internal: CI-enforced docs IA guards (`tests/test_docs_ia.py`).** Four structural
invariants protecting the #703 information architecture, all valid-Sphinx states the
`-W` build cannot catch: the root toctree stays exactly the 5 section landing pages
(a 6th entry regrows the navbar "More" dropdown); every tutorial notebook is
registered in `docs/tutorials/index.rst` with BOTH a short-labeled toctree entry
(<= 40 chars) and a landing-page card; the homepage "Supported Estimators" table
stays 1:1 with the `api/index.rst` Estimators autosummary; and no class is
documented only under `:no-index:` (which renders `:class:` cross-references as
dead text - the pre-#703 RDD failure mode). Runs in the docs-tests `doc-snippets`
job; conventions documented in CLAUDE.md, CONTRIBUTING.md, and `/docs-check` 5b.
- **Internal: 4.0 diagnostic-family amendment to the design spec.** `docs/v4-design.md`
gains section 3.5 formalizing a third object kind - diagnostics: the library's
existing "Diagnostics & Sensitivity" family (parallel-trends testing, placebo
Expand Down
6 changes: 5 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,11 @@ When adding new functionality, the source of truth is:
- **`docs/tutorials/*.ipynb`** for hands-on examples. New notebooks are registered in
`docs/tutorials/index.rst` (toctree entry with a short display label + a card in the
matching group), NOT in `docs/index.rst` - the root toctree lists only the 5 section
landing pages so the navbar stays at 5 links.
landing pages so the navbar stays at 5 links. These IA invariants (plus homepage
estimator-table parity with the API catalog, and the rule that any class documented
with `:no-index:` on a module page keeps a canonical autosummary entry in
`docs/api/index.rst`) are CI-enforced by `tests/test_docs_ia.py`; the full list is in
CONTRIBUTING.md "Docs IA invariants".
- **`CHANGELOG.md`** for release notes.
- **`README.md`** for ONE LINE in the `## Estimators` flat catalog (or `## Diagnostics & Sensitivity` for diagnostic-class features). Do NOT add usage examples, parameter tables, per-estimator sections, or full bibliographies.

Expand Down
18 changes: 18 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,24 @@ If you find yourself adding a usage example, a parameter table, or a multi-parag

9. **`docs/doc-deps.yaml`** - Add source-to-doc mappings for the new module.

### Docs IA invariants (CI-enforced by `tests/test_docs_ia.py`)

The documentation site's information architecture is machine-enforced; a red
`docs-tests` check means one of these was violated:

1. The root `docs/index.rst` toctree lists ONLY the 5 section landing pages
(Getting Started / Practitioner Guide / Tutorials / User Guide / API
Reference). New top-level pages join a section landing page, never the root -
every root entry becomes a navbar item and past 5 the theme regrows an
unusable "More" dropdown.
2. Every tutorial notebook has BOTH a short-labeled toctree entry (<= 40 chars)
and a `grid-item-card`, in the SAME group of `docs/tutorials/index.rst`.
3. The homepage "Supported Estimators" table stays 1:1 with the
`docs/api/index.rst` Estimators autosummary - new estimators need both.
4. A class documented with `:no-index:` on a module page must keep a canonical
autosummary entry in `docs/api/index.rst`, else `:class:` cross-references
to it render as dead text.

### For Bug Fixes or Minor Enhancements

- Update relevant docstrings
Expand Down
Loading
Loading