Skip to content

SEO rework: meta description, comparison table, keyword-rich title#932

Open
daimon-pymclabs wants to merge 21 commits into
mainfrom
claude/seo-landing-page-rework
Open

SEO rework: meta description, comparison table, keyword-rich title#932
daimon-pymclabs wants to merge 21 commits into
mainfrom
claude/seo-landing-page-rework

Conversation

@daimon-pymclabs

Copy link
Copy Markdown

Summary

SEO improvements to the CausalPy docs landing page based on an audit comparing it against pymc-marketing and competitor packages:

  • Meta description + keywords — the page had none, so Google was auto-generating snippets. Added via MyST frontmatter so Sphinx renders proper <meta> tags
  • Keyword-rich H1/title — changed from "Causal Inference for Quasi-Experiments" to "CausalPy — Open-Source Bayesian Causal Inference for Python", adding the three highest-signal non-branded terms people search for ("Python", "Bayesian", "open source"). Set html_title in conf.py to match
  • Comparison table — structured CausalPy vs DoWhy vs CausalML vs pyfixest comparison covering focus, Bayesian support, methods, and best-for guidance. This captures "causalpy vs X" search queries and establishes topical authority. Docs-only (not in the GitHub README) via a <!-- docs-end --> marker that splits the README include

Test plan

  • Verify docs build succeeds on Read the Docs preview
  • Check that <meta name="description"> and <meta name="keywords"> appear in the rendered HTML <head>
  • Confirm the comparison table renders correctly in the docs theme
  • Confirm the README still renders properly on GitHub (the <!-- docs-end --> comment is invisible in Markdown)

🤖 Generated with Claude Code

- Add HTML meta description and keywords to docs landing page via MyST frontmatter
- Update H1 title to include "CausalPy", "Open-Source", "Bayesian", and "Python"
  for better ranking on non-branded search queries
- Set html_title in Sphinx conf.py for consistent browser tab / SERP title
- Add structured comparison table (CausalPy vs DoWhy vs CausalML vs pyfixest)
  to the docs landing page to capture "vs" and comparison search queries
- Split README include with docs-end marker so comparison section is docs-only

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@cursor

cursor Bot commented May 28, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
Documentation and marketing copy only; no runtime, API, or build-logic changes beyond Sphinx/MyST metadata and README include boundaries.

Overview
Docs and README SEO refresh for the landing page: keyword-oriented H1/title (CausalPy — Open-Source Bayesian Causal Inference for Python), aligned html_title in Sphinx, and a tightened tagline on GitHub.

The docs home page now sets MyST html_meta description and keywords so search engines get explicit snippets instead of auto-generated text.

README include split via <!-- docs-end -->: the docs index pulls the main README body, injects a docs-only “How CausalPy compares” table (DoWhy, CausalML, pyfixest) plus “when to choose” guidance, then resumes README from Citing CausalPy onward—keeping the comparison off the GitHub README.

Reviewed by Cursor Bugbot for commit fed7fb8. Bugbot is set up for automated code reviews on this repo. Configure here.

@codecov

codecov Bot commented May 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.28105% with 70 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.16%. Comparing base (c107d4e) to head (71ef5e9).
⚠️ Report is 52 commits behind head on main.

Files with missing lines Patch % Lines
causalpy/experiments/staggered_did.py 86.48% 11 Missing and 14 partials ⚠️
causalpy/pymc_models.py 71.42% 9 Missing and 1 partial ⚠️
causalpy/tests/test_timeseries_model_coverage.py 80.00% 9 Missing ⚠️
causalpy/checks/outcome_falsification.py 92.47% 3 Missing and 4 partials ⚠️
causalpy/experiments/base.py 80.76% 2 Missing and 3 partials ⚠️
causalpy/checks/placebo_in_time.py 95.34% 2 Missing and 2 partials ⚠️
causalpy/experiments/interrupted_time_series.py 55.55% 1 Missing and 3 partials ⚠️
causalpy/reporting.py 50.00% 0 Missing and 2 partials ⚠️
causalpy/tests/test_check_public_exports.py 94.44% 1 Missing and 1 partial ⚠️
causalpy/experiments/regression_kink.py 50.00% 1 Missing ⚠️
... and 1 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #932      +/-   ##
==========================================
+ Coverage   95.07%   95.16%   +0.09%     
==========================================
  Files          87       93       +6     
  Lines       13701    15030    +1329     
  Branches      812      896      +84     
