Skip to content

ci: install CI dependencies from hash-pinned locks - #302

Merged
imran-siddique merged 1 commit into
mainfrom
ci/hash-pinned-pip
Sep 7, 2026
Merged

ci: install CI dependencies from hash-pinned locks#302
imran-siddique merged 1 commit into
mainfrom
ci/hash-pinned-pip

Conversation

@imran-siddique

Copy link
Copy Markdown
Member

Same pattern as agentrust-io/trace-registry#67 (merged, green) and agentrust-io/trace-tests#101.

Three locks under requirements/, each compiled from a .in whose header carries the exact regeneration command:

Lock Covers
dev.txt [project.dependencies] plus the dev extra
docs.txt the docs toolchain
build.txt hatchling for the release path

All installed with --require-hashes, which is all-or-nothing: pip refuses if any requirement, transitive included, lacks a hash.

Editable installs use the two-step, since pip cannot hash-pin an editable install in the same invocation.

Deliberately not pinned

publish.yml installs dist/*.whl and dist/*.tar.gz — the artifacts that job has just built. Pinning those would defeat the verification they exist to perform, so they stay as they are.

Verification

Clean venv: the lock installs under --require-hashes, and the suite gives 1213 passed against the 4 failures that reproduce on an unmodified main (three fixture-regeneration tests and one schema-classification test).

One detail worth calling out: test_docs_quickstart passes here where it fails on my machine. Its subprocess resolves agentrust_trace to the editable tree in this setup, rather than to a shadowing PyPI install — which is precisely the failure mode the conftest guard added in #301 detects.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XbDBXDWWvMFa7c2jGgyq9t

Same pattern as trace-registry and trace-tests. Every pip install in
these workflows resolved whatever PyPI served at that moment.

Three locks under requirements/, each compiled from a .in whose header
carries the exact regeneration command, all installed with
--require-hashes. That flag is all-or-nothing: pip refuses if any
requirement, transitive included, lacks a hash.

The editable installs use the two-step, since pip cannot hash-pin an
editable install in the same invocation: third-party dependencies come
from the lock, then the local package goes in with --no-deps.

Two installs in publish.yml are deliberately left alone. They install
dist/*.whl and dist/*.tar.gz, the artifacts the job has just built, and
pinning those would defeat the verification they exist to perform.

Locks are universal and compiled against 3.11, the floor in
requires-python, so they hold across the 3.11/3.12 matrix.

Verified in a clean venv: the lock installs under --require-hashes and
the suite is 1213 passed against the 4 failures that reproduce on an
unmodified main. Worth noting that test_docs_quickstart passes here where
it fails on my machine: the editable install makes its subprocess resolve
to the tree, which is exactly the shadowing the new conftest guard
detects.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XbDBXDWWvMFa7c2jGgyq9t
@imran-siddique
imran-siddique requested a review from a team as a code owner September 7, 2026 00:43
@imran-siddique
imran-siddique merged commit 5155458 into main Sep 7, 2026
7 checks passed
@imran-siddique
imran-siddique deleted the ci/hash-pinned-pip branch September 7, 2026 00:45
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