Skip to content

build: upgrade pre-commit to 4.6.1 - #67

Merged
dariero merged 3 commits into
mainfrom
codex/bump-pre-commit
Jul 27, 2026
Merged

build: upgrade pre-commit to 4.6.1#67
dariero merged 3 commits into
mainfrom
codex/bump-pre-commit

Conversation

@dariero

@dariero dariero commented Jul 26, 2026

Copy link
Copy Markdown
Owner

Upgrades pre-commit from 4.6.0 to 4.6.1. Lock-only change; pyproject.toml is untouched because pre-commit>=4.6.0,<5 already admits 4.6.1.

Version delta

Package Before After Delta Constraint
pre-commit 4.6.0 4.6.1 patch >=4.6.0,<5 (pyproject.toml:22), unchanged

4.6.1 is the only stable release between 4.6.0 and latest, and 4.6.1 is latest.

Lock regenerated with the first form of .agents/skills/upgrade-dependencies/SKILL.md step 5, targeting only this package:

$ uvx --from uv==0.11.30 uv lock --upgrade-package pre-commit --python 3.14 --prerelease disallow
Resolved 56 packages in 299ms
Updated pre-commit v4.6.0 -> v4.6.1

Resulting diff is 6 lines across both locks, one package, no transitive churn:

$ git diff --stat
 pylock.toml | 6 +++---
 uv.lock     | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

Breaking changes, and which touch this repository

4.6.1 has no Features section, no deprecations, no removals. Five fixes:

Fix Reachable from this repository
install via git for language: node No. No hook uses language: node; all twelve are language: unsupported.
JULIA_DEPOT_PATH handling No. No Julia hook.
Return an error for invalid --repo (autoupdate) No. pre-commit autoupdate is not documented or used here, and with a single repo: local there is nothing to autoupdate.
faster check of rev existing locally as a commit Only from the installed pre-push hook's argv translation, not from run --all-files.
avoid duplicate files in --all-files during conflict Yes. This is the only 4.6.1 change on the path this repository's documented and CI commands take.

The one that lands is a single line in pre_commit/git.py get_all_files():

- zsplit(cmd_output('git', 'ls-files', '-z')[1])
+ zsplit(cmd_output('git', 'ls-files', '-z', '--deduplicate')[1])

Undocumented consequence worth recording: this introduces a git version floor. git ls-files --deduplicate was added in git 2.31.0 (git's own Documentation/RelNotes/2.31.0.adoc: "A new option --deduplicate has been introduced."), released 2021-03. pre-commit run --all-files on git older than 2.31.0 will now fail. The 4.6.1 release notes do not mention this. Verified locally:

$ git --version
git version 2.55.0
$ git ls-files -z --deduplicate >/dev/null && echo supported
supported

Not touched anywhere in the 4.6.0 to 4.6.1 diff, which is the load-bearing negative evidence for everything this repository's config relies on: pre_commit/clientlib.py (config schema, validate-config), pre_commit/commands/run.py (types/types_or filtering, always_run, pass_filenames, require_serial, --show-diff-on-failure), pre_commit/languages/unsupported.py, pre_commit/languages/system.py, pre_commit/repository.py, pre_commit/lang_base.py.

minimum_pre_commit_version: "4.6.0" at .pre-commit-config.yaml:1 is a floor and needs no edit.

Prediction recorded before running anything

Both locks change by exactly one package with no transitive movement, because pre-commit's own dependency set (cfgv, identify, nodeenv, pyyaml, virtualenv) is unchanged in 4.6.1. Every gate passes. Coverage stays at 96.05% because pre-commit is not in [tool.coverage.run] source and is not imported by any test. All twelve hooks pass identically; the --deduplicate change is invisible here because the working tree has no merge conflict, so git ls-files -z and git ls-files -z --deduplicate return the same list.

What actually happened

Exactly that.

Gate Before (main) After
uv lock --check Resolved 56 packages Resolved 56 packages
Frozen export vs pylock.toml identical identical
uv pip check 54 packages compatible 54 packages compatible
pytest eval/ -q 335 passed, 13 deselected 335 passed, 13 deselected
Coverage gate 96.05% 96.05%
pre-commit validate-config exit 0 exit 0
pre-commit run --all-files 12 hooks passed 12 hooks passed
ruff format --check . 10 files already formatted 10 files already formatted
ruff check . All checks passed All checks passed
mypy strict scope Success, 5 source files Success, 5 source files
agent-policy-symbols exit 0 exit 0
Default selection 13 deselected 13 deselected
Installed runner pre-commit 4.6.0 pre-commit 4.6.1

Free validation command and result:

$ .venv/bin/python -m pytest -m "not openai and not rag_test" --cov --cov-report=term-missing eval/ -q
TOTAL                       642     18    218     16  96.05%
Required test coverage of 95.0% reached. Total coverage: 96.05%
335 passed, 13 deselected in 1.07s

The mutation question

Which behaviours of this dependency does the suite exercise? pre-commit is the hook runner, not a library. No pytest node imports it and it appears in no coverage-measured module. What does exercise it is the two documented commands, both run above: pre-commit validate-config covers config-schema parsing, and pre-commit run --all-files covers hook discovery, types/types_or file filtering, stages selection, always_run, pass_filenames, require_serial, and the language: unsupported execution path. That is real coverage of the runner's behaviour, but it comes from documented commands rather than from any test node.

For each breaking change that touches a real call site, which test would have failed?

Change Touches this repository Test that would have failed
git ls-files --deduplicate in get_all_files() Yes - run --all-files is both a documented command and a CI step None, and no command either. The change is only observable when the index contains a duplicate path, which happens during an unresolved merge conflict. Nothing here constructs that state.
git 2.31.0 floor introduced by that flag Yes, as an environment precondition None. No gate asserts a minimum git version. A clone on git older than 2.31.0 would fail at pre-commit run --all-files with no diagnostic pointing at the cause.
pre-push _rev_exists() change Only via the installed pre-push hook None. pre-commit install installs the pre-commit stage hook; the pre-push argv translation is never exercised by any documented command or CI step.
autoupdate --repo error No None needed

The finding, stated plainly. The single 4.6.1 change that reaches this repository's own commands cannot be detected by anything runnable here, and the git version floor it silently introduces is asserted nowhere. Both are low-consequence given a modern git, and neither is a reason to withhold the patch - but a green run of all twelve hooks is not evidence that this upgrade was behaviourally neutral on the path it actually touches. It is evidence that the path was not stressed. Per the audit brief, no test was added to close this gap in this pass.

Lock byte-comparison

$ uvx --from uv==0.11.30 uv lock --check --python 3.14 --prerelease disallow
Resolved 56 packages in 5ms
$ uvx --from uv==0.11.30 uv export --frozen --format pylock.toml --all-groups \
    --no-emit-project --python 3.14 --prerelease disallow --no-header --quiet \
    -o "$generated_dir/pylock.generated.toml"
$ cmp pylock.toml "$generated_dir/pylock.generated.toml"
cmp: IDENTICAL (exit 0)
$ shasum -a 256 pylock.toml "$generated_dir/pylock.generated.toml"
cc4b77ff62b5e9d3d671612f2f892e53ab72579ff8f142ed8f10e5a0d19ecd84  pylock.toml
cc4b77ff62b5e9d3d671612f2f892e53ab72579ff8f142ed8f10e5a0d19ecd84  .../pylock.generated.toml

pylock.toml invariants re-checked after the export:

requires-python = "==3.14.*"
sha256 count: 343
local paths / editable / file:// / git+ : 0
non-PyPI index entries: index = "https://pypi.org/simple"
declared roots: numpy=2.5.1 openai=2.45.0 pydantic=2.13.4 mypy=2.2.0 pre-commit=4.6.1
                pre-commit-hooks=6.0.0 ruff=0.15.21 pytest=9.1.1 pytest-cov=7.1.0 ragaliq=0.2.0

Clean-clone transcript

Isolated temp directory, both provider key variables unset and confirmed absent by presence check only, no sibling ../RagaliQ reachable, README install commands verbatim with bare uv as documented.

=== provider key presence check (names only, never values) ===
OPENAI_API_KEY: absent
ANTHROPIC_API_KEY: absent
=== clone root: /private/tmp/verdigrise-cleanclone.1cnfG6 ===
=== sibling RagaliQ reachable from clone parent? ===
not reachable
cloned HEAD: 706b70851f0f2e4e1b0aca6ebcc363dba78d8884  branch: codex/bump-pre-commit
worktree clean: yes
sibling RagaliQ reachable from repo root? not reachable
uv 0.11.32 (Homebrew 2026-07-23 aarch64-apple-darwin)

$ uv venv --python 3.14
Using CPython 3.14.6 interpreter at: /opt/homebrew/opt/python@3.14/bin/python3.14
$ uv pip sync --preview-features pylock --require-hashes pylock.toml
Installed 54 packages in 124ms
$ uv pip check
Checked 54 packages in 1ms
All installed packages are compatible

$ .venv/bin/python -m pytest eval/ -q
335 passed, 13 deselected in 1.83s

=== clone-to-green wall time: 5s (uv cache WARM: 17G) ===

$ .venv/bin/python -m pytest --cov --cov-report=term-missing eval/ -q
TOTAL                       642     18    218     16  96.05%
Required test coverage of 95.0% reached. Total coverage: 96.05%
335 passed, 13 deselected in 1.17s

$ .venv/bin/ruff format --check .   -> 10 files already formatted (exit 0)
$ .venv/bin/ruff check .            -> All checks passed! (exit 0)
$ .venv/bin/python -m mypy config.py corpus.py models.py pipeline.py eval/ragaliq_adapter.py
Success: no issues found in 5 source files (exit 0)
$ .venv/bin/pre-commit validate-config   -> exit 0
$ .venv/bin/pre-commit run --all-files   -> 12 hooks Passed (exit 0)
$ .venv/bin/python -m pytest eval/ --collect-only -q | tail -1
335/348 tests collected (13 deselected) in 0.48s
$ .venv/bin/python -m eval.check_agent_policy_symbols   -> exit 0

ragaliq 0.2.0 from .../.venv/lib/python3.14/site-packages/ragaliq/__init__.py

The clone-to-green figure is a warm-cache number: the uv cache was already populated (17G), so 5s measures command execution, not first contact. A cold-cache clone would additionally download 54 wheels.

Hidden costs

  • A patch bump that quietly raises the minimum git version to 2.31.0 for pre-commit run --all-files. Nothing in this repository documents or asserts a git floor, so the failure mode on an old git is an opaque ls-files error.
  • No provider calls were made at any point in producing this change.

@dariero

dariero commented Jul 26, 2026

Copy link
Copy Markdown
Owner Author

@codex review for deterministic/RagaliQ ownership, dependency reproducibility, Python 3.14 compatibility, public-clone portability, paid-call safety, golden-fixture integrity, marker correctness, public API compatibility, and unintended behaviour changes

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

馃挕 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 706b70851f

鈩癸笍 About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 馃憤.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread uv.lock
@dariero
dariero merged commit 07e9ac1 into main Jul 27, 2026
4 checks passed
@dariero
dariero deleted the codex/bump-pre-commit branch July 27, 2026 02:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant