Dependency maintenance
AncestryLLM records application features as optional extras and repository
tooling as purpose-specific PEP 735 dependency groups. The complete resolution
for every extra and group is committed in uv.lock. Local setup synchronizes
the complete graph; purpose-specific workflow jobs synchronize only the
environment they need before calling the canonical Make command. This keeps
quality, security, build, desktop, and release-verification jobs from relying
on undeclared cross-profile tools.
The repository-local, verified uv 0.12.1 bootstrap is the only supported way
to create or update these environments. It requires a system-supplied Python
3.12-3.14; .python-version selects 3.12 by default, and [tool.uv] prohibits
Python downloads. uv is not a project dependency and must not be installed
through a dependency group, pip, an alternate index, or an unverified
executable on PATH.
Environment contracts
The dependency groups are:
| Group | Purpose | Canonical consumers |
|---|---|---|
lint |
Ruff, pre-commit, GFM Markdown validation, and repository checks | make lint, make markdown-check, make hooks, and CI quality jobs |
typecheck |
Strict mypy, third-party type information, and exact ty advisory evaluation | make typecheck, make typecheck-ty, and CI quality jobs |
test |
Pytest and coverage | make test, Python test matrices, and release-project proof jobs |
security |
Dependency audit, SBOM, and workflow audit tools | make security, make sbom, make workflow-audit, and matching workflow jobs |
build |
Distribution construction, artifact validation, and isolated backend evaluation | make package, make evaluate-uv-build, and package/release build jobs |
release-verifier |
Exact PyPI attestation verifier | Release artifact verification only |
make setup runs uv sync --locked --all-extras --all-groups, including the
release-verifier group, so a local source checkout has the complete locked
graph. Canonical gates use exact uv run --locked --group ... commands. A
purpose-specific workflow may first synchronize a smaller profile with
--no-default-groups, but it then invokes the same Make target without changing
the actual command or flags.
ty==0.0.69 is deliberately exact because the 0.6 work is a reproducible
advisory evaluation, not a floating checker migration. make typecheck-ty
preserves its real exit status in a dedicated nonblocking CI step. Strict mypy,
types-python-dateutil, and pydantic.mypy remain authoritative until every
conditional cutover gate passes. See the
ty advisory evaluation for the current diagnostic
triage, the quality-profile and all-extras counts, and the failed cutover
conditions.
uv_build>=0.12.0,<0.13 belongs to build only as the locked candidate for
the isolated 0.6 backend evaluation. The production [build-system] remains
setuptools.build_meta, and make package plus every release workflow retain
the established setuptools normalization and validation path. From a clean
checkout, make evaluate-uv-build compares both backends under one source
epoch and writes a schema-v1 report; its nonzero incompatible result must not
be masked. The checked uv_build evaluation records
why adoption is rejected/deferred for the candidate configuration.
Provider SDKs remain user-facing optional extras: ollama, openai,
anthropic, gemini, openrouter, and the aggregate all-llm. The Python
test matrix combines test with all-llm for provider coverage. Quality,
security, and build jobs do not install provider extras because their commands
do not import or execute those SDKs. Installing an extra never selects a
provider or grants cloud consent; provider=none remains network-free.
desktop-build remains a user-facing build extra because PyInstaller is part
of the desktop sidecar artifact rather than an ordinary repository tooling
environment. Desktop native build jobs install that extra alone. click is no
longer a direct dependency after source-import and entry-point audits found no
repository consumer; it may still appear transitively in uv.lock. The
verified bootstrap supplies uv, so the lock intentionally contains no direct
uv environment dependency.
Complete dependency-audit export
make dependency-audit executes scripts/run_dependency_audit.py from the
locked security group. The runner generates its input with the exact command
uv export --locked --all-extras --all-groups, then compares normalized
package-name/version pairs with every applicable package in uv.lock before
allowing pip-audit to run. A missing provider extra, desktop-build package,
dependency-group tool, release verifier, or transitive dependency fails closed
instead of silently narrowing the audit.
The closed-schema allowlist at
config/dependency-audit-exclusions.json documents the only formal export
exception: the editable source project itself. Unknown fields, duplicate or
unused entries, unpinned export records, and lock/export drift are stable coded
errors. pip-audit still runs from the locked security group with hashes and
strict dependency processing; this completeness check does not replace
Semgrep, zizmor, CycloneDX, gitleaks, TruffleHog, or CodeQL.
Update procedure
- Edit the narrow direct dependency in
pyproject.toml. Keep application extras separate from repository tooling groups and preserve exact pins for trust-sensitive verifiers. - Run
make lock. This verifies and executes repository-localuv0.12.1 before regenerating the complete lock for all extras and groups. - Run
make lock-check, then inspect both the direct-dependency diff and every changed package record inuv.lock. An unrelated version change, missing artifact hash, alternate source, or unexplained transitive re-resolution is a failure, not routine lockfile noise. - Run the focused dependency-group and workflow contract tests, followed by each affected canonical Make target from a clean environment. Purpose- specific workflow profiles must succeed without tools inherited from another group.
- Run the full applicable quality and security gates and update contributor, CI, security, release, and user installation documentation when the changed dependency affects those surfaces.
The lock-check workflow installs no group and runs make lock-check, whose
canonical command is uv lock --check.
Stock-pip wheel and source-distribution smoke jobs remain intentionally
outside these repository-tool profiles: they verify supported non-uv
consumer installation and do not build or authorize release artifacts.
Review checklist
- Every former development dependency is present in exactly one appropriate group, retained as a named optional extra, or has a documented removal audit.
- Provider extras and
desktop-buildretain their public installation meaning. - Workflow jobs use the group profile declared for their canonical Make target,
pass
--no-default-groups, and invoke that target without command drift. - Semgrep continues through the independently pinned script even though the
surrounding security tools come from the
securitygroup. - The dependency-audit export covers all extras and groups, and its normalized
package pairs match
uv.lockexcept for the reviewed, used source-project entry inconfig/dependency-audit-exclusions.json. - Production release verification installs only
release-verifier; release construction does not inherit it. Full local setup intentionally includes every group. - The complete lock retains artifact hashes for every supported platform and all extras and groups without unexplained package-version movement.
- Application APIs, CLI commands, service DTOs, provider policy, GEDCOM behavior, storage, FastAPI, and Electron boundaries remain unchanged by a tooling-only dependency update.