ADR-0879: Python dependency freshness sweep (2026-05-30)¶
- Status: Accepted
- Date: 2026-05-30
- Deciders: Lusoris
- Tags: security, ai, mcp, deps, python, fork-local
Context¶
The fork ships eight pyproject.toml files (ai/, mcp-server/vmaf-mcp/, dev-llm/, tools/vmaf-tune/, tools/vmaf-roi-score/, tools/ensemble-training-kit/, plus the two harness shims at the repo root and under python/) and four requirements*.txt files. Their floor pins drift slowly relative to PyPI: a package that was at-latest when a tree was authored is rarely at-latest a few weeks later, and the fork's deliverables-bar (ADR-0108) does not require a periodic refresh on its own.
This sweep audits every fork-local Python dep file against PyPI's current info.version and bumps the floors that are behind the latest published release. The goal is floor freshness, not exact pinning — consumers who want pristine determinism use the dedicated requirements-frozen.txt artefact already shipped under tools/ensemble-training-kit/ (ADR-0324).
Findings:
- Most floors were already at-latest (numpy, pandas, scipy, torch, onnxruntime, transformers, etc. — the 2026-vintage tree mostly tracks PyPI within hours of release).
- A small cluster of dev / cloud / agent-SDK deps had drifted one minor or patch behind:
typer(0.25.1 → 0.26.4),ruff(0.15.14 → 0.15.15),anthropic(0.104.1 → 0.105.2),openai(2.37.0 → 2.38.0),pytorch-lightning(2.6.4 → 2.6.5),mcp(1.27.1 → 1.27.2),pytest-asyncio(1.3.0 → 1.4.0),pandas-stubs(3.0.0.260204 → 3.0.3.260530),pytest-cov(unpinned → ≥7.1.0). tools/vmaf-tune/pyproject.tomlcarried a major-version stale floor on the dev extra —optuna>=3.6while thefastextra (the actual user- facing path) already requiresoptuna>=4.8.0. Aligned the dev extra to the same 4.x floor so dev installs match the runtime path.- No
requirements*.txtfile currently uses--hash=sha256:pinning. The audit considered switching topip-compile --generate-hashesbut defers that to a follow-up because the immediate value (floor-freshness against PyPI today) is independent of the hash-pinning question and the latter warrants its own deliverables cycle (lockfile placement, CI gate, refresh cadence, ADR — none of which fit a single drive-by sweep).
Decision¶
Bump the eight pin sites identified above to their PyPI-latest floors as of 2026-05-30. Defer hash-pinning to a separate ADR + PR. Do not change any major-version constraint ceilings (<3.0, <2.0, etc.) — those encode known incompatibilities and are not part of this freshness sweep.
Alternatives considered¶
| Option | Pros | Cons | Why not chosen |
|---|---|---|---|
Bump floors + add --hash=sha256: to every requirements*.txt in one PR | Single security touch | Cross-cuts lockfile policy (cadence, CI gate, refresh tooling); turns a 9-line bump into a ~600-line lockfile-and-process PR | Hash pinning is a policy decision worth its own ADR cycle |
Switch all >= floors to == exact pins | Bit-reproducible installs | Pyproject == pins fight the user's local environment + conflict with sibling tools; the fork already has requirements-frozen.txt for that need | Exact pins are a deployment concern, not a library concern |
| Skip the sweep, let Renovate file PRs piecemeal | Lower-touch | Renovate already runs but the fork's many small pyproject.toml files generate noisy individual PRs; a periodic sweep batches them | Renovate stays valuable for between-sweep coverage; the sweep complements rather than replaces it |
Add ceiling bumps too (<3.0 → <4.0) | Forward-compat | Ceilings encode tested compatibility; bumping a ceiling without testing the new major is the actual security risk | Ceiling moves require validation runs, out of scope here |
Consequences¶
- Positive: Eight floors now match PyPI latest. Dev installs of
tools/vmaf-tunepull a contemporary Optuna instead of a 2-year-old 3.6.x. Thedev-llmcloud extra picks up the current Anthropic / OpenAI SDKs (1 minor release of bug fixes each). - Negative: Anyone with a
pip install -e .[dev]cache from the last ~week will see a fresh wheel resolve. No API breaks expected at this granularity. - Neutral / follow-ups: Hash-pinning lockfiles for the three install- facing requirements files (
python/requirements.txt,docs/requirements.txt,tools/ensemble-training-kit/requirements-frozen.txt) deserve a dedicated ADR + PR.
References¶
- ADR-0108: deep-dive deliverables rule (this sweep ships the full six).
- ADR-0221: changelog fragments under
changelog.d/. - ADR-0324: ensemble-training-kit frozen requirements (the prior art for hash-style exact pinning in the fork).
- Audit dossier:
docs/research/python-dep-freshness-2026-05-30.md. - Source: agent task brief (paraphrased: audit Python
pyproject.tomlfiles andrequirements*.txtfor outdated deps + missing hash pinning).