{"owner":"py-why","repo":"dowhy","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"# DoWhy Agent Guidelines\n\nThis file provides guidance for automated AI agents working with the DoWhy codebase. It covers the repository structure, architectural goals, and the checks that must pass before any PR can be merged.\n\n---\n\n## Project Overview\n\nDoWhy is a Python library for causal inference. It supports two complementary frameworks:\n\n1. **Potential outcomes** (classic treatment/control)\n2. **Graphical causal models (GCM)** (DAG-based)\n\nBoth frameworks are unified under a four-step workflow: **Model → Identify → Estimate → Refute**.\n\n---\n\n## Repository Layout\n\n```\ndowhy/                  # Main package\n  __init__.py           # Public exports: CausalModel, identify_effect_*, EstimandType\n  causal_model.py       # CausalModel: orchestrates the 4-step workflow\n  causal_estimator.py   # Base class for all estimators\n  causal_graph.py       # Graph operations and DAG handling\n  causal_refuter.py     # Base class for refuters\n  causal_estimators/    # 15+ estimation method implementations\n  causal_identifier/    # Identification algorithms (do-calculus)\n  causal_refuters/      # Robustness / sensitivity tests\n  gcm/                  # Graphical Causal Models module (root cause analysis, anomaly detection, etc.)\n  api/                  # Public API surface\n  do_samplers/          # Sampling from interventional distributions\n  graph_learners/       # Structure learning algorithms\n  data_transformers/    # Data preprocessing\n  timeseries/           # Time series causal inference\n  causal_prediction/    # ML-based prediction (neural networks, dataloaders)\n  utils/                # Shared utilities\n  datasets.py           # Built-in datasets for testing/demos\ntests/                  # Test suite (mirrors dowhy/ structure)\ndocs/                   # Sphinx documentation\n  source/\n    contributing/       # Developer & contribution guides\n    example_notebooks/  # Jupyter notebook examples\n    user_guide/         # End-user documentation\npyproject.toml          # Build config, dependencies, tool config (Poetry)\n.flake8                 # flake8 config\n```\n\n---\n\n## Architecture & Design Goals\n\n- **Four-step causal workflow**: Every contribution should fit cleanly into Model, Identify, Estimate, or Refute. Do not conflate steps.\n- **Backwards compatibility**: The `CausalModel` public API is stable. New methods should extend, not replace, existing interfaces.\n- **Two frameworks, one API**: Changes that touch one framework (potential outcomes vs. GCM) should not break the other.\n- **Extensibility**: New estimators inherit from `CausalEstimator`; new refuters from `CausalRefuter`. Follow existing class hierarchies.\n- **Minimal required dependencies**: Core functionality should remain available without optional extras (`plotting`, `pygraphviz`, `econml`). Guard optional imports with try/except and raise informative errors.\n- **Python 3.9–3.13**: All code must be compatible with Python 3.9 through 3.13.\n\n---\n\n## Environment Setup\n\n```bash\npip install --upgrade pip\npoetry install -E \"plotting\"       # Standard dev install\n```\n\nOptional extras:\n\n```bash\npoetry install -E \"pygraphviz\"     # Graph visualization via graphviz\npoetry install -E \"econml\"         # EconML CATE estimators\n```\n\nOn Linux, `pygraphviz` may require installation of graphviz and its developer package\n\n---\n\n## Linting & Formatting\n\n**All three checks must pass before a PR can merge.**\n\n| Tool | Purpose | Config |\n|------|---------|--------|\n| `black` | Code formatting | Line length 120, targets py39–py313 |\n| `isort` | Import sorting | Profile `black`, line length 120, multi-line output 3 |\n| `flake8` | Linting | Max line 127, max complexity 10, hard errors on E9/F63/F7/F82 |\n\n### Commands\n\n```bash\n# Auto-fix formatting\npoetry run poe format\n\n# Check only (what CI runs)\npoetry run poe format_check\npoetry run poe lint\n```\n\n### Rules to follow\n\n- Maximum line length: **120 characters** (black) / **127 characters** (flake8 hard limit).\n- Cyclomatic complexity per function: **≤ 10**.\n- Import order: standard library → third-party → local, each group sorted. `isort` enforces this automatically.\n- Do not add `# noqa` silences unless genuinely unavoidable; document why if you do.\n\n---\n\n## Testing\n\n```bash\n# Standard test run (excludes `advanced` and `econml` markers)\npoetry run poe test\n\n# Skip notebook execution (faster)\npoetry run poe test_no_notebooks\n\n# Run only EconML tests\npoetry run poe test_econml\n\n# Run the full test suite (including `advanced`)\npoetry run poe test_advanced\n\n# Run a specific subdirectory\npoetry run pytest -v tests/causal_refuters\n\n# Run only tests you marked `focused` (debug helper)\npoetry run poe test_focused\n```\n\n### Test markers\n\n| Marker | Meaning |\n|--------|---------|\n| `advanced` | Skipped by default; run only on package-level updates |\n| `notebook` | Executes Jupyter notebooks; slow |\n| `econml` | Requires `econml` extra |\n| `focused` | Temporary debug marker; never commit with this marker |\n\n### Guidelines for new tests\n\n- Mirror the source layout: `tests/gcm/` for `dowhy/gcm/`, etc.\n- New features **must** include tests.\n- Avoid brittle assertions on floating-point results; use tolerances (`pytest.approx`, `np.testing.assert_allclose`).\n- Use `@pytest.mark.advanced` for tests that are slow or depend on heavy external libraries.\n- Do not remove or weaken existing tests.\n\n---\n\n## Commit Requirements\n\n**DCO sign-off is mandatory.** Every commit must be signed off:\n\n```bash\ngit commit --signoff -m \"descriptive message\"\n# or shorthand:\ngit commit -s -m \"descriptive message\"\n```\n\nIf you forgot:\n\n```bash\n# Single commit\ngit commit --amend --no-edit --signoff\n\n# Multiple commits — squash then sign\ngit reset --soft HEAD~<N>\ngit commit -s -m \"new descriptive message\"\n```\n\nCommits without a DCO sign-off cannot be merged.\n\n---\n\n## PR Checklist\n\nBefore opening or updating a PR, confirm:\n\n- [ ] `poetry run poe lint` passes (no hard flake8 errors).\n- [ ] `poetry run poe format_check` passes (black + isort compliant).\n- [ ] `poetry run poe test` passes (or a justification is provided for a new failure).\n- [ ] New code is covered by tests.\n- [ ] All commits include a DCO sign-off (`Signed-off-by:` trailer in the commit message). For example, check with `git log --format='%h %s%n%n%b'` and verify each commit body contains `Signed-off-by:`.\n- [ ] If a new dependency was added or `poetry.lock` changed, a justification is included in the PR description.\n- [ ] Optional imports are guarded and fail gracefully.\n- [ ] Public API additions are documented (docstrings + `docs/` RST where appropriate).\n\n---\n\n## Dependency Management\n\n- DoWhy uses **Poetry** for dependency management.\n- Do not edit `poetry.lock` manually; use `poetry add` / `poetry update`.\n- Updating `poetry.lock` in a PR requires a written justification explaining why the update is necessary.\n- Keep new dependencies to a minimum; prefer libraries already used in the project.\n\n---\n\n## Documentation\n\n- Source docs are in `docs/source/` (Sphinx + RST).\n- Jupyter notebook examples live in `docs/source/example_notebooks/`.\n- New public functions/classes need numpy-style docstrings.\n- After significant API additions, update the relevant `.rst` file under `docs/source/`.\n\n---\n\n## Common Pitfalls\n\n- **Mixing frameworks**: The `gcm` module and the classic `CausalModel` workflow are separate. Do not cross-wire them without a clear interface boundary.\n- **Missing optional-import guards**: Imports of `matplotlib`, `pygraphviz`, `pydot`, `torch`, etc. must be inside a `try/except ImportError` block with a user-friendly error message.\n- **Breaking `CausalModel` constructor or method signatures**: This is a stable public API; use keyword arguments and default values to extend it.\n- **Removing or altering test markers**: Changing an `advanced` marker to a default-run test may slow CI unexpectedly.\n- **Long functions**: flake8 enforces complexity ≤ 10; refactor complex logic into helper functions.\n- **Not running `format` before committing**: black and isort will cause CI to fail if code is not formatted.\n"},"files":{"AGENTS.md":"# DoWhy Agent Guidelines\n\nThis file provides guidance for automated AI agents working with the DoWhy codebase. It covers the repository structure, architectural goals, and the checks that must pass before any PR can be merged.\n\n---\n\n## Project Overview\n\nDoWhy is a Python library for causal inference. It supports two complementary frameworks:\n\n1. **Potential outcomes** (classic treatment/control)\n2. **Graphical causal models (GCM)** (DAG-based)\n\nBoth frameworks are unified under a four-step workflow: **Model → Identify → Estimate → Refute**.\n\n---\n\n## Repository Layout\n\n```\ndowhy/                  # Main package\n  __init__.py           # Public exports: CausalModel, identify_effect_*, EstimandType\n  causal_model.py       # CausalModel: orchestrates the 4-step workflow\n  causal_estimator.py   # Base class for all estimators\n  causal_graph.py       # Graph operations and DAG handling\n  causal_refuter.py     # Base class for refuters\n  causal_estimators/    # 15+ estimation method implementations\n  causal_identifier/    # Identification algorithms (do-calculus)\n  causal_refuters/      # Robustness / sensitivity tests\n  gcm/                  # Graphical Causal Models module (root cause analysis, anomaly detection, etc.)\n  api/                  # Public API surface\n  do_samplers/          # Sampling from interventional distributions\n  graph_learners/       # Structure learning algorithms\n  data_transformers/    # Data preprocessing\n  timeseries/           # Time series causal inference\n  causal_prediction/    # ML-based prediction (neural networks, dataloaders)\n  utils/                # Shared utilities\n  datasets.py           # Built-in datasets for testing/demos\ntests/                  # Test suite (mirrors dowhy/ structure)\ndocs/                   # Sphinx documentation\n  source/\n    contributing/       # Developer & contribution guides\n    example_notebooks/  # Jupyter notebook examples\n    user_guide/         # End-user documentation\npyproject.toml          # Build config, dependencies, tool config (Poetry)\n.flake8                 # flake8 config\n```\n\n---\n\n## Architecture & Design Goals\n\n- **Four-step causal workflow**: Every contribution should fit cleanly into Model, Identify, Estimate, or Refute. Do not conflate steps.\n- **Backwards compatibility**: The `CausalModel` public API is stable. New methods should extend, not replace, existing interfaces.\n- **Two frameworks, one API**: Changes that touch one framework (potential outcomes vs. GCM) should not break the other.\n- **Extensibility**: New estimators inherit from `CausalEstimator`; new refuters from `CausalRefuter`. Follow existing class hierarchies.\n- **Minimal required dependencies**: Core functionality should remain available without optional extras (`plotting`, `pygraphviz`, `econml`). Guard optional imports with try/except and raise informative errors.\n- **Python 3.9–3.13**: All code must be compatible with Python 3.9 through 3.13.\n\n---\n\n## Environment Setup\n\n```bash\npip install --upgrade pip\npoetry install -E \"plotting\"       # Standard dev install\n```\n\nOptional extras:\n\n```bash\npoetry install -E \"pygraphviz\"     # Graph visualization via graphviz\npoetry install -E \"econml\"         # EconML CATE estimators\n```\n\nOn Linux, `pygraphviz` may require installation of graphviz and its developer package\n\n---\n\n## Linting & Formatting\n\n**All three checks must pass before a PR can merge.**\n\n| Tool | Purpose | Config |\n|------|---------|--------|\n| `black` | Code formatting | Line length 120, targets py39–py313 |\n| `isort` | Import sorting | Profile `black`, line length 120, multi-line output 3 |\n| `flake8` | Linting | Max line 127, max complexity 10, hard errors on E9/F63/F7/F82 |\n\n### Commands\n\n```bash\n# Auto-fix formatting\npoetry run poe format\n\n# Check only (what CI runs)\npoetry run poe format_check\npoetry run poe lint\n```\n\n### Rules to follow\n\n- Maximum line length: **120 characters** (black) / **127 characters** (flake8 hard limit).\n- Cyclomatic complexity per function: **≤ 10**.\n- Import order: standard library → third-party → local, each group sorted. `isort` enforces this automatically.\n- Do not add `# noqa` silences unless genuinely unavoidable; document why if you do.\n\n---\n\n## Testing\n\n```bash\n# Standard test run (excludes `advanced` and `econml` markers)\npoetry run poe test\n\n# Skip notebook execution (faster)\npoetry run poe test_no_notebooks\n\n# Run only EconML tests\npoetry run poe test_econml\n\n# Run the full test suite (including `advanced`)\npoetry run poe test_advanced\n\n# Run a specific subdirectory\npoetry run pytest -v tests/causal_refuters\n\n# Run only tests you marked `focused` (debug helper)\npoetry run poe test_focused\n```\n\n### Test markers\n\n| Marker | Meaning |\n|--------|---------|\n| `advanced` | Skipped by default; run only on package-level updates |\n| `notebook` | Executes Jupyter notebooks; slow |\n| `econml` | Requires `econml` extra |\n| `focused` | Temporary debug marker; never commit with this marker |\n\n### Guidelines for new tests\n\n- Mirror the source layout: `tests/gcm/` for `dowhy/gcm/`, etc.\n- New features **must** include tests.\n- Avoid brittle assertions on floating-point results; use tolerances (`pytest.approx`, `np.testing.assert_allclose`).\n- Use `@pytest.mark.advanced` for tests that are slow or depend on heavy external libraries.\n- Do not remove or weaken existing tests.\n\n---\n\n## Commit Requirements\n\n**DCO sign-off is mandatory.** Every commit must be signed off:\n\n```bash\ngit commit --signoff -m \"descriptive message\"\n# or shorthand:\ngit commit -s -m \"descriptive message\"\n```\n\nIf you forgot:\n\n```bash\n# Single commit\ngit commit --amend --no-edit --signoff\n\n# Multiple commits — squash then sign\ngit reset --soft HEAD~<N>\ngit commit -s -m \"new descriptive message\"\n```\n\nCommits without a DCO sign-off cannot be merged.\n\n---\n\n## PR Checklist\n\nBefore opening or updating a PR, confirm:\n\n- [ ] `poetry run poe lint` passes (no hard flake8 errors).\n- [ ] `poetry run poe format_check` passes (black + isort compliant).\n- [ ] `poetry run poe test` passes (or a justification is provided for a new failure).\n- [ ] New code is covered by tests.\n- [ ] All commits include a DCO sign-off (`Signed-off-by:` trailer in the commit message). For example, check with `git log --format='%h %s%n%n%b'` and verify each commit body contains `Signed-off-by:`.\n- [ ] If a new dependency was added or `poetry.lock` changed, a justification is included in the PR description.\n- [ ] Optional imports are guarded and fail gracefully.\n- [ ] Public API additions are documented (docstrings + `docs/` RST where appropriate).\n\n---\n\n## Dependency Management\n\n- DoWhy uses **Poetry** for dependency management.\n- Do not edit `poetry.lock` manually; use `poetry add` / `poetry update`.\n- Updating `poetry.lock` in a PR requires a written justification explaining why the update is necessary.\n- Keep new dependencies to a minimum; prefer libraries already used in the project.\n\n---\n\n## Documentation\n\n- Source docs are in `docs/source/` (Sphinx + RST).\n- Jupyter notebook examples live in `docs/source/example_notebooks/`.\n- New public functions/classes need numpy-style docstrings.\n- After significant API additions, update the relevant `.rst` file under `docs/source/`.\n\n---\n\n## Common Pitfalls\n\n- **Mixing frameworks**: The `gcm` module and the classic `CausalModel` workflow are separate. Do not cross-wire them without a clear interface boundary.\n- **Missing optional-import guards**: Imports of `matplotlib`, `pygraphviz`, `pydot`, `torch`, etc. must be inside a `try/except ImportError` block with a user-friendly error message.\n- **Breaking `CausalModel` constructor or method signatures**: This is a stable public API; use keyword arguments and default values to extend it.\n- **Removing or altering test markers**: Changing an `advanced` marker to a default-run test may slow CI unexpectedly.\n- **Long functions**: flake8 enforces complexity ≤ 10; refactor complex logic into helper functions.\n- **Not running `format` before committing**: black and isort will cause CI to fail if code is not formatted.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"# DoWhy Agent Guidelines\n\nThis file provides guidance for automated AI agents working with the DoWhy codebase. It covers the repository structure, architectural goals, and the checks that must pass before any PR can be merged.\n\n---\n\n## Project Overview\n\nDoWhy is a Python library for causal inference. It supports two complementary frameworks:\n\n1. **Potential outcomes** (classic treatment/control)\n2. **Graphical causal models (GCM)** (DAG-based)\n\nBoth frameworks are unified under a four-step workflow: **Model → Identify → Estimate → Refute**.\n\n---\n\n## Repository Layout\n\n```\ndowhy/                  # Main package\n  __init__.py           # Public exports: CausalModel, identify_effect_*, EstimandType\n  causal_model.py       # CausalModel: orchestrates the 4-step workflow\n  causal_estimator.py   # Base class for all estimators\n  causal_graph.py       # Graph operations and DAG handling\n  causal_refuter.py     # Base class for refuters\n  causal_estimators/    # 15+ estimation method implementations\n  causal_identifier/    # Identification algorithms (do-calculus)\n  causal_refuters/      # Robustness / sensitivity tests\n  gcm/                  # Graphical Causal Models module (root cause analysis, anomaly detection, etc.)\n  api/                  # Public API surface\n  do_samplers/          # Sampling from interventional distributions\n  graph_learners/       # Structure learning algorithms\n  data_transformers/    # Data preprocessing\n  timeseries/           # Time series causal inference\n  causal_prediction/    # ML-based prediction (neural networks, dataloaders)\n  utils/                # Shared utilities\n  datasets.py           # Built-in datasets for testing/demos\ntests/                  # Test suite (mirrors dowhy/ structure)\ndocs/                   # Sphinx documentation\n  source/\n    contributing/       # Developer & contribution guides\n    example_notebooks/  # Jupyter notebook examples\n    user_guide/         # End-user documentation\npyproject.toml          # Build config, dependencies, tool config (Poetry)\n.flake8                 # flake8 config\n```\n\n---\n\n## Architecture & Design Goals\n\n- **Four-step causal workflow**: Every contribution should fit cleanly into Model, Identify, Estimate, or Refute. Do not conflate steps.\n- **Backwards compatibility**: The `CausalModel` public API is stable. New methods should extend, not replace, existing interfaces.\n- **Two frameworks, one API**: Changes that touch one framework (potential outcomes vs. GCM) should not break the other.\n- **Extensibility**: New estimators inherit from `CausalEstimator`; new refuters from `CausalRefuter`. Follow existing class hierarchies.\n- **Minimal required dependencies**: Core functionality should remain available without optional extras (`plotting`, `pygraphviz`, `econml`). Guard optional imports with try/except and raise informative errors.\n- **Python 3.9–3.13**: All code must be compatible with Python 3.9 through 3.13.\n\n---\n\n## Environment Setup\n\n```bash\npip install --upgrade pip\npoetry install -E \"plotting\"       # Standard dev install\n```\n\nOptional extras:\n\n```bash\npoetry install -E \"pygraphviz\"     # Graph visualization via graphviz\npoetry install -E \"econml\"         # EconML CATE estimators\n```\n\nOn Linux, `pygraphviz` may require installation of graphviz and its developer package\n\n---\n\n## Linting & Formatting\n\n**All three checks must pass before a PR can merge.**\n\n| Tool | Purpose | Config |\n|------|---------|--------|\n| `black` | Code formatting | Line length 120, targets py39–py313 |\n| `isort` | Import sorting | Profile `black`, line length 120, multi-line output 3 |\n| `flake8` | Linting | Max line 127, max complexity 10, hard errors on E9/F63/F7/F82 |\n\n### Commands\n\n```bash\n# Auto-fix formatting\npoetry run poe format\n\n# Check only (what CI runs)\npoetry run poe format_check\npoetry run poe lint\n```\n\n### Rules to follow\n\n- Maximum line length: **120 characters** (black) / **127 characters** (flake8 hard limit).\n- Cyclomatic complexity per function: **≤ 10**.\n- Import order: standard library → third-party → local, each group sorted. `isort` enforces this automatically.\n- Do not add `# noqa` silences unless genuinely unavoidable; document why if you do.\n\n---\n\n## Testing\n\n```bash\n# Standard test run (excludes `advanced` and `econml` markers)\npoetry run poe test\n\n# Skip notebook execution (faster)\npoetry run poe test_no_notebooks\n\n# Run only EconML tests\npoetry run poe test_econml\n\n# Run the full test suite (including `advanced`)\npoetry run poe test_advanced\n\n# Run a specific subdirectory\npoetry run pytest -v tests/causal_refuters\n\n# Run only tests you marked `focused` (debug helper)\npoetry run poe test_focused\n```\n\n### Test markers\n\n| Marker | Meaning |\n|--------|---------|\n| `advanced` | Skipped by default; run only on package-level updates |\n| `notebook` | Executes Jupyter notebooks; slow |\n| `econml` | Requires `econml` extra |\n| `focused` | Temporary debug marker; never commit with this marker |\n\n### Guidelines for new tests\n\n- Mirror the source layout: `tests/gcm/` for `dowhy/gcm/`, etc.\n- New features **must** include tests.\n- Avoid brittle assertions on floating-point results; use tolerances (`pytest.approx`, `np.testing.assert_allclose`).\n- Use `@pytest.mark.advanced` for tests that are slow or depend on heavy external libraries.\n- Do not remove or weaken existing tests.\n\n---\n\n## Commit Requirements\n\n**DCO sign-off is mandatory.** Every commit must be signed off:\n\n```bash\ngit commit --signoff -m \"descriptive message\"\n# or shorthand:\ngit commit -s -m \"descriptive message\"\n```\n\nIf you forgot:\n\n```bash\n# Single commit\ngit commit --amend --no-edit --signoff\n\n# Multiple commits — squash then sign\ngit reset --soft HEAD~<N>\ngit commit -s -m \"new descriptive message\"\n```\n\nCommits without a DCO sign-off cannot be merged.\n\n---\n\n## PR Checklist\n\nBefore opening or updating a PR, confirm:\n\n- [ ] `poetry run poe lint` passes (no hard flake8 errors).\n- [ ] `poetry run poe format_check` passes (black + isort compliant).\n- [ ] `poetry run poe test` passes (or a justification is provided for a new failure).\n- [ ] New code is covered by tests.\n- [ ] All commits include a DCO sign-off (`Signed-off-by:` trailer in the commit message). For example, check with `git log --format='%h %s%n%n%b'` and verify each commit body contains `Signed-off-by:`.\n- [ ] If a new dependency was added or `poetry.lock` changed, a justification is included in the PR description.\n- [ ] Optional imports are guarded and fail gracefully.\n- [ ] Public API additions are documented (docstrings + `docs/` RST where appropriate).\n\n---\n\n## Dependency Management\n\n- DoWhy uses **Poetry** for dependency management.\n- Do not edit `poetry.lock` manually; use `poetry add` / `poetry update`.\n- Updating `poetry.lock` in a PR requires a written justification explaining why the update is necessary.\n- Keep new dependencies to a minimum; prefer libraries already used in the project.\n\n---\n\n## Documentation\n\n- Source docs are in `docs/source/` (Sphinx + RST).\n- Jupyter notebook examples live in `docs/source/example_notebooks/`.\n- New public functions/classes need numpy-style docstrings.\n- After significant API additions, update the relevant `.rst` file under `docs/source/`.\n\n---\n\n## Common Pitfalls\n\n- **Mixing frameworks**: The `gcm` module and the classic `CausalModel` workflow are separate. Do not cross-wire them without a clear interface boundary.\n- **Missing optional-import guards**: Imports of `matplotlib`, `pygraphviz`, `pydot`, `torch`, etc. must be inside a `try/except ImportError` block with a user-friendly error message.\n- **Breaking `CausalModel` constructor or method signatures**: This is a stable public API; use keyword arguments and default values to extend it.\n- **Removing or altering test markers**: Changing an `advanced` marker to a default-run test may slow CI unexpectedly.\n- **Long functions**: flake8 enforces complexity ≤ 10; refactor complex logic into helper functions.\n- **Not running `format` before committing**: black and isort will cause CI to fail if code is not formatted.\n","category":"root","tokens":2016}]}