==========================================
+ Hits        13026    14304    +1278     
- Misses        479      507      +28     
- Partials      196      219      +23     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

drbenvincent and others added 18 commits June 4, 2026 22:08
* Add StaggeredDiD group-time effect plots

Expose cohort-time ATT trajectories as a first-class plotting and summary surface so users can inspect heterogeneity hidden by event-time aggregation.

Closes #937

Co-authored-by: Cursor <cursoragent@cursor.com>

* Facet StaggeredDiD cohort trajectories

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add placebo diagnostics to cohort plots

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Use the shared scalar coercion helper for experiment score titles so pandas-like singleton scores satisfy type checking.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Benjamin T. Vincent <inferencelab@gmail.com>
* Slim ARCHITECTURE.md and reference it from CONTRIBUTING.md

Reduce ARCHITECTURE.md to a lean orientation doc and add CONTRIBUTING.md pointers so structural PRs keep it current.

Fixes #843

Co-authored-by: Cursor <cursoragent@cursor.com>

* Clarify that agents should not load CONTRIBUTING.md by default

Point agents at AGENTS.md and ARCHITECTURE.md only; keep CONTRIBUTING.md for human contributor workflow.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Separate AGENTS.md workflow from ARCHITECTURE.md design docs

Move code-structure conventions into ARCHITECTURE.md and keep AGENTS.md focused on environment, testing, and tooling workflow.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
* ci(docs-preview): cancel when not in defined scopes of git diff

* fix(docs): make RTD skip logic POSIX-sh compatible

* fix(docs): make RTD skip hook fully POSIX-safe
* Add structural check scripts for exports and ARCHITECTURE inventory

Introduce AST-based checkers that catch export wiring drift and stale
experiment inventory tables without importing causalpy, wire them into
prek/Makefile, and fix the missing SyntheticDifferenceInDifferences
export in experiments/__init__.py.

Closes #947

Co-authored-by: Cursor <cursoragent@cursor.com>

* Check structural notes in architecture inventory

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Bumps the actions group with 3 updates in the / directory: [j178/prek-action](https://github.com/j178/prek-action), [codecov/codecov-action](https://github.com/codecov/codecov-action) and [github/codeql-action](https://github.com/github/codeql-action).


Updates `j178/prek-action` from 2.0.3 to 2.0.4
- [Release notes](https://github.com/j178/prek-action/releases)
- [Commits](j178/prek-action@6ad8027...bdca6f1)

Updates `codecov/codecov-action` from 6.0.0 to 6.0.1
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](codecov/codecov-action@57e3a13...e79a696)

Updates `github/codeql-action` from 4.35.3 to 4.36.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@e46ed2c...7211b7c)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-version: 6.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: github/codeql-action
  dependency-version: 4.35.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: j178/prek-action
  dependency-version: 2.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Warn when staggered DiD ATTs lack untreated-period support

Detect calendar periods with no untreated observations, emit a clear
UserWarning, and mark non-identified ATT(g, t) and ATT(e) cells with
identified=False and NaN estimates instead of silently returning biased
values when never-treated units are absent.

Closes #938

Co-authored-by: Cursor <cursoragent@cursor.com>

* Mask non-identified cells in get_plot_data_bayesian recompute path

When hdi_prob differs from the stored aggregation value, pass the
recomputed event-time DataFrame through _mark_non_identified_att_rows()
so non-identified ATTs stay NaN. Add regression test for the non-default
HDI path on a no-never-treated panel.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add tests for non-identified ATT coverage gaps

Cover effect_summary filtering and _mark_non_identified_att_rows edge
cases so Codecov patch coverage passes on the identification changes.

Related: #950 (local patch coverage in prek)
Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
* Refresh agent skills layout

