Skip to content

Dependencies

Ownership

The root pyproject.toml owns an empty runtime dependency array, four exact optional tool audiences, and the isolated resolver-bootstrap pins:

Audience Lock Purpose
Quality requirements-dev.txt Ruff, mypy, Bandit, and dependency audit
Tests requirements-test.txt pytest, asyncio support, and branch coverage
Packaging requirements-package.txt standard wheel and sdist construction only
Documentation requirements-docs.txt strict MkDocs site build

Every lock is generated by pip-compile, carries exact versions and SHA-256 hashes, and installs with wheel-only hash enforcement followed by pip check. Direct dependencies do not overlap between audiences. Installed PEP 561 smoke uses mypy from the quality environment; the packaging environment therefore contains no type checker or standalone executable builder.

The four PEP 621 extras are maintainer tool audiences rather than runtime features. Normal library installation resolves none of them. CI's distribution job combines only the packaging tools needed to construct archives with the quality audience's mypy for an installed-package typing check; publication downloads the already gated archives and installs no build tools.

There is no third-party product-license inventory because the runtime dependency set is empty and none of the maintainer tool audiences is redistributed in the wheel or sdist. Distribution verification instead checks that the project's MIT license is present and exact. Adding any runtime or redistributed third-party dependency also requires adding an owned license inventory before release.

Reviewed update loop

  1. Change exact direct pins in the appropriate pyproject.toml group.
  2. Run make lock, or make refresh-dependencies for a deliberate graph-wide refresh.
  3. Review every transitive pin and hash change.
  4. Run make freeze-check, make lock-platform-check, make dependency-snapshot, and make audit.
  5. Review make audit-raw and make outdated.

Generated lock files are not edited manually. The isolated resolver bootstrap is exactly pinned in the standard [dependency-groups].resolver-bootstrap group, which is excluded from built package metadata. The Makefile asks the dependency-policy helper for the complete closure instead of duplicating it, installs that closure with --no-deps, and then runs pip check. Every bootstrap package that also occurs in an audience lock has the same version. Freeze checking compares regenerated content while excluding only pip-compile's interpreter-specific header.

The audit covers all four locks and the exact resolver bootstrap. Findings are accepted only when they exactly equal .github/dependency-audit-exceptions.json; both new findings and stale exceptions fail. Dependency submission derives all four persistent manifests offline from validated locks; the transient resolver group is validated and audited but is not submitted as a fifth lock. The dependency contract contains the evidence mapping.