|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +This file provides guidance to AI agents when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +checkdmarc is a Python library and CLI tool for validating email security DNS records (SPF, DMARC, BIMI, MTA-STS, SMTP TLS Reporting, MX/STARTTLS, DNSSEC, SOA). Published on PyPI as `checkdmarc`. |
| 8 | + |
| 9 | +## Common Commands |
| 10 | + |
| 11 | +```bash |
| 12 | +# Run tests with coverage |
| 13 | +coverage run tests.py |
| 14 | + |
| 15 | +# Lint and format |
| 16 | +ruff check --show-fixes |
| 17 | +ruff format . |
| 18 | + |
| 19 | +# Build package |
| 20 | +hatch build |
| 21 | + |
| 22 | +# Build docs |
| 23 | +cd docs && make html |
| 24 | + |
| 25 | +# Full build (format + docs + package) |
| 26 | +./build.sh |
| 27 | +``` |
| 28 | + |
| 29 | +Tests use `unittest.TestCase` in a single `tests.py` file. Run a single test with: |
| 30 | + |
| 31 | +```bash |
| 32 | +python -m pytest tests.py -k "test_name" |
| 33 | +``` |
| 34 | + |
| 35 | +Some tests require network access and are skipped when `GITHUB_ACTIONS` env var is set. |
| 36 | + |
| 37 | +## Architecture |
| 38 | + |
| 39 | +**Entry point:** `checkdmarc/__init__.py` — `check_domains()` orchestrates all checks, returning `DomainCheckResult` TypedDict(s). |
| 40 | + |
| 41 | +**Modules** (each has a primary `check_*()` function): |
| 42 | + |
| 43 | +- `spf.py` — SPF record parsing, DNS lookup counting |
| 44 | +- `dmarc.py` — DMARC/DMARCbis record parsing with DNS tree walk algorithm |
| 45 | +- `bimi.py` — BIMI record and certificate validation |
| 46 | +- `mta_sts.py` — MTA-STS policy fetching and validation |
| 47 | +- `smtp_tls_reporting.py` — TLSRPT record validation |
| 48 | +- `smtp.py` — MX record lookup and STARTTLS testing |
| 49 | +- `dnssec.py` — DNSSEC validation |
| 50 | +- `soa.py` — SOA record parsing |
| 51 | +- `utils.py` — DNS helpers, exception classes, domain normalization |
| 52 | + |
| 53 | +**CLI:** `_cli.py` (entry point: `checkdmarc._cli:_main`) |
| 54 | + |
| 55 | +**Constants/version:** `_constants.py` |
| 56 | + |
| 57 | +**Output:** `results_to_json()`, `results_to_csv()`, `output_to_file()` in `__init__.py`. |
| 58 | + |
| 59 | +## Key Dependencies |
| 60 | + |
| 61 | +- `dnspython` for DNS queries |
| 62 | +- `pyleri` for grammar parsing |
| 63 | +- `publicsuffixlist` for base domain extraction |
| 64 | +- `cryptography`/`pyopenssl`/`pem` for certificate handling |
| 65 | +- `expiringdict` for DNS result caching |
| 66 | + |
| 67 | +## Code Style |
| 68 | + |
| 69 | +- Formatter/linter: **Ruff** |
| 70 | +- Type annotations use `TypedDict` for structured results |
| 71 | +- Python >=3.10 required |
| 72 | +- Build backend: **hatchling** |
0 commit comments