Move developer skills to .agents as the canonical shared home, retain compatibility symlinks, and add the salvaged user-facing causal investigation and dataset skills from the superseded AI config PR.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Remove committed skill compatibility symlinks

Keep .agents/skills as the only tracked developer skill location and document local symlinks as an uncommitted fallback for tools that need them.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Remove obsolete Cursor command stubs

Drop thin .cursor/commands aliases that only point to skills, including stale entries that referenced non-existent skills, now that .agents/skills is the canonical developer workflow surface.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
* Add local patch coverage gate

Provide an opt-in make target and contributor guidance so patch coverage regressions can be caught locally before Codecov reports them on PRs.

Closes #950

Co-authored-by: Cursor <cursoragent@cursor.com>

* Prefer upstream base for patch coverage.

Use the upstream tracking branch when available so fork-based contributor workflows compare local patch coverage against the PR base rather than a potentially stale fork main.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
* Redesign CausalPy method selection skill

Make method routing more reliable for agents by replacing flat fast routing with ordered intake, text-based routing, explicit no-fit outcomes, and focused disambiguation references.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Broaden CausalPy method skill trigger

Make the method-selection skill easier to discover for plain-language impact questions that imply quasi-experimental causal inference.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Add CITS method selection guidance

Route comparative interrupted time-series questions to InterruptedTimeSeries with comparison series as predictors, and clarify when to prefer synthetic control.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Tone down method skill opening prose

Keep CITS covered in routing without elevating it in the main skill introduction.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Polish method-selection skill for review on current main

Rebase onto main and tighten the skill for review: trim YAML description into a triggers reference, document staggered DiD untreated-period identification support, cross-link causal-detective after a matched route, and update the skills README blurb.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Centralise fit_intercept=False handling in BaseExperiment.__init__: clone the user's sklearn estimator (with deepcopy fallback), warn when overriding fit_intercept=True, and remove duplicated in-place mutation from DifferenceInDifferences, StaggeredDifferenceInDifferences, PanelRegression, and PiecewiseITS.

