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¶
- Change exact direct pins in the appropriate
pyproject.tomlgroup. - Run
make lock, ormake refresh-dependenciesfor a deliberate graph-wide refresh. - Review every transitive pin and hash change.
- Run
make freeze-check,make lock-platform-check,make dependency-snapshot, andmake audit. - Review
make audit-rawandmake 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.