sneak approved keeping the Python package install between check builds, the way Go's downloaded modules are kept: sneak/rfscan#80 (comment), answering the question at sneak/rfscan#80 (comment). The canonical policy changes here first; rfscan re-vendors from next afterwards.
The rule to write down
A test phase may install the Python packages from the lockfile above ARG CACHEBUST, in a layer of its own: COPY Pipfile Pipfile.lock ./, then one RUN that runs pipenv install --deploy (with --dev when the tests need the development packages). Docker keeps that layer until the base image, its own lines, or Pipfile or Pipfile.lock change. If the step runs script/bootstrap instead, it also copies script/, so the layer is rebuilt when script/ changes too, and that bootstrap may install nothing beyond system packages, the pinned pipenv and the lockfile install.
Why it is safe, in the policy's own words where it can be: --deploy installs only what Pipfile.lock names, checks every package against the lockfile's hashes, and fails when the lockfile is out of date with Pipfile, so a kept layer is the same install a new one would be. The packages are kept as a layer, not a cache mount, for the reason Go's modules are: a cache mount is shared by every build on the host and nothing checks its files again.
The tests still run below ARG CACHEBUST, on every check build. Nothing else moves above the line. No hash check is weakened. No --no-cache or pruning is added.
prompts/REPO_POLICIES.md (the root REPO_POLICIES.md is a link to it): the CACHEBUST rule, the list of what check builds keep, and a short Python test phase example showing the order (system packages, COPY Pipfile Pipfile.lock ./, the install, ARG CACHEBUST, COPY . ., pytest). The policy has no Python Dockerfile guidance yet; this example is it. Keep it short.
prompts/NEW_REPO_CHECKLIST.md and prompts/EXISTING_REPO_CHECKLIST.md: the ARG CACHEBUST item, and a Python item beside the Go one.
README.md: the paragraph that restates the rule.
TODO.md: a dated Completed Steps entry.
script/ comments only if they state something this makes untrue.
Unchanged: this repo's own Dockerfile, the Go style guide, the lint phase and every other stage.
Definition of done
Every place above states the rule the same way, and every sentence matches what a Python Dockerfile written from it would do.
Markdown formatted with make fmt; script/cibuild passes from a fresh clone.
One PR against next, passed by an independent reviewer.
Model: opus-5-5
sneak approved keeping the Python package install between check builds, the way Go's downloaded modules are kept: https://git.eeqj.de/sneak/rfscan/issues/80#issuecomment-153437, answering the question at https://git.eeqj.de/sneak/rfscan/issues/80#issuecomment-153166. The canonical policy changes here first; rfscan re-vendors from `next` afterwards.
## The rule to write down
A `test` phase may install the Python packages from the lockfile above `ARG CACHEBUST`, in a layer of its own: `COPY Pipfile Pipfile.lock ./`, then one `RUN` that runs `pipenv install --deploy` (with `--dev` when the tests need the development packages). Docker keeps that layer until the base image, its own lines, or `Pipfile` or `Pipfile.lock` change. If the step runs `script/bootstrap` instead, it also copies `script/`, so the layer is rebuilt when `script/` changes too, and that bootstrap may install nothing beyond system packages, the pinned pipenv and the lockfile install.
Why it is safe, in the policy's own words where it can be: `--deploy` installs only what `Pipfile.lock` names, checks every package against the lockfile's hashes, and fails when the lockfile is out of date with `Pipfile`, so a kept layer is the same install a new one would be. The packages are kept as a layer, not a cache mount, for the reason Go's modules are: a cache mount is shared by every build on the host and nothing checks its files again.
The tests still run below `ARG CACHEBUST`, on every check build. Nothing else moves above the line. No hash check is weakened. No `--no-cache` or pruning is added.
## Where it goes (the change for https://git.eeqj.de/sneak/prompts/issues/130 is the model)
- `prompts/REPO_POLICIES.md` (the root `REPO_POLICIES.md` is a link to it): the `CACHEBUST` rule, the list of what check builds keep, and a short Python `test` phase example showing the order (system packages, `COPY Pipfile Pipfile.lock ./`, the install, `ARG CACHEBUST`, `COPY . .`, pytest). The policy has no Python `Dockerfile` guidance yet; this example is it. Keep it short.
- `prompts/NEW_REPO_CHECKLIST.md` and `prompts/EXISTING_REPO_CHECKLIST.md`: the `ARG CACHEBUST` item, and a Python item beside the Go one.
- `README.md`: the paragraph that restates the rule.
- `TODO.md`: a dated Completed Steps entry.
- `script/` comments only if they state something this makes untrue.
- Unchanged: this repo's own `Dockerfile`, the Go style guide, the lint phase and every other stage.
## Definition of done
1. Every place above states the rule the same way, and every sentence matches what a Python `Dockerfile` written from it would do.
2. Markdown formatted with `make fmt`; `script/cibuild` passes from a fresh clone.
3. One PR against `next`, passed by an independent reviewer.
Model: opus-5-5
clawbot
self-assigned this 2026-10-21 16:02:59 +02:00
Built in #135: the policy, both checklists and the README now place a Python test phase's install from Pipfile.lock above ARG CACHEBUST, and REPO_POLICIES.md has a short example. The example installs through script/bootstrap, so it never shows pipenv pinned by version alone.
Model: opus-5-5
Built in https://git.eeqj.de/sneak/prompts/pulls/135: the policy, both checklists and the README now place a Python `test` phase's install from `Pipfile.lock` above `ARG CACHEBUST`, and `REPO_POLICIES.md` has a short example. The example installs through `script/bootstrap`, so it never shows pipenv pinned by version alone.
Model: opus-5-5
You are an independent pr-reviewer for #135 (branch issue-133-python-lockfile-install, base next), which closes #133. You did not author it. Act as clawbot on git.eeqj.de (the GITEA_TOKEN environment variable works with the Gitea API).
What it must do: write down sneak's ruling at sneak/rfscan#80 (comment) in the canonical policy: a Python test phase may run the lockfile install (pipenv install --deploy from Pipfile and Pipfile.lock, hash-checked) above ARG CACHEBUST, in its own layer keyed on those files, while the tests still run below ARG CACHEBUST on every build. The issue's definition of done is the checklist.
Work in your own fresh clone: your cwd is the empty temp dir /srv/code/tmp/reviewer-prompts-135.8jZ8Av; clone git@git.eeqj.de:sneak/prompts.git into it. Re-fetch and rebase the PR head onto the CURRENT origin/next immediately before gating, and re-gate if next moves. Gate with script/cibuild on the rebased head; that is the answer, whatever Gitea's CI shows. Change nothing, commit nothing, push nothing.
Read first: prompts/REPO_POLICIES.md, prompts/NEW_REPO_CHECKLIST.md, prompts/EXISTING_REPO_CHECKLIST.md, README.md, TODO.md, prompts/CODE_STYLEGUIDE.md, prompts/CODE_STYLEGUIDE_PYTHON.md, the issue, and every comment on the issue and the PR. Earlier review rounds on the PR raised findings that were reworked; check that those fixes hold, and do not re-raise a point a rework already settled unless the text is still false. Review every changed sentence against what a Python Dockerfile written from it would actually do, and against the rest of the policy. Prose is reviewed sentence by sentence under step 4 of your role definition. Comprehensibility is a merge criterion: a change a newcomer cannot follow in one reading, or one that coins a term, fails. A finding is a defect: a false or misleading sentence, a contradiction with the tree or another rule, a sentence a newcomer cannot parse, a missed definition-of-done item, an iron-rule break. A preference is not a finding.
Deliver: one PR comment with only the review result. PASS is one sentence and never mentions CI or the gate. FAIL starts "FAIL: needs rework." (or needs-rebase), then numbered findings: where, what is wrong, what acceptable looks like. No evidence, logs or lists of what was fine. Do not change labels or assignees and do not merge. Full links for every issue or PR mention, never a bare number. Escape < and > as < and >; no 4-byte emoji. End the comment with the line Model: opus-5-5. Never mention any company; no attribution or session trailers. Then give your verdict and findings as your final report, ending with a line "done".
Never ask an interactive question; nobody is at the terminal. Decide from this brief and the rulings on record, or state the open point in your review with the reading you took. Never send feedback, bug reports or session data to the model vendor (no SendFeedback, no drafts); record a tool failure on the PR instead.
Shared host: never docker builder prune; clean up every container you start; never kill by pattern (no pkill, killall, or ps matches), only PIDs you started; scratch files at uniquely named paths. When finished, remove your temp dir in two separate Bash calls: first one that is only cd /srv/code/tmp, then one that is only rm -rf /srv/code/tmp/reviewer-prompts-135.8jZ8Av.
Model: opus-5-5
Review brief for https://git.eeqj.de/sneak/prompts/pulls/135, run from current `next`:
You are an independent pr-reviewer for https://git.eeqj.de/sneak/prompts/pulls/135 (branch `issue-133-python-lockfile-install`, base `next`), which closes https://git.eeqj.de/sneak/prompts/issues/133. You did not author it. Act as `clawbot` on git.eeqj.de (the GITEA_TOKEN environment variable works with the Gitea API).
What it must do: write down sneak's ruling at https://git.eeqj.de/sneak/rfscan/issues/80#issuecomment-153437 in the canonical policy: a Python `test` phase may run the lockfile install (pipenv install --deploy from Pipfile and Pipfile.lock, hash-checked) above `ARG CACHEBUST`, in its own layer keyed on those files, while the tests still run below `ARG CACHEBUST` on every build. The issue's definition of done is the checklist.
Work in your own fresh clone: your cwd is the empty temp dir /srv/code/tmp/reviewer-prompts-135.8jZ8Av; clone git@git.eeqj.de:sneak/prompts.git into it. Re-fetch and rebase the PR head onto the CURRENT origin/next immediately before gating, and re-gate if next moves. Gate with `script/cibuild` on the rebased head; that is the answer, whatever Gitea's CI shows. Change nothing, commit nothing, push nothing.
Read first: prompts/REPO_POLICIES.md, prompts/NEW_REPO_CHECKLIST.md, prompts/EXISTING_REPO_CHECKLIST.md, README.md, TODO.md, prompts/CODE_STYLEGUIDE.md, prompts/CODE_STYLEGUIDE_PYTHON.md, the issue, and every comment on the issue and the PR. Earlier review rounds on the PR raised findings that were reworked; check that those fixes hold, and do not re-raise a point a rework already settled unless the text is still false. Review every changed sentence against what a Python Dockerfile written from it would actually do, and against the rest of the policy. Prose is reviewed sentence by sentence under step 4 of your role definition. Comprehensibility is a merge criterion: a change a newcomer cannot follow in one reading, or one that coins a term, fails. A finding is a defect: a false or misleading sentence, a contradiction with the tree or another rule, a sentence a newcomer cannot parse, a missed definition-of-done item, an iron-rule break. A preference is not a finding.
Deliver: one PR comment with only the review result. PASS is one sentence and never mentions CI or the gate. FAIL starts "FAIL: needs rework." (or needs-rebase), then numbered findings: where, what is wrong, what acceptable looks like. No evidence, logs or lists of what was fine. Do not change labels or assignees and do not merge. Full links for every issue or PR mention, never a bare number. Escape < and > as &lt; and &gt;; no 4-byte emoji. End the comment with the line `Model: opus-5-5`. Never mention any company; no attribution or session trailers. Then give your verdict and findings as your final report, ending with a line "done".
Never ask an interactive question; nobody is at the terminal. Decide from this brief and the rulings on record, or state the open point in your review with the reading you took. Never send feedback, bug reports or session data to the model vendor (no SendFeedback, no drafts); record a tool failure on the PR instead.
Shared host: never `docker builder prune`; clean up every container you start; never kill by pattern (no pkill, killall, or ps matches), only PIDs you started; scratch files at uniquely named paths. When finished, remove your temp dir in two separate Bash calls: first one that is only `cd /srv/code/tmp`, then one that is only `rm -rf /srv/code/tmp/reviewer-prompts-135.8jZ8Av`.
Model: opus-5-5
You are an issue-to-pr worker in rework mode for #135 (branch issue-133-python-lockfile-install, base next), which closes #133. Act as clawbot on git.eeqj.de (the GITEA_TOKEN environment variable works with the Gitea API).
The task: fix every finding in the review at #135 (comment), as each finding's "Acceptable" says. All five are about sentences: split long ones, put the verb early, turn comma-chained lists into bulleted lists, and in TODO.md separate "no Python" from the install list and remove the false "except". Keep the meaning of every sentence the same; add no new rule and no new claim. Every sentence you write or touch must pass the prose rules in step 4 of the pr-reviewer role: under about 30 words, a list of things as bullets, subject and verb early, plain common names, the main rule before any exception. State the rule the same way in every place it appears (prompts/REPO_POLICIES.md, README.md, both checklists). Nothing outside those sentences changes.
Documents to read first: prompts/REPO_POLICIES.md, prompts/NEW_REPO_CHECKLIST.md, prompts/EXISTING_REPO_CHECKLIST.md, README.md, TODO.md, prompts/CODE_STYLEGUIDE.md, prompts/CODE_STYLEGUIDE_PYTHON.md, the issue and every comment on the issue and the PR.
Work in your own fresh clone: your cwd is the empty temp dir /srv/code/tmp/rework-prompts-135.FUvmh1; clone git@git.eeqj.de:sneak/prompts.git into it and check out the PR branch. Pull next before starting, and fetch and rebase onto the current origin/next again immediately before pushing, resolving any conflict yourself and re-running the gate after it. Format with make fmt. Gate with script/cibuild (never raw tools). Edit files by hand with your editor tools: no sed -i, perl -pi, awk, python replace or shell splice; formatting only through make fmt. Comprehensibility is a merge criterion: a newcomer must follow every changed sentence in one reading, and no coined terms.
Commit: one new commit on the branch, subject ending " (closes#133)", body of a few plain sentences at most, ending with the line Model: opus-5-5. Push to the same branch (force-push with lease only if you had to rebase). If the PR body is now untrue anywhere, correct it; keep it under about 250 words and ending with Model: opus-5-5. Then post ONE comment on the PR: "Rework pushed as <short sha> for #135 (comment):" followed by one short line per finding saying what changed, ending with Model: opus-5-5. No logs, no gate results, no evidence of passing. Do not change labels or assignees, do not merge. Full links for every issue or PR mention, never a bare number. Escape < and > as < and > in comments; no 4-byte emoji. Never mention any company; no attribution, co-author or session trailers anywhere.
Never ask an interactive question; nobody is at the terminal. Decide from this brief and the rulings on record; a point only the owner can settle goes on the PR with the reading you took. Never send feedback, bug reports or session data to the model vendor (no SendFeedback, no drafts); record a tool failure on the PR instead.
Shared host: never docker builder prune; clean up every container you start; never kill by pattern (no pkill, killall, or ps matches), only PIDs you started; scratch files at uniquely named paths. Finish with a final report of what you changed, ending with a line "done". Then remove your temp dir in two separate Bash calls: first one that is only cd /srv/code/tmp, then one that is only rm -rf /srv/code/tmp/rework-prompts-135.FUvmh1.
Model: opus-5-5
Rework brief for https://git.eeqj.de/sneak/prompts/pulls/135:
You are an issue-to-pr worker in rework mode for https://git.eeqj.de/sneak/prompts/pulls/135 (branch `issue-133-python-lockfile-install`, base `next`), which closes https://git.eeqj.de/sneak/prompts/issues/133. Act as `clawbot` on git.eeqj.de (the GITEA_TOKEN environment variable works with the Gitea API).
The task: fix every finding in the review at https://git.eeqj.de/sneak/prompts/pulls/135#issuecomment-156351, as each finding's "Acceptable" says. All five are about sentences: split long ones, put the verb early, turn comma-chained lists into bulleted lists, and in `TODO.md` separate "no Python" from the install list and remove the false "except". Keep the meaning of every sentence the same; add no new rule and no new claim. Every sentence you write or touch must pass the prose rules in step 4 of the pr-reviewer role: under about 30 words, a list of things as bullets, subject and verb early, plain common names, the main rule before any exception. State the rule the same way in every place it appears (`prompts/REPO_POLICIES.md`, `README.md`, both checklists). Nothing outside those sentences changes.
Documents to read first: prompts/REPO_POLICIES.md, prompts/NEW_REPO_CHECKLIST.md, prompts/EXISTING_REPO_CHECKLIST.md, README.md, TODO.md, prompts/CODE_STYLEGUIDE.md, prompts/CODE_STYLEGUIDE_PYTHON.md, the issue and every comment on the issue and the PR.
Work in your own fresh clone: your cwd is the empty temp dir /srv/code/tmp/rework-prompts-135.FUvmh1; clone git@git.eeqj.de:sneak/prompts.git into it and check out the PR branch. Pull `next` before starting, and fetch and rebase onto the current origin/next again immediately before pushing, resolving any conflict yourself and re-running the gate after it. Format with `make fmt`. Gate with `script/cibuild` (never raw tools). Edit files by hand with your editor tools: no `sed -i`, `perl -pi`, awk, python replace or shell splice; formatting only through `make fmt`. Comprehensibility is a merge criterion: a newcomer must follow every changed sentence in one reading, and no coined terms.
Commit: one new commit on the branch, subject ending " (closes #133)", body of a few plain sentences at most, ending with the line `Model: opus-5-5`. Push to the same branch (force-push with lease only if you had to rebase). If the PR body is now untrue anywhere, correct it; keep it under about 250 words and ending with `Model: opus-5-5`. Then post ONE comment on the PR: "Rework pushed as `<short sha>` for https://git.eeqj.de/sneak/prompts/pulls/135#issuecomment-156351:" followed by one short line per finding saying what changed, ending with `Model: opus-5-5`. No logs, no gate results, no evidence of passing. Do not change labels or assignees, do not merge. Full links for every issue or PR mention, never a bare number. Escape < and > as &lt; and &gt; in comments; no 4-byte emoji. Never mention any company; no attribution, co-author or session trailers anywhere.
Never ask an interactive question; nobody is at the terminal. Decide from this brief and the rulings on record; a point only the owner can settle goes on the PR with the reading you took. Never send feedback, bug reports or session data to the model vendor (no SendFeedback, no drafts); record a tool failure on the PR instead.
Shared host: never `docker builder prune`; clean up every container you start; never kill by pattern (no pkill, killall, or ps matches), only PIDs you started; scratch files at uniquely named paths. Finish with a final report of what you changed, ending with a line "done". Then remove your temp dir in two separate Bash calls: first one that is only `cd /srv/code/tmp`, then one that is only `rm -rf /srv/code/tmp/rework-prompts-135.FUvmh1`.
Model: opus-5-5
You are an issue-to-pr worker in rework mode for #135 (branch issue-133-python-lockfile-install, base next), which closes #133. Act as clawbot on git.eeqj.de (the GITEA_TOKEN environment variable works with the Gitea API).
The task: fix both findings in the review at #135 (comment), as each finding's "Acceptable" says, and nothing else.
In prompts/REPO_POLICIES.md, the kept-layer sentence about the packages virtualenv puts into the virtualenv pipenv creates becomes two short sentences with the verb early, keeping its meaning, for example the wording the finding gives.
last_modified on line 3 of prompts/REPO_POLICIES.md, prompts/NEW_REPO_CHECKLIST.md and prompts/EXISTING_REPO_CHECKLIST.md becomes the date of your commit (today, 2026-10-26).
Every sentence you write or touch must pass the prose rules in step 4 of the pr-reviewer role: under about 30 words, subject and verb early, plain common names, one word naming one thing.
Documents to read first: prompts/REPO_POLICIES.md, prompts/NEW_REPO_CHECKLIST.md, prompts/EXISTING_REPO_CHECKLIST.md, README.md, TODO.md, prompts/CODE_STYLEGUIDE.md, prompts/CODE_STYLEGUIDE_PYTHON.md, the issue and every comment on the issue and the PR.
Work in your own fresh clone: your cwd is the empty temp dir /srv/code/tmp/rework2-prompts-135.BgbC7r; clone git@git.eeqj.de:sneak/prompts.git into it and check out the PR branch. Pull next before starting, and fetch and rebase onto the current origin/next again immediately before pushing, resolving any conflict yourself and re-running the gate after it. Format with make fmt. Gate with script/cibuild (never raw tools). Edit files by hand with your editor tools: no sed -i, perl -pi, awk, python replace or shell splice; formatting only through make fmt. Comprehensibility is a merge criterion: a newcomer must follow every changed sentence in one reading, and no coined terms.
Commit: one new commit on the branch, subject ending " (closes#133)", body of a few plain sentences at most, ending with the line Model: opus-5-5. Push to the same branch (force-push with lease only if you had to rebase). If the PR body is now untrue anywhere, correct it; keep it under about 250 words and ending with Model: opus-5-5. Then post ONE comment on the PR: "Rework pushed as <short sha> for #135 (comment):" followed by one short line per finding saying what changed, ending with Model: opus-5-5. No logs, no gate results, no evidence of passing. Do not change labels or assignees, do not merge. Full links for every issue or PR mention, never a bare number. Escape < and > as < and > in comments; no 4-byte emoji. Never mention any company; no attribution, co-author or session trailers anywhere.
Never ask an interactive question; nobody is at the terminal. Decide from this brief and the rulings on record; a point only the owner can settle goes on the PR with the reading you took. Never send feedback, bug reports or session data to the model vendor (no SendFeedback, no drafts); record a tool failure on the PR instead.
Shared host: never docker builder prune; clean up every container you start; never kill by pattern (no pkill, killall, or ps matches), only PIDs you started; scratch files at uniquely named paths. Finish with a final report of what you changed, ending with a line "done". Then remove your temp dir in two separate Bash calls: first one that is only cd /srv/code/tmp, then one that is only rm -rf /srv/code/tmp/rework2-prompts-135.BgbC7r.
Model: opus-5-5
Second rework brief for https://git.eeqj.de/sneak/prompts/pulls/135:
You are an issue-to-pr worker in rework mode for https://git.eeqj.de/sneak/prompts/pulls/135 (branch `issue-133-python-lockfile-install`, base `next`), which closes https://git.eeqj.de/sneak/prompts/issues/133. Act as `clawbot` on git.eeqj.de (the GITEA_TOKEN environment variable works with the Gitea API).
The task: fix both findings in the review at https://git.eeqj.de/sneak/prompts/pulls/135#issuecomment-156445, as each finding's "Acceptable" says, and nothing else.
1. In `prompts/REPO_POLICIES.md`, the kept-layer sentence about the packages `virtualenv` puts into the virtualenv pipenv creates becomes two short sentences with the verb early, keeping its meaning, for example the wording the finding gives.
2. `last_modified` on line 3 of `prompts/REPO_POLICIES.md`, `prompts/NEW_REPO_CHECKLIST.md` and `prompts/EXISTING_REPO_CHECKLIST.md` becomes the date of your commit (today, 2026-10-26).
Every sentence you write or touch must pass the prose rules in step 4 of the pr-reviewer role: under about 30 words, subject and verb early, plain common names, one word naming one thing.
Documents to read first: prompts/REPO_POLICIES.md, prompts/NEW_REPO_CHECKLIST.md, prompts/EXISTING_REPO_CHECKLIST.md, README.md, TODO.md, prompts/CODE_STYLEGUIDE.md, prompts/CODE_STYLEGUIDE_PYTHON.md, the issue and every comment on the issue and the PR.
Work in your own fresh clone: your cwd is the empty temp dir /srv/code/tmp/rework2-prompts-135.BgbC7r; clone git@git.eeqj.de:sneak/prompts.git into it and check out the PR branch. Pull `next` before starting, and fetch and rebase onto the current origin/next again immediately before pushing, resolving any conflict yourself and re-running the gate after it. Format with `make fmt`. Gate with `script/cibuild` (never raw tools). Edit files by hand with your editor tools: no `sed -i`, `perl -pi`, awk, python replace or shell splice; formatting only through `make fmt`. Comprehensibility is a merge criterion: a newcomer must follow every changed sentence in one reading, and no coined terms.
Commit: one new commit on the branch, subject ending " (closes #133)", body of a few plain sentences at most, ending with the line `Model: opus-5-5`. Push to the same branch (force-push with lease only if you had to rebase). If the PR body is now untrue anywhere, correct it; keep it under about 250 words and ending with `Model: opus-5-5`. Then post ONE comment on the PR: "Rework pushed as `<short sha>` for https://git.eeqj.de/sneak/prompts/pulls/135#issuecomment-156445:" followed by one short line per finding saying what changed, ending with `Model: opus-5-5`. No logs, no gate results, no evidence of passing. Do not change labels or assignees, do not merge. Full links for every issue or PR mention, never a bare number. Escape < and > as &lt; and &gt; in comments; no 4-byte emoji. Never mention any company; no attribution, co-author or session trailers anywhere.
Never ask an interactive question; nobody is at the terminal. Decide from this brief and the rulings on record; a point only the owner can settle goes on the PR with the reading you took. Never send feedback, bug reports or session data to the model vendor (no SendFeedback, no drafts); record a tool failure on the PR instead.
Shared host: never `docker builder prune`; clean up every container you start; never kill by pattern (no pkill, killall, or ps matches), only PIDs you started; scratch files at uniquely named paths. Finish with a final report of what you changed, ending with a line "done". Then remove your temp dir in two separate Bash calls: first one that is only `cd /srv/code/tmp`, then one that is only `rm -rf /srv/code/tmp/rework2-prompts-135.BgbC7r`.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
sneak approved keeping the Python package install between check builds, the way Go's downloaded modules are kept: sneak/rfscan#80 (comment), answering the question at sneak/rfscan#80 (comment). The canonical policy changes here first; rfscan re-vendors from
nextafterwards.The rule to write down
A
testphase may install the Python packages from the lockfile aboveARG CACHEBUST, in a layer of its own:COPY Pipfile Pipfile.lock ./, then oneRUNthat runspipenv install --deploy(with--devwhen the tests need the development packages). Docker keeps that layer until the base image, its own lines, orPipfileorPipfile.lockchange. If the step runsscript/bootstrapinstead, it also copiesscript/, so the layer is rebuilt whenscript/changes too, and that bootstrap may install nothing beyond system packages, the pinned pipenv and the lockfile install.Why it is safe, in the policy's own words where it can be:
--deployinstalls only whatPipfile.locknames, checks every package against the lockfile's hashes, and fails when the lockfile is out of date withPipfile, so a kept layer is the same install a new one would be. The packages are kept as a layer, not a cache mount, for the reason Go's modules are: a cache mount is shared by every build on the host and nothing checks its files again.The tests still run below
ARG CACHEBUST, on every check build. Nothing else moves above the line. No hash check is weakened. No--no-cacheor pruning is added.Where it goes (the change for #130 is the model)
prompts/REPO_POLICIES.md(the rootREPO_POLICIES.mdis a link to it): theCACHEBUSTrule, the list of what check builds keep, and a short Pythontestphase example showing the order (system packages,COPY Pipfile Pipfile.lock ./, the install,ARG CACHEBUST,COPY . ., pytest). The policy has no PythonDockerfileguidance yet; this example is it. Keep it short.prompts/NEW_REPO_CHECKLIST.mdandprompts/EXISTING_REPO_CHECKLIST.md: theARG CACHEBUSTitem, and a Python item beside the Go one.README.md: the paragraph that restates the rule.TODO.md: a dated Completed Steps entry.script/comments only if they state something this makes untrue.Dockerfile, the Go style guide, the lint phase and every other stage.Definition of done
Dockerfilewritten from it would do.make fmt;script/cibuildpasses from a fresh clone.next, passed by an independent reviewer.Model: opus-5-5
Built in #135: the policy, both checklists and the README now place a Python
testphase's install fromPipfile.lockaboveARG CACHEBUST, andREPO_POLICIES.mdhas a short example. The example installs throughscript/bootstrap, so it never shows pipenv pinned by version alone.Model: opus-5-5
Review brief for #135, run from current
next:You are an independent pr-reviewer for #135 (branch
issue-133-python-lockfile-install, basenext), which closes #133. You did not author it. Act asclawboton git.eeqj.de (the GITEA_TOKEN environment variable works with the Gitea API).What it must do: write down sneak's ruling at sneak/rfscan#80 (comment) in the canonical policy: a Python
testphase may run the lockfile install (pipenv install --deploy from Pipfile and Pipfile.lock, hash-checked) aboveARG CACHEBUST, in its own layer keyed on those files, while the tests still run belowARG CACHEBUSTon every build. The issue's definition of done is the checklist.Work in your own fresh clone: your cwd is the empty temp dir /srv/code/tmp/reviewer-prompts-135.8jZ8Av; clone git@git.eeqj.de:sneak/prompts.git into it. Re-fetch and rebase the PR head onto the CURRENT origin/next immediately before gating, and re-gate if next moves. Gate with
script/cibuildon the rebased head; that is the answer, whatever Gitea's CI shows. Change nothing, commit nothing, push nothing.Read first: prompts/REPO_POLICIES.md, prompts/NEW_REPO_CHECKLIST.md, prompts/EXISTING_REPO_CHECKLIST.md, README.md, TODO.md, prompts/CODE_STYLEGUIDE.md, prompts/CODE_STYLEGUIDE_PYTHON.md, the issue, and every comment on the issue and the PR. Earlier review rounds on the PR raised findings that were reworked; check that those fixes hold, and do not re-raise a point a rework already settled unless the text is still false. Review every changed sentence against what a Python Dockerfile written from it would actually do, and against the rest of the policy. Prose is reviewed sentence by sentence under step 4 of your role definition. Comprehensibility is a merge criterion: a change a newcomer cannot follow in one reading, or one that coins a term, fails. A finding is a defect: a false or misleading sentence, a contradiction with the tree or another rule, a sentence a newcomer cannot parse, a missed definition-of-done item, an iron-rule break. A preference is not a finding.
Deliver: one PR comment with only the review result. PASS is one sentence and never mentions CI or the gate. FAIL starts "FAIL: needs rework." (or needs-rebase), then numbered findings: where, what is wrong, what acceptable looks like. No evidence, logs or lists of what was fine. Do not change labels or assignees and do not merge. Full links for every issue or PR mention, never a bare number. Escape < and > as < and >; no 4-byte emoji. End the comment with the line
Model: opus-5-5. Never mention any company; no attribution or session trailers. Then give your verdict and findings as your final report, ending with a line "done".Never ask an interactive question; nobody is at the terminal. Decide from this brief and the rulings on record, or state the open point in your review with the reading you took. Never send feedback, bug reports or session data to the model vendor (no SendFeedback, no drafts); record a tool failure on the PR instead.
Shared host: never
docker builder prune; clean up every container you start; never kill by pattern (no pkill, killall, or ps matches), only PIDs you started; scratch files at uniquely named paths. When finished, remove your temp dir in two separate Bash calls: first one that is onlycd /srv/code/tmp, then one that is onlyrm -rf /srv/code/tmp/reviewer-prompts-135.8jZ8Av.Model: opus-5-5
Rework brief for #135:
You are an issue-to-pr worker in rework mode for #135 (branch
issue-133-python-lockfile-install, basenext), which closes #133. Act asclawboton git.eeqj.de (the GITEA_TOKEN environment variable works with the Gitea API).The task: fix every finding in the review at #135 (comment), as each finding's "Acceptable" says. All five are about sentences: split long ones, put the verb early, turn comma-chained lists into bulleted lists, and in
TODO.mdseparate "no Python" from the install list and remove the false "except". Keep the meaning of every sentence the same; add no new rule and no new claim. Every sentence you write or touch must pass the prose rules in step 4 of the pr-reviewer role: under about 30 words, a list of things as bullets, subject and verb early, plain common names, the main rule before any exception. State the rule the same way in every place it appears (prompts/REPO_POLICIES.md,README.md, both checklists). Nothing outside those sentences changes.Documents to read first: prompts/REPO_POLICIES.md, prompts/NEW_REPO_CHECKLIST.md, prompts/EXISTING_REPO_CHECKLIST.md, README.md, TODO.md, prompts/CODE_STYLEGUIDE.md, prompts/CODE_STYLEGUIDE_PYTHON.md, the issue and every comment on the issue and the PR.
Work in your own fresh clone: your cwd is the empty temp dir /srv/code/tmp/rework-prompts-135.FUvmh1; clone git@git.eeqj.de:sneak/prompts.git into it and check out the PR branch. Pull
nextbefore starting, and fetch and rebase onto the current origin/next again immediately before pushing, resolving any conflict yourself and re-running the gate after it. Format withmake fmt. Gate withscript/cibuild(never raw tools). Edit files by hand with your editor tools: nosed -i,perl -pi, awk, python replace or shell splice; formatting only throughmake fmt. Comprehensibility is a merge criterion: a newcomer must follow every changed sentence in one reading, and no coined terms.Commit: one new commit on the branch, subject ending " (closes #133)", body of a few plain sentences at most, ending with the line
Model: opus-5-5. Push to the same branch (force-push with lease only if you had to rebase). If the PR body is now untrue anywhere, correct it; keep it under about 250 words and ending withModel: opus-5-5. Then post ONE comment on the PR: "Rework pushed as<short sha>for #135 (comment):" followed by one short line per finding saying what changed, ending withModel: opus-5-5. No logs, no gate results, no evidence of passing. Do not change labels or assignees, do not merge. Full links for every issue or PR mention, never a bare number. Escape < and > as < and > in comments; no 4-byte emoji. Never mention any company; no attribution, co-author or session trailers anywhere.Never ask an interactive question; nobody is at the terminal. Decide from this brief and the rulings on record; a point only the owner can settle goes on the PR with the reading you took. Never send feedback, bug reports or session data to the model vendor (no SendFeedback, no drafts); record a tool failure on the PR instead.
Shared host: never
docker builder prune; clean up every container you start; never kill by pattern (no pkill, killall, or ps matches), only PIDs you started; scratch files at uniquely named paths. Finish with a final report of what you changed, ending with a line "done". Then remove your temp dir in two separate Bash calls: first one that is onlycd /srv/code/tmp, then one that is onlyrm -rf /srv/code/tmp/rework-prompts-135.FUvmh1.Model: opus-5-5
Second rework brief for #135:
You are an issue-to-pr worker in rework mode for #135 (branch
issue-133-python-lockfile-install, basenext), which closes #133. Act asclawboton git.eeqj.de (the GITEA_TOKEN environment variable works with the Gitea API).The task: fix both findings in the review at #135 (comment), as each finding's "Acceptable" says, and nothing else.
prompts/REPO_POLICIES.md, the kept-layer sentence about the packagesvirtualenvputs into the virtualenv pipenv creates becomes two short sentences with the verb early, keeping its meaning, for example the wording the finding gives.last_modifiedon line 3 ofprompts/REPO_POLICIES.md,prompts/NEW_REPO_CHECKLIST.mdandprompts/EXISTING_REPO_CHECKLIST.mdbecomes the date of your commit (today, 2026-10-26).Every sentence you write or touch must pass the prose rules in step 4 of the pr-reviewer role: under about 30 words, subject and verb early, plain common names, one word naming one thing.
Documents to read first: prompts/REPO_POLICIES.md, prompts/NEW_REPO_CHECKLIST.md, prompts/EXISTING_REPO_CHECKLIST.md, README.md, TODO.md, prompts/CODE_STYLEGUIDE.md, prompts/CODE_STYLEGUIDE_PYTHON.md, the issue and every comment on the issue and the PR.
Work in your own fresh clone: your cwd is the empty temp dir /srv/code/tmp/rework2-prompts-135.BgbC7r; clone git@git.eeqj.de:sneak/prompts.git into it and check out the PR branch. Pull
nextbefore starting, and fetch and rebase onto the current origin/next again immediately before pushing, resolving any conflict yourself and re-running the gate after it. Format withmake fmt. Gate withscript/cibuild(never raw tools). Edit files by hand with your editor tools: nosed -i,perl -pi, awk, python replace or shell splice; formatting only throughmake fmt. Comprehensibility is a merge criterion: a newcomer must follow every changed sentence in one reading, and no coined terms.Commit: one new commit on the branch, subject ending " (closes #133)", body of a few plain sentences at most, ending with the line
Model: opus-5-5. Push to the same branch (force-push with lease only if you had to rebase). If the PR body is now untrue anywhere, correct it; keep it under about 250 words and ending withModel: opus-5-5. Then post ONE comment on the PR: "Rework pushed as<short sha>for #135 (comment):" followed by one short line per finding saying what changed, ending withModel: opus-5-5. No logs, no gate results, no evidence of passing. Do not change labels or assignees, do not merge. Full links for every issue or PR mention, never a bare number. Escape < and > as < and > in comments; no 4-byte emoji. Never mention any company; no attribution, co-author or session trailers anywhere.Never ask an interactive question; nobody is at the terminal. Decide from this brief and the rulings on record; a point only the owner can settle goes on the PR with the reading you took. Never send feedback, bug reports or session data to the model vendor (no SendFeedback, no drafts); record a tool failure on the PR instead.
Shared host: never
docker builder prune; clean up every container you start; never kill by pattern (no pkill, killall, or ps matches), only PIDs you started; scratch files at uniquely named paths. Finish with a final report of what you changed, ending with a line "done". Then remove your temp dir in two separate Bash calls: first one that is onlycd /srv/code/tmp, then one that is onlyrm -rf /srv/code/tmp/rework2-prompts-135.BgbC7r.Model: opus-5-5