Closes #664
…ort (#826)

* Fix interrogate coverage by excluding .marimo and .scratch directories

These directories contain exploratory/demo scripts that are not part
of the main package and should not count toward docstring coverage.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add _clone methods to BayesianBasisExpansionTimeSeries and StateSpaceTimeSeries

Sensitivity checks like PlaceboInTime and OutcomeFalsification need
to create fresh, unfitted copies of models. These _clone methods
preserve all configuration (components, sample_kwargs, mode) while
resetting fitted state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add random fold selection mode and fix assurance formula in PlaceboInTime

Adds a "random" selection_method that randomly samples eligible placebo
windows from the pre-intervention period, with constraints on minimum
training fraction, minimum gap between folds, and optional period
exclusion. Also fixes the assurance simulation to correctly model the
alternative hypothesis as null baseline noise + expected treatment
effect (theta_new + expected_effect), matching the paper's formulation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add OutcomeFalsification sensitivity check

Introduces outcome falsification, which re-fits the experiment with
alternative outcome formulas and reports their estimated effect sizes
with HDI intervals. This is an informational check (no pass/fail)
that lets researchers assess whether the pattern of effects across
outcomes is consistent with their causal story. Inspired by the
"causal detective" approach in Gallea (2026).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add sensitivity checks article notebook

Adds a developer notebook documenting the placebo-in-time and
outcome falsification sensitivity check methodology with worked
examples.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Update

* Preparing PR

* Address PR review feedback on sensitivity checks

Must-fix:
- pymc_models: forward user priors through BayesianBasisExpansionTimeSeries
  and StateSpaceTimeSeries _clone() (add priors kwarg to both __init__s)
- placebo_in_time: tighten selection_method to Literal["sequential",
  "random"]

Should-fix:
- placebo_in_time: min_gap now measures observation-count distance
  between selected folds (tracked via each candidate's position in the
  sorted pre-period index), matching the test's intent
- test_placebo_in_time: add targeted unit tests pinning the corrected
  assurance formula (true_effect = theta_new + expected_effect)
- outcome_falsification: narrow the broad except to (PatsyError,
  FormulaException, DataException, ValueError, KeyError, RuntimeError,
  LinAlgError) and warnings.warn on skip so silent failures surface
- outcome_falsification: add store_experiments flag so callers can drop
  fitted experiments and keep only the summary stats

Nits:
- notebook: add comment flagging the OWID URL runtime dependency
- notebook: CO2 -> CO2 (with subscript) in markdown prose
- test_outcome_falsification: extract shared its_context fixture
- placebo_in_time: document greedy-selection failure mode in docstring
  and error message

Tests:
- add regression tests that _clone() preserves user_priors on both
  time-series models

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Address PR #826 review feedback (round 2)

Ben's review from 2026-04-23:

PlaceboInTime (checks/placebo_in_time.py):
- Add allow_overlap parameter (default False) that enforces non-overlap
  of pseudo-intervention windows, so random folds no longer violate
  the hierarchical model's exchangeability assumption by default.
- Replace the "retry with a different random_seed" error path with a
  bounded greedy-selection retry loop (MAX_RANDOM_SELECTION_RETRIES=16)
  using deterministic sub-seeds derived from random_seed; failure
  message now names the knobs to relax (allow_overlap, min_gap,
  n_folds).
- Warn when a pre-drawn numpy expected_effect_prior is shorter than
  the number of replications requested by the assurance simulation,
  documenting the cycling behaviour in _draw_expected_effect_samples.
- Surface allow_overlap=True in __repr__ following the same
  "non-default only" pattern as selection_method.
- Document how intervention_length falls back to
  data.index.max() - treatment_time when treatment_end_time is unset,
  shrinking the random-mode eligible window.

OutcomeFalsification (checks/outcome_falsification.py):
- Warn at run() when storing >= 3 fitted experiments, explaining that
  store_experiments=False keeps only summary statistics.
- Rewrite __repr__ to hide default alpha and store_experiments flags.
- Drop dead np.linalg.LinAlgError from the caught-exception tuple and
  the now-unused numpy import.

Docs:
- Wire its_place_in_time_analysis.ipynb into the ITS toctree so it
  stops being an orphan page.
- Cross-link the notebook from sensitivity_checks.md under the
  "Where examples already exist" list.
- Tag plot-only cells with hide-input and sampler-heavy cells with
  hide-output so the rendered page collapses non-essential chunks.

Tests:
- Pin allow_overlap default, the non-overlap invariant, the
  _windows_overlap helper for numeric and datetime indices, the
  allow_overlap opt-out, the bounded-retry reproducibility and
  exhaustion paths, and the expected-effect-prior cycling warning.
- Pin the new OutcomeFalsification __repr__ pattern, the
  store_experiments memory warning at run() time, and its opt-out and
  below-threshold paths.
- Expand the upstream-bug TODO in test_run_handles_failed_formula.

Made-with: Cursor

* Update its_place_in_time_analysis.ipynb

* Retune sampler kwargs for ITS notebook

Lower target_accept (0.94 -> 0.89), add explicit step_scale and
max_treedepth=100, double chains (4 -> 8) with draws=500 and cores=16,
and reduce n_changepoints_trend (18 -> 8). Re-executes the notebook so
runtime/sample-count messages match the new config.

* Fix 'fossilfuels' typo in ITS placebo notebook

Addresses Ben's review (PR #826, 2026-04-30): "fossilfuels" -> "fossil fuels".

* Fix '?.' punctuation in fog detective example

Addresses Ben's review (PR #826, 2026-04-30): "?." -> "?".

* Enable retina figure format in ITS placebo notebook

Adds `%config InlineBackend.figure_format = 'retina'` to the Setup cell
so plots render at high resolution on retina displays. Addresses Ben's
review (PR #826, 2026-04-30).

* Replace 'hallucinate effects' with 'false positives' phrasing

Three occurrences updated to be slightly clearer per Ben's review
(PR #826, 2026-04-30): the table row in 'The case', the framing
question after the coal CO2 fit, and the callout-tip on Panel C.

* Clarify 'estimator' vs 'model' scope in StateSpaceTimeSeries note

Spells out that 'estimator' means the underlying counterfactual model
(BayesianBasisExpansionTimeSeries, StateSpaceTimeSeries, ...) still
inside the ITS quasi-experimental approach, and notes that ITS-level
and model-specific assumptions still have to hold. Addresses Ben's
review (PR #826, 2026-04-30).

* Flag placebo-in-time framing in notebook introduction

Adds a paragraph after the 'detective workflow' line that explicitly
states the notebook showcases how placebo-in-time stress-tests the
ITS identifying assumptions and helps move from 'CI excludes zero' to
a defensible causal claim. Addresses Ben's review (PR #826, 2026-04-30).

* Add closing sentence on placebo-in-time's role in ITS

Final callout-important now closes with a sentence stating that, in
ITS settings, placebo-in-time turns the unfalsifiable parallel-
counterfactual assumption into something you can probe with the data
you have, making causal claims more robust to skeptical readers.
Addresses Ben's review (PR #826, 2026-04-30).

* Explain PlaceboInTime n_folds, selection_method, min_gap in notebook

Adds a short bulleted breakdown of the three knobs the next Pipeline
cell uses (n_folds=3, selection_method='random', min_gap=2), explains
why three folds is a reasonable default for short pre-periods, and
links to the PlaceboInTime API page and the sensitivity_checks survey
for the full set of options. Addresses Ben's review (PR #826,
2026-04-30).

* Explain pipeline reuse in 'Did gas CO2 rise?' section

Adds a short explainer right under the heading saying the next cell
re-uses exactly the coal-CO2 pipeline with gas_co2 as the outcome,
and what we expect the placebo result to look like if fuel
substitution really happened. Addresses Ben's review (PR #826,
2026-04-30).

* Expand calibration plot interpretation and decision-making notes

Rewrites the 'How to read the three panels' callout to give a fuller
account of what each panel encodes, with explicit decision rules for
panel C, the meaning of p_cal, and the SUPPORTED threshold. Adds a
'Beyond the qualitative reading' paragraph that points to the
quantitative decision tools already in PlaceboInTime (Bayesian
assurance, ROPE, n_design_replications) and cross-links to the
PlaceboInTime API page and the sensitivity_checks survey.

Also moves the post-plot observation ('the coal CO2 effect is
massive') into a new markdown cell *after* the calibration plot, so
the reading order is: how-to-read -> plot -> what we actually saw.
Addresses Ben's review (PR #826, 2026-04-30).

* Number L2 headings 'Question 1..4' to match the case-study table

Renames the four investigative L2 headings to match the four-row
table in 'The case' so the link between the questions and the
sections is unambiguous:

  Q1 -> Estimate the effect on coal CO2
  Q2 -> How often does the model lie?
  Q3 -> Falsification --- where did the energy go?
  Q4 -> Did total CO2 or energy demand change? (NEW L2)

Q4 was previously two ### sub-sections nested inside Q3, which
mixed the trace-the-mechanism step with the boundary-check step.
Promoting it makes the boundary check its own section and matches
the table's row 4. The total-CO2 transition prose is rewritten to
serve as the Q4 lead-in.

Also demotes the standalone 'Visualising what the estimator sees
when nothing happens' L2 to ### so it sits cleanly under Q2 rather
than becoming a 5th top-level entry. Addresses Ben's review (PR
#826, 2026-04-30).

* Shrink first overview plot figsize for larger relative text

Reduces the four-panel UK overview from figsize=(14, 8) to (9, 6) so
axis labels and panel titles read at a more comfortable relative size
(retina rendering keeps it crisp). Addresses Ben's review (PR #826,
2026-04-30).

* Switch calibration plot to 3 rows and shrink figsize

Reshapes plot_placebo_calibration from a 1x3 strip at (14, 4) to a
3x1 stack at (7, 9). Each panel is now wider relative to the figure
(7 vs ~4.7 inches) so axis labels, legends, and the p_cal banner
read at a more comfortable relative size, and the overall figure is
narrower so the existing fontsize=7/8/9 settings now look right
without further tuning. Addresses Ben's review (PR #826,
2026-04-30).

* Refresh notebook outputs after replotting + retina config

Re-runs the notebook so the embedded figures match the updated
plotting code (overview at figsize=(9, 6), calibration plot in 3x1
layout) and reflect the retina figure_format. Sampler stats also
refreshed; numeric results are unchanged in substance, only the
small run-to-run variation expected for fresh MCMC seeds.

* Fix codespell warning: 're-use' -> 'reuse'

Pre-commit's codespell skips .ipynb files, but CI converts the
notebook to markdown via docs/source/.codespell/notebook_to_markdown.py
and runs codespell on the result, which flagged 're-use' on line 452
of the converted Q3 explainer.

* Fix ruff lints in ITS placebo notebook (prek/pre-commit.ci)

Four ruff errors flagged in CI by prek (the local pre-commit hook
config excludes docs/, but prek lints them anyway):

* I001 + F401 in cell 1 (Setup): drop unused mpatches import and
  normalize the import grouping (stdlib / third-party / first-party).
* B905 in cell 14: add strict=True to zip(fold_results, fold_samples).
  The two lists are constructed in lockstep so True is the safer choice
  (catches mismatch as a bug rather than silently truncating).
* C408 in cell 14: rewrite bbox=dict(...) as a {} literal.

Verified with `ruff check docs/source/notebooks/its_place_in_time_analysis.ipynb`:
'All checks passed!'.

* changes

* Update outcome_falsification.py

* Update placebo_in_time.py

* precommit

* 3.14

* Rename ITS placebo notebook and merge main

Rename its_place_in_time_analysis.ipynb to its_placebo_in_time_analysis.ipynb and update notebook index and sensitivity_checks cross-links. Merge latest main to stay current with upstream.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Benjamin T. Vincent <inferencelab@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
* Update UML Diagrams

* Trigger CI (bot-opened PRs skip GITHUB_TOKEN workflow chain)

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Benjamin T. Vincent <inferencelab@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
pre-commit-ci and other bots should not receive first-contributor welcome comments when opening autoupdate PRs.

Co-authored-by: Cursor <cursoragent@cursor.com>
Supersedes pre-commit.ci autoupdate PR #869: bump ruff, pymarkdown, and mypy; keep pyproject2conda on 0.22.x until the 0.23 regression is fixed. Add blank lines around list blocks required by pymarkdown v0.9.37.

Co-authored-by: Cursor <cursoragent@cursor.com>
Suppress zizmor dangerous-triggers with an inline justification, set
top-level permissions to {} and grant issues/pull-requests write at the
job level only, and hoist github.actor into env:.

Closes #888

Co-authored-by: Benjamin T. Vincent <inferencelab@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
* Broaden numpydoc-validation scope across causalpy/ (#898)

Replace the ``.plot``-only exclude regex in ``[tool.numpydoc_validation]`` with a private-member exclude (``\\._``), and widen the pre-commit ``files`` pattern from ``^causalpy/experiments/.*\\.py$`` to ``^causalpy/(?!tests/|data/).*\\.py$`` so the existing ``PR01``/``PR02`` checks now apply package-wide. Document and fix every public-API ``PR01``/``PR02`` violation that surfaces under the new scope: convert remaining Sphinx ``:param:`` blocks to numpydoc ``Parameters`` sections, add missing ``**kwargs``/``*args`` rows, populate the protocol/check/maketables/skl helpers, and tidy a ``See Also`` entry in ``utils.py`` that previously broke the docstring parser. The simulated-data helpers under ``causalpy/data/`` are intentionally excluded for this round; they keep their didactic ``:param`` style.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Enable PR04 (parameter has no type) numpydoc check (#898)

Add ``PR04`` to the numpydoc-validation check set so parameter rows missing a type are caught going forward. No code changes are required: every documented parameter under the package-wide scope already declares a type.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Enable PR07 (parameter has no description) numpydoc check (#898)

Add ``PR07`` to the numpydoc-validation check set so undocumented parameter rows are caught going forward. No code changes are required: every parameter row under the package-wide scope already carries a description.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Enable PR10 (space before colon) numpydoc check (#898)

Add ``PR10`` to the numpydoc-validation check set so parameter rows that omit a space before the type colon are caught going forward. No code changes are required: existing docstrings in the broadened scope already conform.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Enable RT03 (return value has no description) numpydoc check (#898)

Add ``RT03`` to the numpydoc-validation check set so undocumented return rows are caught going forward, and flesh out the bare ``CheckResult`` return entry on the ``Check`` protocol's ``run`` method (the only violation surfaced under the package-wide scope).

Co-authored-by: Cursor <cursoragent@cursor.com>

* Enable SS03 (summary ends with period) numpydoc check (#898)

Add ``SS03`` to the numpydoc-validation check set so first-line summaries that omit a trailing period are caught going forward, and update every docstring under the package-wide scope that previously violated the rule (mostly module-level docstrings and a handful of method summaries).

Co-authored-by: Cursor <cursoragent@cursor.com>

* Enable GL07 (section ordering) numpydoc check (#898)

Add ``GL07`` to the numpydoc-validation check set so out-of-order docstring sections are caught going forward. Reorder ``Examples``/``Notes``/``See Also`` blocks in ``InterruptedTimeSeries``, ``PiecewiseITS``, ``PyMCModel.priors_from_data``, and the variable-selection-prior classes (the latter previously used a non-standard singular ``Example`` heading), all to match numpydoc's canonical ordering.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Enable GL08 and replace interrogate with numpydoc-validation (#898)

Add ``GL08`` (object has no docstring) to the numpydoc-validation check set so missing docstrings are caught the same way every other rule is, and retire the standalone ``interrogate`` hook now that ``numpydoc-validation`` covers the same ground (and more) for the public API. Concretely:

- Drop the ``interrogate`` pre-commit hook, the ``[tool.interrogate]`` section in ``pyproject.toml``, the ``interrogate`` extras entries, the ``interrogate-badge`` workflow, the ``Makefile`` invocation, and the README badge.
- Add a top-level package docstring in ``causalpy/__init__.py`` and flesh out abstract ``fit``/``build_model``/``calculate_cumulative_impact`` stubs that previously had no docstring.
- Rename the nested ``plot_weights``/``make_hists`` helpers in ``InversePropensityWeighting._plot_weights_propensity`` to a leading underscore so they fall under the configured private exclude.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fix numpydoc violations in code merged from main (#898)

After rebasing onto main, the widened numpydoc-validation scope surfaced
new violations in code that landed on main after this PR was opened
(SyntheticDifferenceInDifferences, the SDiD weight fitter, the basis-expansion
and state-space time-series models, and the OutcomeFalsification check).
Document the missing parameters and fix the SDiD module summary period.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
@drbenvincent drbenvincent added the documentation Improvements or additions to documentation label Jun 10, 2026
@review-notebook-app

Copy link
Copy Markdown

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@drbenvincent

Copy link
Copy Markdown
Collaborator

Automated triage

Recommendation: review:high — no decision gate identified.

Why:

  • Despite the title focusing on SEO/docs, the changed files include core library code (causalpy/__init__.py, causalpy/checks/*.py, causalpy/experiments/*.py, causalpy/pymc_models.py, causalpy/pipeline.py, causalpy/reporting.py, causalpy/maketables_adapters.py), CI workflows, pre-commit config, and ARCHITECTURE.md.
  • More than 50 files are touched, including non-documentation source changes.
  • codecov/patch check has FAILED.

Review focus:

  1. Understand the scope: the body describes SEO-only changes but the diff includes many core library files — verify whether the file list is stale or the PR bundles unrelated changes.
  2. Check the codecov/patch failure for untested code paths.
  3. Review the pre-commit-config.yaml and workflow changes.

Confidence: medium

@drbenvincent drbenvincent added the review:high High-impact change requiring thorough human review label Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation review:high High-impact change requiring thorough human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants