Repository navigation
fix(deps): remediate pillow CVEs by raising the floor to >=13.0.0 - #180
Merged
Merged
Conversation
pip-audit reported 8 advisories against the locked pillow 12.3.0 (CVE-2026-112895, -112400, -112397, -112896, -112897, -112395, -112404, -112899), all fixed in 13.0.0. The advisory job is advisory rather than required, but it is red on every PR and on main. Both halves are required: pip-audit audits the lock via 'uv export --frozen', so re-locking alone would leave the declared minimum (pillow>=12.3.0) known-vulnerable for anyone resolving from pyproject.toml without the lock. The floor moves to >=13.0.0 and the lock is re-pinned for pillow only. Verified: pillow 12.3.0 -> 13.0.0 is the ONLY version change in the lock (no package added or removed); 'uv pip check' reports all 29 packages compatible; pip-audit exits 0 with 'No known vulnerabilities found'; the Python unit suite passes 67/67, unchanged from the pillow 12.3.0 baseline; ruff and mypy clean; go test ./... and go test -race ./... green against real PostgreSQL. The committed parser corpus is NOT regenerated and is byte-reproducible under pillow 13: regenerating all 45 cases with seed 29 into a scratch directory reproduces every committed sha256 (45/45 identical, case order and transforms unchanged), and TestVerifyCorpus_RealFixtures passes. 'git diff -- fixtures/parser_eval/' is empty. No parser behaviour, fixture, or business logic changed. Co-Authored-By: opencode <no-reply@opencode.ai>
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configuration
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
21 of 36 tasks
Aparnap2
marked this pull request as ready for review
October 21, 2026 06:44
Aparnap2
added a commit
that referenced
this pull request
Oct 21, 2026
The rebase onto main@7ad446c (which merged #180 and #179) made three statements in this change false as written: - The ADR, the decision-log entry and KL-18 all said the cross-language fixture 'contains nine cases'. After #179 it contains nineteen. None of the nineteen covers EXPIRED, so the substantive claim is unchanged; only the count was stale. - The ADR's Base line still named main@254c4b9; it is now written against main@7ad446c. - The Context said 'no document in this repository ever ratified it'. This ADR ratifies it, so the claim needs its temporal qualifier. The statemachine.go reference is likewise now stated as 'before this ADR', since this change corrects that header. Also fixes KL-18's position: it was inserted between KL-16 and KL-17 instead of after KL-17, so the register's rows were out of order. Co-Authored-By: opencode <no-reply@opencode.ai>
Aparnap2
added a commit
that referenced
this pull request
Oct 21, 2026
* docs(adr): ratify the claim expiry contract (ADR-011, S5/APA-26) EXPIRED has been implemented, wired, tested and deployed for a long time, but no document in this repository ever ratified it. Its semantics were attested only by code comments citing a Linear id the repo does not record, while the file calling itself the specification of this lifecycle did not contain the status at all. ADR-011 records the approved semantics: EXPIRED is terminal-for-round (no out-edges; terminality by absence from claims.Transitions), reachable only as HITL -> EXPIRED or ACTION_PENDING -> EXPIRED (HITL-wait timeout). Timeout expiry can never approve, reject, close, escalate or otherwise decide a claim; post-expiry APPROVE/REJECT/ESCALATE/HOLD are illegal and APPROVE from HITL was already illegal. Re-drive after expiry requires an explicit new decision/round, never an implicit edge. Reconciled documentation: - statemachine.go's header no longer claims the file is 'the Go port of the Python specification' - packages/domain/state_machine.py is a demoted artifact, not a mirror, and does not define EXPIRED. Comment-only change. - AGENT_OPERATING_CONTRACT.md item 5 now lists EXPIRED in the chain. - packages/domain/state_machine.py's docstring states it is superseded for lifecycle semantics and is not a mirror. Docstring-only change. - 09_DECISION_LOG.md and 06_PROGRESS.md carry the decision. - KNOWN_LIMITATIONS.md gains KL-18 registering the narrower Python graph rather than reconciling it silently. No lifecycle behaviour changed. The implementation already behaved this way and the existing tests already pin it: claims/expiry_red_test.go, handlers/decision_expiry_test.go (4 PG-gated), repository/postgres/hitl_expiry_test.go. The statemachine.go comment about golden case 08 is also inaccurate but is deliberately left alone: that correction is a separate focused change. Co-Authored-By: opencode <no-reply@opencode.ai> * docs(adr): correct ADR-011 facts after rebasing onto #179 The rebase onto main@7ad446c (which merged #180 and #179) made three statements in this change false as written: - The ADR, the decision-log entry and KL-18 all said the cross-language fixture 'contains nine cases'. After #179 it contains nineteen. None of the nineteen covers EXPIRED, so the substantive claim is unchanged; only the count was stale. - The ADR's Base line still named main@254c4b9; it is now written against main@7ad446c. - The Context said 'no document in this repository ever ratified it'. This ADR ratifies it, so the claim needs its temporal qualifier. The statemachine.go reference is likewise now stated as 'before this ADR', since this change corrects that header. Also fixes KL-18's position: it was inserted between KL-16 and KL-17 instead of after KL-17, so the register's rows were out of order. Co-Authored-By: opencode <no-reply@opencode.ai> --------- Co-authored-by: opencode <no-reply@opencode.ai>
Aparnap2
added a commit
that referenced
this pull request
Oct 24, 2026
…#184) The PyPI advisory database moved between the last green main run and the next PR's CI: pypdf 6.21.0 (in the lock via >=6.19.0) now carries four advisories, all fixed by 6.21.2: - CVE-2026-113786 (fix: 6.21.1) - CVE-2026-115572 (fix: 6.21.2) - CVE-2026-115585 (fix: 6.21.2) - CVE-2026-115580 (fix: 6.21.2) Mirrors the pillow remediation (W1 / #180) exactly: raise the pyproject floor, relock, verify the range, then prove the committed corpus is byte-identical under the new generator dependency. pypdf is the generator dependency for fixtures/parser_eval/ (seed 29, sole reproducer tools/corpus through tools/corpus.generate). Produced a candidate corpus with pypdf 6.21.2 at master seed 29 and diffed the whole tree against the committed corpus: 'diff -r' exits clean, all 45 case PDFs byte-identical. No corpus requalification is needed. Gates: pip-audit 'No known vulnerabilities found' (claimops-ai is workspace-local and skipped as before); pytest 67 passed; ruff 'All checks passed!'; go vet/test untouched scope 41 ok. Co-authored-by: opencode <no-reply@opencode.ai>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Two files, dependency-only:
pyproject.tomlpillow>=12.3.0→pillow>=13.0.0(1 line)uv.lock12.3.0→13.0.0Base
main@254c4b92dddf59a758a133c1edbf7618dcc011b2· commitb0eeff2· branchfix/pillow-cve-remediation.No parser behaviour, fixture, business logic, CI workflow, or other dependency changed.
The advisories
pip-auditon the committed lock reported 8 known vulnerabilities in 1 package — allpillow 12.3.0, all fixed in13.0.0:The job is advisory rather than required, but it is red on
mainand on every PR, which erodes the signal of a green run.Why both halves were required
security.ymlaudits the lock (uv export --frozen), so re-locking alone would turn the scanner green while the declared minimum stayed known-vulnerable for anyone resolving frompyproject.tomlwithout the lock — and would let a futureuv lock --upgrade(or a Dependabot PR touching another package) re-select 12.3.0. The floor therefore moves too.Verification
Dependency graph —
pillow 12.3.0 → 13.0.0is the only version change in the entire lock; no package added, none removed, every other resolved version identical.uv pip check: All installed packages are compatible (29 packages).Advisory —
uvx pip-audit -r <new export>→No known vulnerabilities found, exit code 0.Compatibility —
requires-python = ">=3.12"; Pillow 13 requires>=3.11; CI runs Python 3.12.reportlab 5.0.1requirespillow>=9.0.0with no upper bound.liteparse 2.14.4has no dependencies, so it cannot conflict. Resolution succeeded with no constraint backtracking.Python suite —
uv run pytest tests/unit -q→ 67 passed, identical to the pre-change baseline I ran first onpillow 12.3.0(67 passed). All 14 corpus-generator tests pass, includingtest_render_is_byte_deterministic.ruff check .→ All checks passed.mypy packages scripts/ci→ Success: no issues found in 11 source files.Go —
go test ./... -count=1→ 41 packages ok, 0 failures against real PostgreSQL (claimops_app,rolsuper=f, rolbypassrls=f, so RLS is genuinely enforced).go test -race -count=1 ./...→ clean, no data races.go vet ./...,go build ./...→ clean.The corpus was NOT regenerated — and it does not need to be
git diff -- fixtures/parser_eval/is empty, andTestVerifyCorpus_RealFixturespasses.I additionally measured the risk rather than assuming it. A prior audit warned that Pillow 13's HarfBuzz/-O2 text-rasterization change and a
textbboxunderflow fix could alter the rasterised cases (CASE-039/042/044) and force corpus requalification. I regenerated all 45 cases with the corpus's own seed (29) into a scratch directory under Pillow 13 and compared against the committed manifest:The committed corpus is byte-reproducible under Pillow 13.0.0. The feared delta does not materialise, so no corpus requalification is triggered and the frozen artefact stays frozen. The scratch output was not committed and the repo fixtures were never touched.
Not run / unavailable
Mockoon contract tests (gate
GET /v1/policies/POL-001returns 404), localgcp GCS/Pub/Sub, the GCW emulator, and the Groq live-LLM matrix are unavailable in this environment and self-skip — they are not passing coverage and are unaffected by this change.Status
Dependency-only, isolated from PR #179. Not authorized to merge — opened as a draft for review. No branch-protection change, no deployment. Release status NOT QUALIFIED; this clears a supply-chain advisory and nothing else —
docs/KNOWN_LIMITATIONS.mdis unchanged and no release gate is closed by it.