Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .agent-eval/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ offline. No grader calls an LLM.

Every code task also gets these metrics:
- `regress_pass`: the whole suite, except timing- and process-sensitive tests: all of
`test_example_runner_processes.py` (4 tests, 7 cases) and 2 single tests (`REGRESSION` in `run.py`)
`test_example_runner_processes.py` (4 tests, 7 cases) and 2 single tests (`REGRESSION` in `run.py`),
and the real ragas import check, which needs the `[ragas]` extra the image does not install
- `ruff_ok`, `mypy_ok`, `config_ok`, `schema_ok`
- `compat_ok`: `schema_compat` against the start commit
- `diffcov_*`: CI's changed-line coverage gate
Expand Down
5 changes: 4 additions & 1 deletion .agent-eval/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@
"regress_pass": ["python", "-m", "pytest", "-q", "-p", "no:cacheprovider", "-x",
"--deselect", "tests/test_example_runner_processes.py",
"--deselect", "tests/test_container_agent.py::test_probe_finds_a_proxy_that_forwards_plain_http",
"--deselect", "tests/test_benchflow_harness.py::test_run_bench_kills_the_process_group_on_timeout"],
"--deselect", "tests/test_benchflow_harness.py::test_run_bench_kills_the_process_group_on_timeout",
# Needs the [ragas] extra, which the image (built from the lock) leaves out;
# task bases older than its skip-when-missing would fail it.
"--deselect", "tests/test_ragas_runtime.py::test_ragas_imports_and_evaluator_builds_from_installed_deps"],
"ruff_ok": ["ruff", "check", "."],
"mypy_ok": ["mypy"],
"config_ok": ["python", "-m", "dokimi.config_check"],
Expand Down
17 changes: 11 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ defaults:
working-directory: dokimi

# Single-version jobs (here, in agent-quality.yml, docs.yml and
# stack-health.yml) and `make dev` use Python 3.13, not 3.14: scikit-network
# (pulled in by ragas) has no cp314 wheels yet, so on 3.14 every install builds
# it from source (C++ with OpenMP, unpinned build deps); the pip cache keeps the
# built wheel for the 3.14 test leg. Move them to 3.14 once scikit-network ships
# cp314 wheels.
# stack-health.yml) and `make dev` use Python 3.13, not 3.14. The reason was
# scikit-network, which has no cp314 wheels yet, so on 3.14 an install builds it
# from source (C++ with OpenMP, unpinned build deps). Only the `[ragas]` extra
# pulls it in now, not the locks: test-latest installs the extra and stays on
# 3.13 until scikit-network ships cp314 wheels; the other jobs could move.
jobs:
# The checks that need no dependency lock, in one job: each takes seconds, and
# as separate jobs each waited for a runner of its own. Every step after the
Expand Down Expand Up @@ -393,9 +393,14 @@ jobs:
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: '3.13'
# The `[ragas]` extra is not in requirements.txt or the lock; this job is
# where `eval ragas` runs on real packages, and DOKIMI_REQUIRE_RAGAS=1 makes
# tests/test_ragas_runtime.py fail rather than skip if ragas is missing.
- name: Install newest allowed deps
run: pip install --upgrade -r requirements.txt -r requirements-test.txt
run: pip install --upgrade -r requirements.txt -r requirements-test.txt -e '.[ragas]'
- name: Run tests
env:
DOKIMI_REQUIRE_RAGAS: '1'
run: pytest -q -n auto

# Installs the built package with a fresh resolve of its dependency ranges, not
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/pip-audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ jobs:
| awk -F'==' '/^[A-Za-z0-9]/ { print > (ENVIRON["RUNNER_TEMP"] "/pins" seen[$1]++ ".txt") }'
for f in "$RUNNER_TEMP"/pins*.txt; do
pip-audit -r "$f" --no-deps --disable-pip --progress-spinner off \
--ignore-vuln PYSEC-2026-2447 \
--ignore-vuln PYSEC-2026-3046 \
--ignore-vuln GHSA-v4x8-3wr5-3wq8 \
--ignore-vuln GHSA-9vhv-jxww-xfm5 \
--ignore-vuln GHSA-567q-5qvw-pf92
Expand Down
2 changes: 1 addition & 1 deletion dokimi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ BASE ?= baselines/baseline.json

