Repository navigation
chore(deps): allow pillow 13 - #830
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
|
Enabling e.g. Pillow 13 is very relevant to my projects as it would enable better CVE resolution; @joein could you provide any timescales on when this might be feasible? Thanks in advance |
…sory fixes pillow 12.3.0 carries eight advisories fixed only in 13.0.0, and every fastembed release through 0.9.0 caps pillow<13.0. A [tool.uv] override-dependencies entry lifts the cap until fastembed releases qdrant/fastembed#830. Refs #1824 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sory fixes (#1826) ## Closes / Refs Closes #1824 Refs pvliesdonk/fastmcp-server-template#813, #1823 ## What & why CI's `Dependency Audit` fails on #1823 and will fail on `main` on its next run. `pillow` 12.3.0 carries eight new advisories (CVE-2026-112395, -112397, -112400, -112404, -112895, -112896, -112897, -112899), all fixed only in 13.0.0. `pillow` comes in only through `fastembed`, and every `fastembed` release through 0.9.0 caps `pillow<13.0`, so neither Renovate nor `uv lock --upgrade` can reach the fix. The Docker image installs `--extra all`, so the vulnerable `pillow` ships in it. The change: - `[tool.uv] override-dependencies = ["pillow>=13"]` with `# until: #1824`. An override is needed because a constraint would intersect with `<13.0` and resolve to nothing. Upstream qdrant/fastembed#830 raises the cap with no code change, and fastembed's image tests pass on Pillow 13.0.0. `import fastembed` loads Pillow, and it imports cleanly on 13.0.0. This server only uses text embeddings, which never call Pillow. Nothing else in the lock moves. The `certifi` bump this PR first carried (PYSEC-2026-4320) landed on `main` separately in #1828. ## What this PR deliberately does NOT do Nothing beyond the override. The branch is rebased onto `main` at template v11.4.0, whose audit reads the hashed export with `--require-hashes --disable-pip` (pvliesdonk/fastmcp-server-template#814). pip no longer re-resolves the dependencies, so the override no longer causes `ResolutionImpossible`. v11.4.0 also takes the audit out of `CI Success` (pvliesdonk/fastmcp-server-template#816). After this merges, tick the rebase box on #1823. ## Design None. ## Local review - [x] Ran a local self-review of the cumulative diff before `gh pr create`. - [x] No commit carries `!`. Self-review `96992a30..433defa` (after rebasing onto `main` and re-locking), charters: rules, diff, comments, history (normative: none in this change). Coverage: full. Template conformance: no new drift. `check_pins.py`: OK, two pins with open exit conditions. The lock changes one package version, pillow 12.3.0 → 13.0.0. `main`'s audit commands report `No known vulnerabilities found`, and the full suite passes on pillow 13 (6405 passed; one git-lineage test that also fails on a clean `main` locally was deselected). pillow 13.0.0 has cp311–cp314 manylinux wheels for x86_64 and aarch64, which covers the `python:3.14-slim` image. No findings. **Title type is a call for the account holder.** `fix(deps)` cuts a patch release, so the Docker image ships the patched pillow. Precedent for advisory bumps (#1688, #1747) is `chore(deps)`, but those touched nothing that ships. ## Docs impact - [ ] `README.md`: not affected. - [ ] `docs/` site pages: not affected. - [ ] `docs/design/`: not affected. - [ ] Inline docstrings: not affected. - [x] No spec, so no decisions to port. Gates: ruff, mypy and pre-commit pass. `uv run pytest -q` passes (6394 passed, 2 skipped) except `tests/test_git_merge_lineage.py::TestTheBoundaryHoldsAcrossTheMerge::test_a_predecessor_of_the_old_name_stays_out`. That test fails identically on pristine `main` under local git 2.56.0 (CI runs 2.55.0), and it has nothing to do with this change. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- _Agent-authored: written by [Claude Code](https://claude.ai/code) under this account's credentials. Analysis and proposal, not a decision by the account holder._ Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…stls-webpki; Python 3.11 or newer → 3.148.7-alpha (#968) pip-audit and cargo-deny, and with them the required `dependencies` check, have been red on main and on every PR since this week's advisories. This takes all of them in one place. pillow 12.3.0 carries CVE-2026-112895, -112400, -112397, -112896, -112897, -112395, -112404 and -112899, and GitHub lists about forty more advisories published from 2026-10-17, two of them critical (among them heap overflows in the FlashPix and JPEG decoders). All are fixed only in pillow 13.0.0; there is no 12.x after 12.3.0. certifi before 2026.10.19 trusts the emSign ECC Root CA - G3, under which eight eMudhra intermediates have compromised keys (PYSEC-2026-4320, GHSA-6q48-6c7w-9gw2). The same distrust reaches Rust as RUSTSEC-2026-0381 (webpki-roots), RUSTSEC-2026-0382 (rustls-webpki) and RUSTSEC-2026-0383 (webpki-root-certs), all CVE-2026-111943. `cargo update -p` moves rustls-webpki 0.103.15 to 0.103.16 and webpki-roots and webpki-root-certs 1.0.7 to 1.0.10, and nothing else in Cargo.lock. In the sidecar locks certifi moves to 2026.10.19 with every other pin held. Its licence was re-entered by hand after reading the wheel: MPL-2.0, with a LICENSE byte-identical to 2026.7.22's. fastembed 0.9.0, the latest release, still declares pillow<13 on every Python although its code runs on 13 (qdrant/fastembed#830 lifts the cap; open and unmerged). So pillow==13.0.0 also goes in a new sidecar/requirements-override.txt, which `just lock-regen` passes to `uv pip compile --override` for the base lock only and stamps in its header. check-requirements-lock verifies the stamp, and that the file only overrides packages requirements.txt pins at the same version. Remove the override line once a fastembed release allows pillow 13. Because the lock is resolved past that cap, pip's own resolver refuses it, so every install of a lock now passes --no-deps beside --require-hashes: the base and optional-component installs in sidecar.rs, pr.yml's locked-dependency test step and release.yml's python-smoke. Every line is still pinned and hash-checked, and the lock is complete because uv resolved it. `just pip-audit` now audits the hashed locks with --disable-pip instead of installing them; on the old locks it still reports all eight pillow advisories. pillow 13 needs Python 3.11, so MIN_PYTHON goes from 3.10 to 3.11 (3.10 reaches end of life this month). The Windows and Linux installers bundle 3.12, and on a Mac PM uses the machine's Python when it is new enough and downloads its own 3.12 otherwise. So the new floor reaches only a venv an older PM built on a 3.10, which is rebuilt once on the next launch, and from-source development on a machine with nothing newer than 3.10. The setup messages now take the version from MIN_PYTHON. The locks lose the 13 package versions that existed only for Python below 3.11, and tzdata's 3.10 marker. pillow 13.0.0's wheel LICENSE is MIT-CMU plus the permissive licences of its bundled natives, byte-identical to 12.3.0's on Linux and macOS. Hardening, on any pillow: the sidecar opens a photo only as a photo format (JPEG, PNG, WebP, and HEIF once pi-heif has registered it), the one its extension names tried first. A TIFF, FlashPix, EPS or any other format renamed .jpg no longer reaches its decoder, while a PNG or WebP saved as .jpg, or a JPEG saved as .png, still reads. Without pi-heif a .heic is tried as the other three, so a real HEIC is refused and a JPEG saved as .heic still reads; any other extension is refused. The fallback that handed rapidocr the raw path when PM's own open failed is gone, since rapidocr opens a path with no such restriction. With OCR on, the pixels are decoded before the engine loads, so a file cut off halfway comes back with no size (its EXIF kept) and its row blames the file, not text recognition; with OCR off nothing decodes the pixels, as before. The photo's file is closed once it has been read. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…bot #136–#167) (#403) * Raise certifi, pypdf, vitest floors; record the Pillow block (Dependabot #136–#167) - certifi>=2026.10.19 (#138, CRITICAL, newly declared): compromised emSign roots; outbound TLS trust store only. - pypdf>=6.21.1 (#148): needs page.images, which _extract_pdf never calls. LightweightExtractor output byte-identical on 300 real archive PDFs. - vitest ^4.1.12 (#136, #137): dev-only; npm audit clean. - Pillow 13 (29 alerts) is blocked by fastembed's pillow<13 (upstream qdrant/fastembed#830). Left open by operator decision: a spy on PIL.Image.open shows embedded JPEG bytes never reach Pillow on the docling path (pdfium decodes them), under ocrmac and rapidocr. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Session 55 handoff Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Record that certifi does not reach IMAP; name the one emSign root dropped Review follow-up on #403. certifi 2026.10.19 removes only emSign ECC Root CA - G3, and imapclient builds ssl.create_default_context(), so IMAP reads the OS store, which still carries G3 on both hosts. Also name the chai and tinyrainbow lock moves under vitest. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…3, not on the closed #1824 (#1855) ## Closes / Refs Refs #1824 (closed by #1826) and qdrant/fastembed#830. ## What & why Lint (and so CI Success) has failed on `main` since #1826 merged at 0a58c22. `scripts/check_pins.py` reports: > pyproject.toml:301 [tool.uv] override-dependencies 'pillow>=13': outlived its reason — #1824 is resolved; lift the pin #1826 pinned `pillow>=13` "until" #1824, and closed #1824 in the same change. The override is still needed, because every `fastembed` release through 0.9.0 caps `pillow<13`. This PR points the exit condition at the upstream change that removes that need: qdrant/fastembed#830 ("allow pillow 13"), which is open. Once it merges, `check_pins` fails again, which is the reminder to lift the override after a fastembed release carries it. The lock and the pin are unchanged; only the `# until:` URL moves. The same red Lint blocks the #1504 integration PR (#1814), which carries `main`'s pin through its merges of `main`. ## What this PR deliberately does NOT do - Lift the override: fastembed still caps pillow below 13. ## Design None. ## Local review - [x] Ran the `self-reviewing` skill on the cumulative diff before opening this PR. - [x] No commit carries `!`. **Gates:** - `check_pins.py`: OK, with 2 pins whose exit conditions are open. - `tests/test_dependency_pins.py`: 12 passed. - `uv lock --check` and template conformance are clean. - No source or docs change. ## Docs impact - [ ] `README.md`, `docs/`, `docs/design/`, docstrings: not affected. 🤖 Generated with [Claude Code](https://claude.com/claude-code) _Agent-authored: written by [Claude Code](https://claude.ai/code) under this account's credentials. Analysis and proposal, not a decision by the account holder._ Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
fastembed 0.8.0 and 0.9.0 declare pillow<13, so a direct Pillow 13.0.0 pin does not resolve. qdrant/fastembed#830 raises that cap and its image tests pass on Pillow 13, but it is not released. Materialize the official 0.8.0 wheel with only those Requires-Dist caps raised to <14 before pip/uv install. No fastembed code changes. Co-authored-by: Joe McCann <joemccann@users.noreply.github.com>
…nce (#2090) docling 2.142.0 no longer caps pillow<13 (docling-slim, docling-core, docling-parse and docling-ibm-models all allow <14), so the 28 Pillow 12.3.0 advisories accepted in #2083 now have an installable fix. - fastembed (latest 0.9.0) still declares pillow<13.0. Add pillow to [tool.uv] override-dependencies next to oauthlib: fastembed only uses Image.open/new/fromarray and Image.Resampling, and its fromarray(uint8, mode="RGB") calls keep the dtype, so Pillow 13's fromarray change does not affect it. Drop once qdrant/fastembed#830 lands. The published pillow>=12.2.0 floor is unchanged, so installing the embeddings-local extra still resolves. - Pillow 13 needs Python 3.11+. requirements-ci.txt and the .github/requirements files (all 3.11/3.13) are on 13.0.0; uv.lock keeps 12.3.0 for Python 3.10 only. - Regenerate requirements-ci.txt, base-deps, benchmark-extra, explorer-extra-py311/py313, open-ontologies-extra and uv.lock with uv 0.13.4. docling moves 2.135.0 -> 2.142.0 with its family and doclang 0.8.0. benchmark-extra.txt also picks up seven pins that were already stale against requirements-ci.txt. - security-scan.yml: pip-audit only scans requirements-ci.txt and open-ontologies-extra.txt, both now on 13.0.0, so remove the 28 IGNORED_VULN_IDS entries and their expiry gate. - osv-scanner.toml: keep the 28 ignores, narrowed to the 3.10-only uv.lock entry, until 3.10 support is dropped. - ImageParser.preprocess_image: Pillow 13 refuses to write 32-bit "I" images as PNG (12.x clipped them silently). Convert to I;16 first and drop "I" from PNG_MODES. Regression test included; it fails on Pillow 13 without the fix. Refs #2067
generall
left a comment
There was a problem hiding this comment.
Verified locally: lock is consistent, image/multimodal tests pass on Pillow 13.0.0. CI green on all matrix jobs. Thanks!
|
Thanks for the merge and the version bump! |
…eat-232) (#234) * docs(feat-232): expand plan for the 2026-10-24 re-scan cohort (REQ-004, Phase 105, workflow override) The 06:04Z Dependabot re-scan created 51 new alerts (62 open total: 41 pillow, 15 virtualenv, 3 filelock, 1 certifi, 1 opentelemetry-api, 1 stale uv). User-approved scope expansion (option A): new REQ-004 / ACC-004 + Phase 105 for the lock-only virtualenv/filelock/ opentelemetry-api bump, REQ-003/ACC-003 re-scoped to the full 62-alert population, snapshot annotated (pre-rescan 11-alert cohort preserved), and the workflow override recorded (one local commit per phase, no push/merge until wrap-up, no upstream posting on fastembed#829). * chore(deps): bump certifi 2026.7.22 → 2026.10.23 (feat-232 Phase 100) Lock-only bump via 'uv lock --upgrade-package certifi'; the lock diff is confined to the certifi package entry (REQ-001, fixes Dependabot alert 29, GHSA-6q48-6c7w-9gw2, critical — emSign root CA compromise). Gate green: uv sync --frozen --all-extras, ruff format --check, ruff check, and the full default pytest suite (4759 passed, 18 skipped). Alert closure is expected on merge + Dependabot re-scan per the plan's workflow override. * docs(feat-232): record Phase 105 documented exception (resolver-forced packaging 26.2 → 26.3, user-approved) Every virtualenv >= 21.14.9 (REQ-004's compliant range) declares packaging>=26.3 while the lock carried 26.2, so the Phase 105 bump deterministically forces packaging 26.2 -> 26.3 (a new virtualenv -> packaging edge). User decision (Option 1): accept the forced move as a documented exception to Task 105.100's 'nothing else moved' invariant — packaging 26.3 is the latest release, outside the 62-alert population, with zero resolution conflicts across the 120-package graph. Option 2 (de-scope virtualenv, leaving 15 alerts open) rejected. Phase 105 re-runs under the corrected invariant. * chore(deps): bump virtualenv, filelock, opentelemetry-api (feat-232 Phase 105) Lock-only bump via 'uv lock --upgrade-package virtualenv --upgrade-package filelock --upgrade-package opentelemetry-api': virtualenv 21.7.13 → 21.14.13, filelock 3.32.2 → 4.2.4, opentelemetry-api 1.44.0 → 1.45.1 (REQ-004; fixes the 19 Dependabot alerts 39–42/62–64/77/81–87 virtualenv, 80/88/89 filelock, 75 opentelemetry-api). Includes the documented, user-approved, resolver-forced packaging 26.2 → 26.3 move (new virtualenv → packaging edge; every virtualenv >= 21.14.9 declares packaging>=26.3 — see Decisions Made in the feat plan). Gate green: uv sync --frozen --all-extras, ruff format --check, ruff check, full default pytest suite (4759 passed, 18 skipped) and the opt-in 'pytest -m embedding_model' real-backend test (3 passed). Alert closure expected on merge + Dependabot re-scan per the plan's workflow override. * docs(feat-232): record Phase 110 tracking — fastembed#830 still open, no unblocking release Task 110.100 re-verification (read-only, no upstream posting per the workflow override): qdrant/fastembed#830 remains open/unmerged (updated 2026-10-20), and the latest fastembed release (0.9.0, 2026-10-07) still caps pillow <13.0 on every Python-version marker, so Task 110.110's 'On release' condition is unmet. Tasks 110.110/ 110.120 stay open; the 41 pillow alerts remain under the recorded risk acceptance (stall contingency checked, not triggered). No lock change this phase. * docs(feat-232): record Phase 120 final verification — alert disposition, monitored branch (dev) Open-alerts query (2026-10-24T12:16Z): 62 open, unchanged — 20 fixed on this branch (1 certifi, 15 virtualenv, 3 filelock, 1 opentelemetry-api) pending merge to dev + Dependabot re-scan; 41 pillow blocked on qdrant/fastembed#830 under the recorded risk acceptance; 1 stale uv alert (#28) — dev already carries 0.13.4 via #226, closes on re-scan, no repo change needed. Monitored branch confirmed: dependabot.yml has no target-branch key, repo default is dev. ACC-001 and ACC-004 checked off as met; ACC-002/ACC-003 remain open (upstream block / pending merge + re-scan). * docs(feat-232): set status to review All executable phases complete (100 certifi, 105 virtualenv/filelock/ opentelemetry-api, 110 tracking, 120 final verification); ACC-001 and ACC-004 met. ACC-002/ACC-003 remain open pending the upstream fastembed release and the merge + Dependabot re-scan, as recorded in the plan. Feature is ready for review. * docs(feat-232): apply post-implementation review corrections (D1–D4, I2; D5 confirmed accurate) feat-reviewer pass on PR #234 found no functional defects; corrected five documentation-accuracy items in the recorded evidence: D1 — the uv advisory (GHSA-hq85-5cpj-mr62) does name first-patched 0.13.4 (verified via the alerts API), fixing two spans; D2 — the risk-accept entry's cited grep was a non-reproducible substring match, corrected to the anchored import-form grep (re-verified: no PIL imports in src//tests/); D3 — the 'no PIL import in fastembed 0.8.0 source' claim was wrong (six modules import PIL, transitively loaded by 'import fastembed'); corrected with the no-exposure conclusion explicitly preserved (TextEmbedding-only usage); D4 — the second-refiner entry heading was mislabeled UTC (08:38:00.000Z); I2 — Task 110.100's stale '9 advisories' count updated to 41 with the waived comment made explicit. D5 required no change (recorded xdist summary quotes are verbatim-accurate). Full accounting in the new post-review Updates entry. * docs(feat-232): apply refiner round-3 corrections (D1-D3, G2, I1-I3); carve pillow cohort out to issue #235 (G1)
…ow 13 (#1884) ## Closes / Refs Refs #1824 (closed): the pillow advisories that #1826 added the override for. This PR covers #1882's fastembed bump too, so Renovate's PR can be closed once this merges. ## What & why `scripts/check_pins.py` now fails Lint on every branch. The override's exit condition was qdrant/fastembed#830, which merged today and shipped in fastembed 0.9.1 at 18:32 UTC. - **Removed:** the `pillow>=13` override and its comment, from `[tool.uv]`. - **`uv.lock`:** fastembed goes from 0.9.0 to 0.9.1, and pillow stays at 13.0.0 without the override. ## Local review - [x] Ran the `self-reviewing` skill: no findings. - [x] `check_pins.py` passes, and so do `tests/test_dependency_pins.py` and `tests/test_providers.py` (85 passed). - [x] After `uv sync --all-extras`, `import fastembed, PIL` gives 0.9.1 and 13.0.0. ## Docs impact - [x] None: only a lock pin. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Qa5csDmuTKjXcgRVXmtUEU _Agent-authored: written by [Claude Code](https://claude.ai/code) under this account's credentials. Analysis and proposal, not a decision by the account holder._
…ation) (#427) ## Summary Delivers the Pillow items of the 2026-W44 release scope recorded in #426 (items 1 and 3, `Pillow`/`pillow` to 13.0.0, critical, due 2026-10-26 12:48 UTC; accepted by default under the operator's ruling of 2026-10-25) into `release/new`. The other #426 items (certifi, filelock, opentelemetry-api, fastmcp, fastmcp-slim, setuptools) are delivered by the lane's own lockfile step, per the controller's scope ruling; this PR leaves their locked versions as on `release/new`. | Package | Locked before | Locked after | | --- | --- | --- | | pillow | 12.3.0 | 13.0.0 | | fastembed (enabler) | 0.8.1 | 0.9.1 | No other locked version changes. Regenerated from the `release/new` lock with the repository's pinned uv 0.12.23 (the Dockerfile pin; there is no `mise.toml`) via `uv lock --upgrade-package fastembed==0.9.1 --upgrade-package pillow==13.0.0`; the lock moves from revision 3 to 5. ## Why fastembed moves fastembed 0.8.x and 0.9.0 declare `pillow<13.0`; 0.9.1 (2026-10-24, qdrant/fastembed#830 "allow Pillow 13") is the smallest release that allows it. The `embeddings` and `dev` extras move from `fastembed>=0.8,<0.9` to `fastembed>=0.9.1,<0.10`. Maturity (SDLC 13.2): the 0.9 minor line went stable with 0.9.0 on 2026-10-07, 18 days ago, so the 14-day minor wait is met; 0.9.1 is a patch within that line (no wait). Its own one-day age is accepted on the expedited security path (SDLC 13.2 last paragraph and 12.2: 41 Pillow alerts, 5 critical, deadline 2026-10-26 12:48 UTC), with review and validation preserved. Compatibility: data-olympus calls only `TextEmbedding(model_name=...)` and `.embed(...)` (`src/data_olympus/embeddings.py`), both unchanged in 0.9. The upgrade note that touches us: built-in models download from Hugging Face only (cached GCS copies still load with a `FutureWarning`). No code change was needed. The container image installs neither extra: its no-dev package set (`uv export --no-dev`) is identical before and after; neither changed package is in it. ## Alerts closed - Pillow: #27 #28 #29 #30 #32 #33 #35 #37 #38 #39 #42 #44 #45 #46 #47 #48 #49 #51 #52 #54 #55 #56 #59 #60 #62 #63 #64 #65 #71 - pillow: #31 #34 #40 #41 #43 #50 #53 #57 #58 #61 #67 #72 That is 41 alerts, 28 of them critical or high. The remaining 2 critical/high of the 30 (#36 certifi, #73 filelock) are in the lane's lockfile step. ## Evidence - grype 0.119.0 (checksum-verified; the release checksum file matches the workflow's pinned linux sha) on `uv.lock`: base `8a234cb` 6 critical, 24 high, 16 medium, 3 low; this head has 0 pillow matches, and the only remaining matches are the lane's items (certifi 1 critical, filelock 1 high and 2 low, fastmcp, fastmcp-slim, opentelemetry-api 1 medium each, setuptools 1 low). - `uv run mypy src`: no issues in 81 files; `uv run ruff check .`: clean; `scripts/check_changelog.py`: ok; prose lint: clean. - Embedding tests (`tests/test_embeddings*.py`): pass. Real model smoke with fastembed 0.9.1: `build_embedder` on `BAAI/bge-small-en-v1.5` returns 384-dim L2-normalised vectors. - Full `uv run pytest`: see the comment below. ## Type of change - [x] Tool / code change (dependency lock) ## Checklist - [x] Base is `release/new` - [x] Conventional Commit title (`fix(deps)`) - [x] `CHANGELOG.md` `[Unreleased]` Security entry - [x] `ruff` reports no errors - [x] No em-dashes in added prose - [x] No credentials or secrets committed Refs #426
# Release 0.11.4 ## Fixes - fix(release): record scoped exceptions for the libexpat1 findings (#433) Refs #426. - fix(deps): lock certifi 2026.10.19 to remediate a security alert (#432) Locks certifi 2026.10.19 (was 2026.7.22) to remediate Dependabot alert #36 (critical, SDLC 12.2 deadline 2026-10-27 03:52 UTC). Scope record #426 item 2. Only the certifi [[package]] block in uv.lock changes (version, sdist and wheel URLs, sha256 hashes, sizes, upload times). Produced with uv 0.12.23, the version pinned in deploy/docker/Dockerfile, via `uv lock --upgrade-package certifi==2026.10.19`. - fix: bump setuptools to 84.1.0 to remediate a security advisory (#431) <!-- lane-develop repo=knaisoma/data-olympus cycle=2026-W44 item=8 --> Developed by the weekly SDLC lane from the release scope the operator confirmed in the lane session. The lane never merges: the operator does, after green CI and an independent review bound to the head. - Scope record: [#426](#426) (2026-W44), item 8: mandatory, security remediation: **low**, due 2027-01-22 03:53 UTC: `pip` `setuptools` in `uv.lock`; fixed in `84.1.0`; 1 alert(s), first [#70](https://github.com/knaisoma/data-olympus/security/dependabot/70); open Dependabot PR [#423](#423) - Acceptance: every listed alert closes as fixed on the release candidate, and the candidate's vulnerability gate passes - Base: `release/new` at `178a5dc089b447b0196151d433d664d5c9e9efe1`; head `a8a11e3e4b71b5900b88ddebc435d1c43716f3f6`. - Local checks: static only (reserved paths, symlinks, whitespace, Python syntax); the lane does not run the code it wrote, CI does. - Review: STD-U-604 reviewer verdicts are posted below as comments bound to a head. Lane notes (written by the lane; data): ~~~~text Regenerates uv.lock with setuptools upgraded to 84.1.0, the first patched version named by the open Dependabot alert on uv.lock. Only the setuptools record changes, with every artifact from PyPI carrying a sha256. Once this reaches the release candidate the alert closes as fixed, which is the item's acceptance; the candidate's vulnerability gate confirms it. ~~~~ - fix: bump fastmcp to 3.4.10 to remediate a security advisory (#430) <!-- lane-develop repo=knaisoma/data-olympus cycle=2026-W44 item=6 --> Developed by the weekly SDLC lane from the release scope the operator confirmed in the lane session. The lane never merges: the operator does, after green CI and an independent review bound to the head. - Scope record: [#426](#426) (2026-W44), item 6: mandatory, security remediation: **medium**, due 2026-11-23 03:53 UTC: `pip` `fastmcp` in `uv.lock`; fixed in `3.4.10`; 1 alert(s), first [#68](https://github.com/knaisoma/data-olympus/security/dependabot/68); open Dependabot PR [#421](#421) - Acceptance: every listed alert closes as fixed on the release candidate, and the candidate's vulnerability gate passes - Base: `release/new` at `178a5dc089b447b0196151d433d664d5c9e9efe1`; head `f1976a4378f0a7df6941ea196e0842a4b93b257b`. - Local checks: static only (reserved paths, symlinks, whitespace, Python syntax); the lane does not run the code it wrote, CI does. - Review: STD-U-604 reviewer verdicts are posted below as comments bound to a head. Lane notes (written by the lane; data): ~~~~text Regenerates uv.lock with fastmcp upgraded to 3.4.10, the first patched version named by the open Dependabot alert on uv.lock. Only fastmcp and records of its own dependencies at the target version change, with every artifact from PyPI carrying a sha256. Once this reaches the release candidate the alert closes as fixed, which is the item's acceptance; the candidate's vulnerability gate confirms it. ~~~~ - fix: bump opentelemetry-api to 1.45.1 to remediate a security advisory (#429) <!-- lane-develop repo=knaisoma/data-olympus cycle=2026-W44 item=5 --> Developed by the weekly SDLC lane from the release scope the operator confirmed in the lane session. The lane never merges: the operator does, after green CI and an independent review bound to the head. - Scope record: [#426](#426) (2026-W44), item 5: mandatory, security remediation: **medium**, due 2026-11-23 03:53 UTC: `pip` `opentelemetry-api` in `uv.lock`; fixed in `1.45.1`; 1 alert(s), first [#66](https://github.com/knaisoma/data-olympus/security/dependabot/66); open Dependabot PR [#422](#422) - Acceptance: every listed alert closes as fixed on the release candidate, and the candidate's vulnerability gate passes - Base: `release/new` at `178a5dc089b447b0196151d433d664d5c9e9efe1`; head `5007f2464e4e17d444baa3ccf759fc59b3bd8449`. - Local checks: static only (reserved paths, symlinks, whitespace, Python syntax); the lane does not run the code it wrote, CI does. - Review: STD-U-604 reviewer verdicts are posted below as comments bound to a head. Lane notes (written by the lane; data): ~~~~text Regenerates uv.lock with opentelemetry-api upgraded to 1.45.1, the first patched version named by the open Dependabot alert on uv.lock. Only the opentelemetry-api record changes, with every artifact from PyPI carrying a sha256. Once this reaches the release candidate the alert closes as fixed, which is the item's acceptance; the candidate's vulnerability gate confirms it. ~~~~ - fix: lock filelock at 4.2.1 to remediate security alerts (#428) <!-- lane-develop repo=knaisoma/data-olympus cycle=2026-W44 item=4 --> Developed by the weekly SDLC lane from the release scope the operator confirmed in the lane session. The lane never merges: the operator does, after green CI and an independent review bound to the head. - Scope record: [#426](#426) (2026-W44), item 4: mandatory, security remediation: **high**, due 2026-10-31 03:53 UTC: `pip` `filelock` in `uv.lock`; fixed in `4.2.1`; 3 alert(s), first [#73](https://github.com/knaisoma/data-olympus/security/dependabot/73); open Dependabot PR [#425](#425) - Acceptance: every listed alert closes as fixed on the release candidate, and the candidate's vulnerability gate passes - Base: `release/new` at `dbbfc297aa89328f3a18b1c0d90d1b4b60ca8e98`; head `3536eb0139e46ef1fd28be654b6748cdbe3291f9`. - Local checks: static only (reserved paths, symlinks, whitespace, Python syntax); the lane does not run the code it wrote, CI does. - Review: STD-U-604 reviewer verdicts are posted below as comments bound to a head. Lane notes (written by the lane; data): ~~~~text Regenerates uv.lock with filelock upgraded to 4.2.1, the first patched version named by the Dependabot alerts of this item (first #73). Only uv.lock changes; the resolution stayed within the existing pyproject.toml bounds and every artifact comes from PyPI with a sha256. This meets the acceptance once the release candidate is built: the listed alerts close as fixed and the candidate's vulnerability gate passes. Note that filelock moves from 3.x to 4.x, so CI must confirm compatibility. ~~~~ - fix(deps): lock pillow 13.0.0 with fastembed 0.9.1 (W44 Pillow remediation) (#427) ## Summary Delivers the Pillow items of the 2026-W44 release scope recorded in #426 (items 1 and 3, `Pillow`/`pillow` to 13.0.0, critical, due 2026-10-26 12:48 UTC; accepted by default under the operator's ruling of 2026-10-25) into `release/new`. The other #426 items (certifi, filelock, opentelemetry-api, fastmcp, fastmcp-slim, setuptools) are delivered by the lane's own lockfile step, per the controller's scope ruling; this PR leaves their locked versions as on `release/new`. | Package | Locked before | Locked after | | --- | --- | --- | | pillow | 12.3.0 | 13.0.0 | | fastembed (enabler) | 0.8.1 | 0.9.1 | No other locked version changes. Regenerated from the `release/new` lock with the repository's pinned uv 0.12.23 (the Dockerfile pin; there is no `mise.toml`) via `uv lock --upgrade-package fastembed==0.9.1 --upgrade-package pillow==13.0.0`; the lock moves from revision 3 to 5. ## Why fastembed moves fastembed 0.8.x and 0.9.0 declare `pillow<13.0`; 0.9.1 (2026-10-24, qdrant/fastembed#830 "allow Pillow 13") is the smallest release that allows it. The `embeddings` and `dev` extras move from `fastembed>=0.8,<0.9` to `fastembed>=0.9.1,<0.10`. Maturity (SDLC 13.2): the 0.9 minor line went stable with 0.9.0 on 2026-10-07, 18 days ago, so the 14-day minor wait is met; 0.9.1 is a patch within that line (no wait). Its own one-day age is accepted on the expedited security path (SDLC 13.2 last paragraph and 12.2: 41 Pillow alerts, 5 critical, deadline 2026-10-26 12:48 UTC), with review and validation preserved. Compatibility: data-olympus calls only `TextEmbedding(model_name=...)` and `.embed(...)` (`src/data_olympus/embeddings.py`), both unchanged in 0.9. The upgrade note that touches us: built-in models download from Hugging Face only (cached GCS copies still load with a `FutureWarning`). No code change was needed. The container image installs neither extra: its no-dev package set (`uv export --no-dev`) is identical before and after; neither changed package is in it. ## Alerts closed - Pillow: #27 #28 #29 #30 #32 #33 #35 #37 #38 #39 #42 #44 #45 #46 #47 #48 #49 #51 #52 #54 #55 #56 #59 #60 #62 #63 #64 #65 #71 - pillow: #31 #34 #40 #41 #43 #50 #53 #57 #58 #61 #67 #72 That is 41 alerts, 28 of them critical or high. The remaining 2 critical/high of the 30 (#36 certifi, #73 filelock) are in the lane's lockfile step. ## Evidence - grype 0.119.0 (checksum-verified; the release checksum file matches the workflow's pinned linux sha) on `uv.lock`: base `8a234cb` 6 critical, 24 high, 16 medium, 3 low; this head has 0 pillow matches, and the only remaining matches are the lane's items (certifi 1 critical, filelock 1 high and 2 low, fastmcp, fastmcp-slim, opentelemetry-api 1 medium each, setuptools 1 low). - `uv run mypy src`: no issues in 81 files; `uv run ruff check .`: clean; `scripts/check_changelog.py`: ok; prose lint: clean. - Embedding tests (`tests/test_embeddings*.py`): pass. Real model smoke with fastembed 0.9.1: `build_embedder` on `BAAI/bge-small-en-v1.5` returns 384-dim L2-normalised vectors. - Full `uv run pytest`: see the comment below. ## Type of change - [x] Tool / code change (dependency lock) ## Checklist - [x] Base is `release/new` - [x] Conventional Commit title (`fix(deps)`) - [x] `CHANGELOG.md` `[Unreleased]` Security entry - [x] `ruff` reports no errors - [x] No em-dashes in added prose - [x] No credentials or secrets committed Refs #426 ## Other changes - docs(releases): release/new and hotfix/new carry no linear history rule (#418) ## Summary Operator ruling 2026-10-20: only `main` requires linear history. `release/new` and `hotfix/new` may be rebased onto `main` or recreated at it, and their history rewritten, with no ruleset change. `main` stays linear because `release/new` is squash-merged into it. The owner's linear-history toggle around a recut is retired. Documentation only: - `docs/releases/repository-settings.md` section 5.2: `w10-release-branches` has no linear history rule and needs no toggle. Required checks are still enforced on creation. The pull request rule refuses a direct update, so the recut deletes and recreates the branch. - `docs/releases/branch-recut.md`: the ruleset section no longer describes a toggle. - `docs/releases/adoption-cut-runbook.md`: lesson 6 is marked superseded. Code is unchanged. `scripts/sdlc_recut.py` and `.github/workflows/recut-release-branch.yml` never touch rulesets, so neither assumes the toggle. ## Live state The desired state is company-knowledge PR 299 (merge `480a2b3`). It was applied on 2026-10-20 to ruleset 24749294, whose rules now read back as `pull_request` and `required_status_checks` with enforcement `active`. `main protection` (18080131) still has `required_linear_history`.
fastembed 0.9.1 lifts its pillow<13 cap (qdrant/fastembed#830), so pillow can move to 13.0.0. docling releases before 2.142.0 also cap pillow below 13, so the docling extra's floor rises to the locked 2.142.1.
Raises the pillow cap to
<14.0; image tests pass on Pillow 13.0.0. Closes #829.