golangci-lint now runs only inside the pinned container image, never on the host.
script/lint builds a hash-pinned root Dockerfile.lint. A per-run CACHEBUST build-arg is folded into the lint step's cache key, so BuildKit cannot serve it from cache and the linter re-executes every run, never a cached green that linted nothing. Dockerfile.lint refuses to build without the arg, and script/lint fails any build whose log shows the lint step was skipped.
Dockerfile's lint stage runs golangci-lint directly, not make lint (which now builds a container, and there is no Docker inside a build). Same image and config.
The host install is gone: script/bootstrap no longer fetches or installs golangci-lint (its version/sha256 pins, the release download, the ensure/verify helpers, and the curl dependency they alone used are removed), and golangci-lint is dropped from the nix-shell package lists in the Makefile and script/test, which build and test but never lint.
Why
Owner ruling: linting happens only in a container, so no lint tool belongs on the host.
Disclosures
golangci-lint config verify is excluded: it fetches its schema over an unpinned live HTTPS call, which REPO_POLICIES.md forbids.
Deviation: REPO_POLICIES's lint-stage pattern runs make lint; here it runs golangci-lint directly, forced by the docker-only ruling.
Gate: host has no libvips, so docker build --target builder . under the shared lock; lint, tests, and build all ran. Two script/lint runs both re-executed the linter; a planted violation failed with its finding, then was reverted.
Model: opus-4-8
## What changed
golangci-lint now runs only inside the pinned container image, never on the host.
- `script/lint` builds a hash-pinned root `Dockerfile.lint`. A per-run `CACHEBUST` build-arg is folded into the lint step's cache key, so BuildKit cannot serve it from cache and the linter re-executes every run, never a cached green that linted nothing. `Dockerfile.lint` refuses to build without the arg, and `script/lint` fails any build whose log shows the lint step was skipped.
- `Dockerfile`'s lint stage runs `golangci-lint` directly, not `make lint` (which now builds a container, and there is no Docker inside a build). Same image and config.
- The host install is gone: `script/bootstrap` no longer fetches or installs golangci-lint (its version/sha256 pins, the release download, the ensure/verify helpers, and the curl dependency they alone used are removed), and golangci-lint is dropped from the nix-shell package lists in the Makefile and `script/test`, which build and test but never lint.
## Why
Owner ruling: linting happens only in a container, so no lint tool belongs on the host.
## Disclosures
- `golangci-lint config verify` is excluded: it fetches its schema over an unpinned live HTTPS call, which REPO_POLICIES.md forbids.
- Deviation: REPO_POLICIES's lint-stage pattern runs `make lint`; here it runs `golangci-lint` directly, forced by the docker-only ruling.
- Gate: host has no libvips, so `docker build --target builder .` under the shared lock; lint, tests, and build all ran. Two `script/lint` runs both re-executed the linter; a planted violation failed with its finding, then was reverted.
Model: opus-4-8
PASS: linting runs only inside Docker through script/lint; both cache-defeat and negative-control traps hold (two consecutive runs on an unchanged tree each re-executed the linter, and a planted violation failed the run with its exact finding); every image is pinned by digest; the Dockerfile lint stage and make check lint with the identical command, config, and image; the config verify exclusion is stated; the build leaves no image behind; and the full Docker builder gate is green on a clean rebase onto current next.
Model: opus-4-8
PASS: linting runs only inside Docker through `script/lint`; both cache-defeat and negative-control traps hold (two consecutive runs on an unchanged tree each re-executed the linter, and a planted violation failed the run with its exact finding); every image is pinned by digest; the `Dockerfile` lint stage and `make check` lint with the identical command, config, and image; the `config verify` exclusion is stated; the build leaves no image behind; and the full Docker builder gate is green on a clean rebase onto current `next`.
Model: opus-4-8
Rebased onto the current next. The only conflict was in TODO.md Completed Steps: I kept the existing entry for #92 and placed this change's entry above it. Dockerfile merged cleanly — the lint-stage change here and the signing-key runtime change from #110 are in separate build stages and did not conflict. README.md needed no change: its script/lint description still reads correctly and the Getting Started signing-key text is untouched. The full build gate passed.
Model: opus-4-8
Rebased onto the current `next`. The only conflict was in `TODO.md` Completed Steps: I kept the existing entry for https://git.eeqj.de/sneak/pixa/issues/92 and placed this change's entry above it. `Dockerfile` merged cleanly — the lint-stage change here and the signing-key runtime change from https://git.eeqj.de/sneak/pixa/issues/110 are in separate build stages and did not conflict. `README.md` needed no change: its `script/lint` description still reads correctly and the Getting Started signing-key text is untouched. The full build gate passed.
Model: opus-4-8
Fix the bootstrap issue where it's installing an unneeded binary. You need to not be so sloppy about this. Obviously if we're doing linting in a container, we don't need to be installing linting tools on the host. Clean up after yourself. Remember that.
Fix the bootstrap issue where it's installing an unneeded binary. You need to not be so sloppy about this. Obviously if we're doing linting in a container, we don't need to be installing linting tools on the host. Clean up after yourself. Remember that.
golangci-lint now runs only inside a container, never on the host.
script/lint builds a hash-pinned root Dockerfile.lint; the nix-shell and
host golangci-lint paths are gone. A per-run CACHEBUST build-arg is
folded into the lint step's cache key, so the linter re-executes on every
run and an unchanged tree cannot return a cached success having linted
nothing; script/lint fails a build that did not run the linter.
Dockerfile's lint stage runs golangci-lint directly, since make lint now
builds a container and there is no Docker inside a build. It is the same
image and config. golangci-lint config verify is left out: it fetches its
schema over an unpinned live HTTPS call, which REPO_POLICIES.md forbids.
Model: opus-4-8
The linter runs only inside the pinned golangci-lint container image
(Dockerfile.lint, and the Dockerfile lint stage). Remove the host
install that was still left behind: script/bootstrap's version and
sha256 pins, the release download, the ensure/verify helpers, and the
curl dependency they were the only user of; and drop golangci-lint from
the nix-shell package lists in the Makefile and script/test, which build
and test but never lint.
Model: opus-4-8
Reworked the host-install finding: golangci-lint is no longer installed on the host and now lives only in the pinned container image.
Removed:
script/bootstrap: the golangci-lint version and sha256 pins, the release-archive download, the ensure/verify helpers, and the sole-use curl dependency.
golangci-lint from the nix-shell package lists in the Makefile and script/test, which build and test but never lint.
Rebased onto next.
Model: opus-4-8
Reworked the host-install finding: golangci-lint is no longer installed on the host and now lives only in the pinned container image.
Removed:
- `script/bootstrap`: the golangci-lint version and sha256 pins, the release-archive download, the ensure/verify helpers, and the sole-use curl dependency.
- `golangci-lint` from the nix-shell package lists in the `Makefile` and `script/test`, which build and test but never lint.
Rebased onto `next`.
Model: opus-4-8
PASS: golangci-lint now installs and runs only inside the pinned Docker image and nowhere on the host — script/bootstrap no longer fetches or installs it (its version/sha256 pins, the release download, the ensure/verify helpers, and the curl dependency they alone used are all gone, with no orphaned references and the build/test toolchain still installed), and golangci-lint is dropped from the nix-shell lists in the Makefile and script/test; Dockerfile.lint and the Dockerfile lint stage are pinned to the same digest and run the identical command and config, the cache-defeat trap holds (two consecutive script/lint runs on an unchanged tree each re-executed the linter and a planted violation failed with its exact finding), the full builder gate is green on a clean rebase onto current next, and the PR targets next with the closes keyword and correct model lines throughout — see #104
Model: opus-4-8
PASS: golangci-lint now installs and runs only inside the pinned Docker image and nowhere on the host — `script/bootstrap` no longer fetches or installs it (its version/sha256 pins, the release download, the ensure/verify helpers, and the curl dependency they alone used are all gone, with no orphaned references and the build/test toolchain still installed), and `golangci-lint` is dropped from the nix-shell lists in the `Makefile` and `script/test`; `Dockerfile.lint` and the `Dockerfile` lint stage are pinned to the same digest and run the identical command and config, the cache-defeat trap holds (two consecutive `script/lint` runs on an unchanged tree each re-executed the linter and a planted violation failed with its exact finding), the full builder gate is green on a clean rebase onto current `next`, and the PR targets `next` with the closes keyword and correct model lines throughout — see https://git.eeqj.de/sneak/pixa/issues/104
Model: opus-4-8
“make lint” should invoke strta lint, which should detect if it’s in docker or not and either build the lint container or run the linter. one entrypoint in all cases.
“make lint” should invoke strta lint, which should detect if it’s in docker or not and either build the lint container or run the linter. one entrypoint in all cases.
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.
What changed
golangci-lint now runs only inside the pinned container image, never on the host.
script/lintbuilds a hash-pinned rootDockerfile.lint. A per-runCACHEBUSTbuild-arg is folded into the lint step's cache key, so BuildKit cannot serve it from cache and the linter re-executes every run, never a cached green that linted nothing.Dockerfile.lintrefuses to build without the arg, andscript/lintfails any build whose log shows the lint step was skipped.Dockerfile's lint stage runsgolangci-lintdirectly, notmake lint(which now builds a container, and there is no Docker inside a build). Same image and config.script/bootstrapno longer fetches or installs golangci-lint (its version/sha256 pins, the release download, the ensure/verify helpers, and the curl dependency they alone used are removed), and golangci-lint is dropped from the nix-shell package lists in the Makefile andscript/test, which build and test but never lint.Why
Owner ruling: linting happens only in a container, so no lint tool belongs on the host.
Disclosures
golangci-lint config verifyis excluded: it fetches its schema over an unpinned live HTTPS call, which REPO_POLICIES.md forbids.make lint; here it runsgolangci-lintdirectly, forced by the docker-only ruling.docker build --target builder .under the shared lock; lint, tests, and build all ran. Twoscript/lintruns both re-executed the linter; a planted violation failed with its finding, then was reverted.Model: opus-4-8
PASS: linting runs only inside Docker through
script/lint; both cache-defeat and negative-control traps hold (two consecutive runs on an unchanged tree each re-executed the linter, and a planted violation failed the run with its exact finding); every image is pinned by digest; theDockerfilelint stage andmake checklint with the identical command, config, and image; theconfig verifyexclusion is stated; the build leaves no image behind; and the full Docker builder gate is green on a clean rebase onto currentnext.Model: opus-4-8
66bf9a589dto8dc46af6b7Rebased onto the current
next. The only conflict was inTODO.mdCompleted Steps: I kept the existing entry for #92 and placed this change's entry above it.Dockerfilemerged cleanly — the lint-stage change here and the signing-key runtime change from #110 are in separate build stages and did not conflict.README.mdneeded no change: itsscript/lintdescription still reads correctly and the Getting Started signing-key text is untouched. The full build gate passed.Model: opus-4-8
Fix the bootstrap issue where it's installing an unneeded binary. You need to not be so sloppy about this. Obviously if we're doing linting in a container, we don't need to be installing linting tools on the host. Clean up after yourself. Remember that.
8dc46af6b7tof1c1bffb5aReworked the host-install finding: golangci-lint is no longer installed on the host and now lives only in the pinned container image.
Removed:
script/bootstrap: the golangci-lint version and sha256 pins, the release-archive download, the ensure/verify helpers, and the sole-use curl dependency.golangci-lintfrom the nix-shell package lists in theMakefileandscript/test, which build and test but never lint.Rebased onto
next.Model: opus-4-8
PASS: golangci-lint now installs and runs only inside the pinned Docker image and nowhere on the host —
script/bootstrapno longer fetches or installs it (its version/sha256 pins, the release download, the ensure/verify helpers, and the curl dependency they alone used are all gone, with no orphaned references and the build/test toolchain still installed), andgolangci-lintis dropped from the nix-shell lists in theMakefileandscript/test;Dockerfile.lintand theDockerfilelint stage are pinned to the same digest and run the identical command and config, the cache-defeat trap holds (two consecutivescript/lintruns on an unchanged tree each re-executed the linter and a planted violation failed with its exact finding), the full builder gate is green on a clean rebase onto currentnext, and the PR targetsnextwith the closes keyword and correct model lines throughout — see #104Model: opus-4-8
“make lint” should invoke strta lint, which should detect if it’s in docker or not and either build the lint container or run the linter. one entrypoint in all cases.
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.