# `make dev` venv: at the repo root, outside this directory, so `bandit -r .`
# and the docs benchmark (both run from here) do not scan it. CI's Python:
# 3.13 until scikit-network ships cp314 wheels (see the top of ci.yml). An
# 3.13 (see the top of ci.yml). An
# existing venv on another Python is converted in place by re-running `make dev`.
VENV ?= ../.venv
PYTHON_VERSION ?= 3.13
Expand Down
35 changes: 20 additions & 15 deletions dokimi/SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,6 @@ The project is pre-1.0; only the latest `main` is supported. Fixes land on
`requirements-docs.lock.txt` and `requirements-ci.lock.txt`) reports these advisories with no
fix the locks can take:

- **diskcache 5.6.3 — PYSEC-2026-2447** (CVE-2025-69872, GHSA-w8v5-vhqr-4h9v;
pickle deserialization from a cache directory). Pulled in only by ragas,
which imports it inside its opt-in `DiskCacheBackend`; Dokimi never
constructs one, so no diskcache directory is created or read.
- **ragas 0.3.9 — PYSEC-2026-3046** (CVE-2026-6587, GHSA-95ww-475f-pr4f; SSRF
and file read in the multi-modal faithfulness metric's loader). The
advisory's range is 0.2.3–0.4.3, but the vulnerable module
(`ragas/metrics/collections/multi_modal_faithfulness/util.py`) first ships
in 0.4.2, so the pinned 0.3.9 does not contain it. A fixed release would be
0.4.4 or later, which is outside the `ragas<0.4` cap: taking it means lifting
the cap and migrating, not a bump, and 0.4.2–0.4.3 must be skipped.
- **filelock 3.32.7 — GHSA-v4x8-3wr5-3wq8, GHSA-9vhv-jxww-xfm5,
GHSA-567q-5qvw-pf92** (CVE-2026-112940, CVE-2026-112913, CVE-2026-112907;
fixed in 4.2.1). Every litellm release requires `filelock<4.0`, so 4.2.1
Expand All @@ -71,15 +60,31 @@ fix the locks can take:
to dataset and model downloads on a shared Windows host. Drop all three when
litellm allows `filelock>=4.2.1`.

The locks do not contain ragas: it is the optional `[ragas]` extra (`eval ragas`,
`answers generate --ragas`), which installs ragas 0.3.9 and diskcache 5.6.3. Their
advisories do not affect Dokimi:

- **diskcache 5.6.3 — PYSEC-2026-2447** (CVE-2025-69872, GHSA-w8v5-vhqr-4h9v;
pickle deserialization from a cache directory). Pulled in only by ragas,
which imports it inside its opt-in `DiskCacheBackend`; Dokimi never
constructs one, so no diskcache directory is created or read.
- **ragas 0.3.9 — PYSEC-2026-3046** (CVE-2026-6587, GHSA-95ww-475f-pr4f; SSRF
and file read in the multi-modal faithfulness metric's loader). The
advisory's range is 0.2.3–0.4.3, but the vulnerable module
(`ragas/metrics/collections/multi_modal_faithfulness/util.py`) first ships
in 0.4.2, so 0.3.9 does not contain it. A fixed release would be
0.4.4 or later, which is outside the `ragas<0.4` cap: taking it means lifting
the cap and migrating, not a bump, and 0.4.2–0.4.3 must be skipped.

The `ragas>=0.3.0` floor keeps out 0.2.3–0.2.x, which are affected by
CVE-2025-45691 (GHSA-v2xr-wvrv-p969, file read through `retrieved_contexts`,
fixed in 0.3.0).

`.github/workflows/pip-audit.yml` runs `pip-audit` with exactly these IDs
ignored, on every PR or push that changes a lock or requirements file and daily
`.github/workflows/pip-audit.yml` runs `pip-audit` against the locks with exactly
the three filelock IDs ignored, on every PR or push that changes a lock or requirements file and daily
on `main`; a daily run that finds a new advisory opens an issue rather than
failing unrelated PRs. The `static` job in `.github/workflows/ci.yml` runs
`bandit -ll` with no Medium or High finding allowed.
The same IDs are ignored by osv-scanner through `dokimi/osv-scanner.toml`,
which OpenSSF Scorecard runs. A removed advisory comes out of this section,
the `pip-audit` step, and that file together.
which OpenSSF Scorecard runs. A removed advisory comes out of the first list
above, the `pip-audit` step, and that file together.
9 changes: 9 additions & 0 deletions dokimi/changelog.d/20261027_000000_cve_ragas_fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
### Security

- **The CI and development lock no longer contains ragas, the langchain packages or
diskcache**, which clears CVE-2025-69872 (diskcache, PYSEC-2026-2447) and CVE-2026-6587
(ragas, PYSEC-2026-3046) from the locks (`requirements.lock.txt` was the only one with
them), so `pip-audit` no longer has to ignore them. `pip install dokimi` was already free of both
since ragas became the `[ragas]` extra (#126); `eval ragas` and `answers generate --ragas`
still need `pip install 'dokimi[ragas]'`, and the weekly `test-latest` CI job installs
that extra and runs its import check. The three filelock advisories are unchanged.
8 changes: 0 additions & 8 deletions dokimi/osv-scanner.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,6 @@
# --ignore-vuln in .github/workflows/pip-audit.yml; SECURITY.md ("Known advisories in
# dependencies") explains why each one does not affect Dokimi.

[[IgnoredVulns]]
id = "PYSEC-2026-2447"
reason = "diskcache, via ragas: DiskCacheBackend is never constructed. See SECURITY.md."

[[IgnoredVulns]]
id = "PYSEC-2026-3046"
reason = "ragas 0.3.9 does not ship the vulnerable module (first in 0.4.2). See SECURITY.md."

[[IgnoredVulns]]
id = "GHSA-v4x8-3wr5-3wq8"
reason = "filelock ReadWriteLock on POSIX: no dependency of Dokimi uses ReadWriteLock; litellm caps filelock<4. See SECURITY.md."
Expand Down
9 changes: 2 additions & 7 deletions dokimi/requirements-ci.lock.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1077,9 +1077,7 @@ mypy==2.4.0 \
mypy-extensions==1.1.0 \
--hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \
--hash=sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558
# via
# -c requirements.lock.txt
# mypy
# via mypy
nh3==0.3.7 \
--hash=sha256:157ec1eb7a62f3d9a7badb8d82d89aa810e3e24e097eedfa481a25d0c8a99877 \
--hash=sha256:15f5fbf090f5c88d61c820e1fc1fceecb6520cca9fe85649c06b57ef9dc9ff62 \
Expand Down Expand Up @@ -1302,9 +1300,7 @@ requests==2.34.2 \
requests-toolbelt==1.0.0 \
--hash=sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6 \
--hash=sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06
# via
# -c requirements.lock.txt
# twine
# via twine
requirements-parser==0.13.1 \
--hash=sha256:6e385663eb32589d16e5b22bb6e5251a57908e73803ffff438b53cd6ea2056e0 \
--hash=sha256:78811383b2089b6c5197a1431bc2c12ff950245edca39a23eea3460782038dd3
Expand All @@ -1317,7 +1313,6 @@ rich==14.3.4 \
--hash=sha256:07e7adb4690f68864777b1450859253bed81a99a31ac321ac1817b2313558952 \
--hash=sha256:817e02727f2b25b40ef56f5aa2217f400c8489f79ca8f46ea2b70dd5e14558a9
# via
# -c requirements.lock.txt
# bandit
# pip-audit
# twine
Expand Down
2 changes: 2 additions & 0 deletions dokimi/requirements-test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ httpx>=0.27.0
numpy>=1.24.0
scipy>=1.11.0
litellm>=1.105.0
# tests/test_docs_hooks.py imports it; it was only in the lock via ragas -> rich, so its tests would skip.
markdown-it-py>=3
Loading
Loading