Keep a Python test phase's lockfile install in check builds #135

Open
clawbot wants to merge 4 commits from issue-133-python-lockfile-install into next
Collaborator

Writes down sneak's ruling in sneak/rfscan#80 (comment), which answers sneak/rfscan#80 (comment). A Python test phase that installs its packages from Pipfile.lock does it above ARG CACHEBUST, so check builds keep them the way they keep Go's modules.

  • prompts/REPO_POLICIES.md: the CACHEBUST rule and the list of what check builds keep name the step that runs script/bootstrap to install those packages. A new point gives the steps (COPY script/ script/, COPY Pipfile Pipfile.lock ./, RUN script/bootstrap, then ARG CACHEBUST), what script/bootstrap may install in that step (system packages, pipenv and its dependencies by hash, the lockfile's packages, no Python), and what a kept layer holds. It ends with a short example.
  • Both checklists: the ARG CACHEBUST and script/cibuild items name that step, and a Python item sits beside the Go one.
  • README.md: the paragraph that restates the rule.
  • TODO.md: a Completed Steps entry.

The tests, and the Python installs in every other stage, stay after the line. No script/ comment became untrue, so none changed.

Disclosures:

  • Judgement call: as with Go's module download, the rule says where ARG CACHEBUST goes, not "may".
  • The canonical Go Dockerfile's opening comment still names only system packages and Go's modules; that file has no Python stage.
  • rfscan installs pipenv by version, not by hash, so its script/bootstrap does not meet this rule yet.

Closes #133

Model: opus-5-5

Writes down sneak's ruling in https://git.eeqj.de/sneak/rfscan/issues/80#issuecomment-153437, which answers https://git.eeqj.de/sneak/rfscan/issues/80#issuecomment-153166. A Python `test` phase that installs its packages from `Pipfile.lock` does it above `ARG CACHEBUST`, so check builds keep them the way they keep Go's modules. - `prompts/REPO_POLICIES.md`: the `CACHEBUST` rule and the list of what check builds keep name the step that runs `script/bootstrap` to install those packages. A new point gives the steps (`COPY script/ script/`, `COPY Pipfile Pipfile.lock ./`, `RUN script/bootstrap`, then `ARG CACHEBUST`), what `script/bootstrap` may install in that step (system packages, pipenv and its dependencies by hash, the lockfile's packages, no Python), and what a kept layer holds. It ends with a short example. - Both checklists: the `ARG CACHEBUST` and `script/cibuild` items name that step, and a Python item sits beside the Go one. - `README.md`: the paragraph that restates the rule. - `TODO.md`: a Completed Steps entry. The tests, and the Python installs in every other stage, stay after the line. No `script/` comment became untrue, so none changed. Disclosures: - Judgement call: as with Go's module download, the rule says where `ARG CACHEBUST` goes, not "may". - The canonical Go `Dockerfile`'s opening comment still names only system packages and Go's modules; that file has no Python stage. - rfscan installs pipenv by version, not by hash, so its `script/bootstrap` does not meet this rule yet. Closes https://git.eeqj.de/sneak/prompts/issues/133 Model: opus-5-5
clawbot added 1 commit 2026-10-21 17:12:22 +02:00
On sneak's ruling in
sneak/rfscan#80 (comment), a Python
test phase installs its packages from Pipfile.lock above ARG CACHEBUST,
so Docker keeps them until the base image, Pipfile, Pipfile.lock or a
line up to the install changes. The step is COPY Pipfile Pipfile.lock ./
and one RUN of pipenv install --deploy, or a script/bootstrap that
installs nothing beyond system packages, the pinned pipenv and the
lockfile's packages. --deploy installs only what the lockfile names and
checks its hashes. The tests, and every other stage's Python installs,
stay after the line. REPO_POLICIES.md gains a short example; both
checklists and the README state the rule the same way.

Model: opus-5-5
clawbot self-assigned this 2026-10-21 17:12:25 +02:00
clawbot added the needs-review label 2026-10-21 17:12:25 +02:00
Author
Collaborator

FAIL: needs rework.

  1. prompts/REPO_POLICIES.md lines 369–372, and the Python item in both checklists (prompts/NEW_REPO_CHECKLIST.md line 131, prompts/EXISTING_REPO_CHECKLIST.md line 71): the form without script/bootstrap (COPY Pipfile Pipfile.lock ./, then one RUN of pipenv install --deploy) never says where pipenv comes from. The python images do not include it, so a Dockerfile written from these sentences fails at that step. Installing pipenv is also missing from every list of what may go above ARG CACHEBUST (the CACHEBUST rule, the checklists' ARG CACHEBUST item, README.md), so a reader cannot tell where to put it. Acceptable: say that the same RUN installs pipenv first, pinned as in finding 2, and add that to every place that lists what goes above the line. Or drop this form and keep only the script/bootstrap one.

  2. prompts/REPO_POLICIES.md lines 378–381: "A kept layer holds the same packages a new install would" is true only of the packages Pipfile.lock names. The layer also keeps pipenv's own dependencies, among them virtualenv, and the pip and setuptools that virtualenv puts into every new virtualenv. None of these are in the lockfile. The PR body says "the pinned pipenv" (here and in both checklists) means pinned by version. That leaves all of them free to change, so a kept layer and a fresh build can run the tests with different pip and setuptools. It also falls short of the policy's rule that every external reference is pinned by hash. Acceptable: wherever "the pinned pipenv" appears, require pipenv and its dependencies to be installed by hash, as that rule already demands, and say this is what keeps pip and setuptools fixed. Or limit the claim to the lockfile's packages and name what else the layer keeps.

  3. prompts/REPO_POLICIES.md line 368: the bold sentence says every Python test phase installs from Pipfile.lock. That reads as requiring pipenv in every Python repo, while the policy elsewhere names only pyproject.toml for Python, and the checklists say "a test phase that installs its packages from Pipfile.lock". Acceptable: make the policy sentence conditional, as the checklists are.

  4. prompts/NEW_REPO_CHECKLIST.md lines 224–230 and prompts/EXISTING_REPO_CHECKLIST.md lines 240–246: the script/cibuild item still says that only the steps that install system packages and download Go's modules are expected to show CACHED. After this change the Python lockfile install shows CACHED too, and a reader following the item cannot tell whether that is expected. Acceptable: name that install, or the script/bootstrap step that runs it, in the same sentence, as the change for #130 did for Go's modules.

  5. prompts/REPO_POLICIES.md lines 376–378, and the same sentence in both checklists: "That script/bootstrap may install nothing beyond system packages, the pinned pipenv and the packages from the lockfile" does not say whether it means what the script installs when it runs in that step, or everything it can install on any host. rfscan's script/bootstrap, the case this rule was written for, can also install a pinned Python from a hash-checked archive, though it skips that in the image because the image's Python is the pinned one. A reader cannot tell whether it qualifies. Acceptable: say the limit applies to what the script installs when it runs in that step, and say whether a pinned Python counts.

  6. prompts/REPO_POLICIES.md lines 393–395: the example installs make and git with no reason given, and its script/bootstrap is described as installing only pipenv and the lockfile's packages. A reader copying it cannot tell whether those two packages are needed. Acceptable: a short comment saying what needs them, or a placeholder package name.

Model: opus-5-5

FAIL: needs rework. 1. `prompts/REPO_POLICIES.md` lines 369–372, and the Python item in both checklists (`prompts/NEW_REPO_CHECKLIST.md` line 131, `prompts/EXISTING_REPO_CHECKLIST.md` line 71): the form without `script/bootstrap` (`COPY Pipfile Pipfile.lock ./`, then one `RUN` of `pipenv install --deploy`) never says where pipenv comes from. The `python` images do not include it, so a `Dockerfile` written from these sentences fails at that step. Installing pipenv is also missing from every list of what may go above `ARG CACHEBUST` (the `CACHEBUST` rule, the checklists' `ARG CACHEBUST` item, `README.md`), so a reader cannot tell where to put it. Acceptable: say that the same `RUN` installs pipenv first, pinned as in finding 2, and add that to every place that lists what goes above the line. Or drop this form and keep only the `script/bootstrap` one. 2. `prompts/REPO_POLICIES.md` lines 378–381: "A kept layer holds the same packages a new install would" is true only of the packages `Pipfile.lock` names. The layer also keeps pipenv's own dependencies, among them virtualenv, and the pip and setuptools that virtualenv puts into every new virtualenv. None of these are in the lockfile. The PR body says "the pinned pipenv" (here and in both checklists) means pinned by version. That leaves all of them free to change, so a kept layer and a fresh build can run the tests with different pip and setuptools. It also falls short of the policy's rule that every external reference is pinned by hash. Acceptable: wherever "the pinned pipenv" appears, require pipenv and its dependencies to be installed by hash, as that rule already demands, and say this is what keeps pip and setuptools fixed. Or limit the claim to the lockfile's packages and name what else the layer keeps. 3. `prompts/REPO_POLICIES.md` line 368: the bold sentence says every Python `test` phase installs from `Pipfile.lock`. That reads as requiring pipenv in every Python repo, while the policy elsewhere names only `pyproject.toml` for Python, and the checklists say "a `test` phase that installs its packages from `Pipfile.lock`". Acceptable: make the policy sentence conditional, as the checklists are. 4. `prompts/NEW_REPO_CHECKLIST.md` lines 224–230 and `prompts/EXISTING_REPO_CHECKLIST.md` lines 240–246: the `script/cibuild` item still says that only the steps that install system packages and download Go's modules are expected to show `CACHED`. After this change the Python lockfile install shows `CACHED` too, and a reader following the item cannot tell whether that is expected. Acceptable: name that install, or the `script/bootstrap` step that runs it, in the same sentence, as the change for https://git.eeqj.de/sneak/prompts/issues/130 did for Go's modules. 5. `prompts/REPO_POLICIES.md` lines 376–378, and the same sentence in both checklists: "That `script/bootstrap` may install nothing beyond system packages, the pinned pipenv and the packages from the lockfile" does not say whether it means what the script installs when it runs in that step, or everything it can install on any host. rfscan's `script/bootstrap`, the case this rule was written for, can also install a pinned Python from a hash-checked archive, though it skips that in the image because the image's Python is the pinned one. A reader cannot tell whether it qualifies. Acceptable: say the limit applies to what the script installs when it runs in that step, and say whether a pinned Python counts. 6. `prompts/REPO_POLICIES.md` lines 393–395: the example installs `make` and `git` with no reason given, and its `script/bootstrap` is described as installing only pipenv and the lockfile's packages. A reader copying it cannot tell whether those two packages are needed. Acceptable: a short comment saying what needs them, or a placeholder package name. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-21 17:26:30 +02:00
Author
Collaborator

Rework plan for #135 (comment):

  1. Drop the form without script/bootstrap. The one form left is COPY script/ script/, COPY Pipfile Pipfile.lock ./, RUN script/bootstrap, and every list of what goes above ARG CACHEBUST names that step.
  2. pipenv and its dependencies are installed by hash, as the policy's first rule already requires of every external reference. The "same install" claim covers only what is pinned by hash and says what else the layer keeps.
  3. The bold sentence becomes conditional: a Python test phase that installs from Pipfile.lock.
  4. Both checklists' script/cibuild item names the script/bootstrap step among the steps expected to show CACHED.
  5. The limit is on what script/bootstrap installs when it runs in that step: system packages, pipenv and its dependencies by hash, and the lockfile's packages. No Python: the base image's Python is the one the tests use.
  6. The example says in a comment why it installs make and git.

Model: opus-5-5

Rework plan for https://git.eeqj.de/sneak/prompts/pulls/135#issuecomment-153985: 1. Drop the form without `script/bootstrap`. The one form left is `COPY script/ script/`, `COPY Pipfile Pipfile.lock ./`, `RUN script/bootstrap`, and every list of what goes above `ARG CACHEBUST` names that step. 2. pipenv and its dependencies are installed by hash, as the policy's first rule already requires of every external reference. The "same install" claim covers only what is pinned by hash and says what else the layer keeps. 3. The bold sentence becomes conditional: a Python `test` phase that installs from `Pipfile.lock`. 4. Both checklists' `script/cibuild` item names the `script/bootstrap` step among the steps expected to show `CACHED`. 5. The limit is on what `script/bootstrap` installs when it runs in that step: system packages, pipenv and its dependencies by hash, and the lockfile's packages. No Python: the base image's Python is the one the tests use. 6. The example says in a comment why it installs `make` and `git`. Model: opus-5-5
clawbot added 1 commit 2026-10-21 17:48:13 +02:00
Rework of #135 on the review at
#135 (comment). A Python
test phase now has one form: COPY script/, COPY Pipfile Pipfile.lock,
RUN script/bootstrap, then ARG CACHEBUST, and every list of what goes
above the line names that step. In that step script/bootstrap installs
only system packages, pipenv and its dependencies by hash with pip
--require-hashes, and the lockfile's packages, and no Python. The claim
about a kept layer covers only what is pinned by hash and says its
system packages may be older. The bold rule is conditional, the
script/cibuild items expect the step to show CACHED, and the example
says why it installs make and git.

Model: opus-5-5
Author
Collaborator

Rework pushed as a3ec846, following #135 (comment), for the findings in #135 (comment):

  1. The form without script/bootstrap is gone everywhere. Every list of what goes above ARG CACHEBUST now names the step that runs script/bootstrap to install a Python test phase's packages from Pipfile.lock.
  2. script/bootstrap installs pipenv and its dependencies with pip install --require-hashes. The kept-layer claim now covers only what is pinned by hash. It says pip and setuptools come from wheels inside the virtualenv package, and that system packages may be older.
  3. The bold sentence now applies only to a test phase that installs its packages from Pipfile.lock.
  4. Both checklists' script/cibuild item now expects that script/bootstrap step to show CACHED.
  5. The limit is on what script/bootstrap installs when it runs in that step. It installs no Python there, because the tests use the base image's.
  6. The example's comment says make and git are base tools that script/bootstrap installs when they are missing. Installing them first puts them in a layer that a change to script/ does not rebuild.

Model: opus-5-5

Rework pushed as `a3ec846`, following https://git.eeqj.de/sneak/prompts/pulls/135#issuecomment-153989, for the findings in https://git.eeqj.de/sneak/prompts/pulls/135#issuecomment-153985: 1. The form without `script/bootstrap` is gone everywhere. Every list of what goes above `ARG CACHEBUST` now names the step that runs `script/bootstrap` to install a Python `test` phase's packages from `Pipfile.lock`. 2. `script/bootstrap` installs pipenv and its dependencies with `pip install --require-hashes`. The kept-layer claim now covers only what is pinned by hash. It says pip and setuptools come from wheels inside the `virtualenv` package, and that system packages may be older. 3. The bold sentence now applies only to a `test` phase that installs its packages from `Pipfile.lock`. 4. Both checklists' `script/cibuild` item now expects that `script/bootstrap` step to show `CACHED`. 5. The limit is on what `script/bootstrap` installs when it runs in that step. It installs no Python there, because the tests use the base image's. 6. The example's comment says `make` and `git` are base tools that `script/bootstrap` installs when they are missing. Installing them first puts them in a layer that a change to `script/` does not rebuild. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-21 17:48:44 +02:00
Author
Collaborator

FAIL: needs rework.

  1. prompts/REPO_POLICIES.md lines 394–397: "The pip and setuptools inside the virtualenv that pipenv creates are the same too" says the virtualenv holds setuptools. On Python 3.12 and later, virtualenv puts only pip into a new virtualenv. So with any current python base image there is no setuptools there, and a reader may count on one. Acceptable: name pip alone and say setuptools is added only on Python before 3.12, or say "the packages virtualenv puts into it" without naming them.

  2. PR body, the paragraph headed "Not in the diff": both facts it gives are in the diff, at prompts/REPO_POLICIES.md lines 394–399. Those facts are that pip and setuptools come from wheels the virtualenv package ships, and that a kept layer's system packages may be older. The label tells a reader the policy leaves them out, when it does not. Acceptable: drop the paragraph, which also brings the body under about 250 words, or reword it to say the policy states them.

Model: opus-5-5

FAIL: needs rework. 1. `prompts/REPO_POLICIES.md` lines 394–397: "The pip and setuptools inside the virtualenv that pipenv creates are the same too" says the virtualenv holds setuptools. On Python 3.12 and later, `virtualenv` puts only pip into a new virtualenv. So with any current `python` base image there is no setuptools there, and a reader may count on one. Acceptable: name pip alone and say setuptools is added only on Python before 3.12, or say "the packages `virtualenv` puts into it" without naming them. 2. PR body, the paragraph headed "Not in the diff": both facts it gives are in the diff, at `prompts/REPO_POLICIES.md` lines 394–399. Those facts are that pip and setuptools come from wheels the `virtualenv` package ships, and that a kept layer's system packages may be older. The label tells a reader the policy leaves them out, when it does not. Acceptable: drop the paragraph, which also brings the body under about 250 words, or reword it to say the policy states them. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-21 18:03:33 +02:00
clawbot added 1 commit 2026-10-21 18:06:14 +02:00
Name no package the virtualenv gets (closes #133)
check / check (push) Canceled after 0s
899beebc1f
virtualenv adds setuptools to a new virtualenv only on Python before
3.12, so the policy now says "the packages virtualenv puts into" the
virtualenv instead of naming pip and setuptools.

Model: opus-5-5
Author
Collaborator

Rework pushed as 899beeb for #135 (comment):

  1. The sentence now says "the packages virtualenv puts into the virtualenv that pipenv creates" and names none of them. The checklists, README.md and TODO.md did not repeat the claim.
  2. The paragraph is gone from the PR body.

Model: opus-5-5

Rework pushed as `899beeb` for https://git.eeqj.de/sneak/prompts/pulls/135#issuecomment-154070: 1. The sentence now says "the packages `virtualenv` puts into the virtualenv that pipenv creates" and names none of them. The checklists, `README.md` and `TODO.md` did not repeat the claim. 2. The paragraph is gone from the PR body. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-21 18:07:06 +02:00
Author
Collaborator

FAIL: needs rework.

  1. prompts/REPO_POLICIES.md lines 392–394 ("A kept layer holds the same pipenv, the same dependencies of pipenv and the same lockfile packages that a new install would, because each was checked against its hash"), and the matching sentence in the TODO.md entry ("A kept layer holds the same hashed packages a new install would"): some packages have no ready-built wheel for the image's Python and platform, so pip builds them from source. pip builds them with tools such as setuptools that it downloads at that moment, with no hash check. A kept layer's copy of such a package may have been built with older tools than a new install would use, so the sentence promises more than the build does. Acceptable: say the claim holds for packages installed from wheels. Say also that pip builds a source-only package with tools it downloads without a hash check, so a kept layer's copy may differ from a new one. The TODO.md entry should say the same.

Model: opus-5-5

FAIL: needs rework. 1. `prompts/REPO_POLICIES.md` lines 392–394 ("A kept layer holds the same pipenv, the same dependencies of pipenv and the same lockfile packages that a new install would, because each was checked against its hash"), and the matching sentence in the `TODO.md` entry ("A kept layer holds the same hashed packages a new install would"): some packages have no ready-built wheel for the image's Python and platform, so pip builds them from source. pip builds them with tools such as setuptools that it downloads at that moment, with no hash check. A kept layer's copy of such a package may have been built with older tools than a new install would use, so the sentence promises more than the build does. Acceptable: say the claim holds for packages installed from wheels. Say also that pip builds a source-only package with tools it downloads without a hash check, so a kept layer's copy may differ from a new one. The `TODO.md` entry should say the same. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-21 18:18:38 +02:00
clawbot added 1 commit 2026-10-21 18:22:26 +02:00
A kept layer holds nothing a new install would refuse, since pip and
pipenv checked every package against its hash. A package built from
source uses build tools pip downloads without a hash check, and system
packages may be newer in a new install, so those two can differ. The
TODO.md entry says the same.

Model: opus-5-5
Author
Collaborator

Rework pushed as 14e7987 for #135 (comment): the kept-layer bullet and the TODO.md entry now say a kept layer holds nothing a new install would refuse, except that a package built from source and the system packages may differ from a new install. Model: opus-5-5

Rework pushed as `14e7987` for https://git.eeqj.de/sneak/prompts/pulls/135#issuecomment-154102: the kept-layer bullet and the `TODO.md` entry now say a kept layer holds nothing a new install would refuse, except that a package built from source and the system packages may differ from a new install. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-21 18:22:37 +02:00
Author
Collaborator

Stopped by the top-level manager at 16:36 UTC on 21 October, when the primary reached sneak's 60% guard: the independent review of this PR was running and did not report. The next manager reruns it from current next; nothing else on the branch changed.

Model: opus-5-5

Stopped by the top-level manager at 16:36 UTC on 21 October, when the primary reached sneak's 60% guard: the independent review of this PR was running and did not report. The next manager reruns it from current `next`; nothing else on the branch changed. Model: opus-5-5
Some checks are pending
check / check (push) Waiting to run
You are not authorized to merge this pull request.
This pull request can be merged automatically.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin issue-133-python-lockfile-install:issue-133-python-lockfile-install
git checkout issue-133-python-lockfile-install
Sign in to join this conversation.