Every lint run now happens inside Docker, so the pinned linter (v2.12.2) is used everywhere rather than any host binary.
Changes:
New root Dockerfile.lint (FROM the pinned golangci-lint image) COPYs the tree and runs golangci-lint run --config .golangci.yml ./... as a build step; script/lint is reduced to building it.
A GATE_RUN build arg carries a fresh value each run and the lint layer references it, so it always executes. Caching is waived.
script/bootstrap no longer installs golangci-lint (docker is the only prerequisite now; the #184 goimports install is untouched).
The main Dockerfile lint stage invokes golangci-lint directly instead of make lint, avoiding docker-in-docker while still failing the full build fast on lint errors.
config verify decision: NOT run — it fetches its JSON schema over an unpinned live HTTPS call, which REPO_POLICIES.md's hash-pinning rule forbids with zero exceptions.
Verification:
Two consecutive script/lint runs on an unchanged tree both executed the linter (~70s each to 0 issues.), not cached.
Negative control: an added unused function made lint FAIL with func negativeControlUnused is unused (unused); reverting returned 0 issues..
make check green; full docker build . green.
Disclosure: REPO_POLICIES.md still documents RUN make lint in the lint stage; this 2026-08-09 owner ruling supersedes that for the lint step. .golangci.yml unchanged.
Model: opus-4-8
Every lint run now happens inside Docker, so the pinned linter (v2.12.2) is used everywhere rather than any host binary.
Changes:
- New root `Dockerfile.lint` (FROM the pinned golangci-lint image) COPYs the tree and runs `golangci-lint run --config .golangci.yml ./...` as a build step; `script/lint` is reduced to building it.
- A `GATE_RUN` build arg carries a fresh value each run and the lint layer references it, so it always executes. Caching is waived.
- `script/bootstrap` no longer installs golangci-lint (docker is the only prerequisite now; the #184 goimports install is untouched).
- The main `Dockerfile` lint stage invokes `golangci-lint` directly instead of `make lint`, avoiding docker-in-docker while still failing the full build fast on lint errors.
`config verify` decision: NOT run — it fetches its JSON schema over an unpinned live HTTPS call, which REPO_POLICIES.md's hash-pinning rule forbids with zero exceptions.
Verification:
- Two consecutive `script/lint` runs on an unchanged tree both executed the linter (~70s each to `0 issues.`), not cached.
- Negative control: an added unused function made lint FAIL with `func negativeControlUnused is unused (unused)`; reverting returned `0 issues.`.
- `make check` green; full `docker build .` green.
Disclosure: REPO_POLICIES.md still documents `RUN make lint` in the lint stage; this 2026-08-09 owner ruling supersedes that for the lint step. `.golangci.yml` unchanged.
Model: opus-4-8
golangci-lint now runs only in Docker. New Dockerfile.lint (pinned
golangci-lint v2.12.2) COPYs the tree and runs the linter as a build
step; script/lint just builds it. A GATE_RUN build arg differs every
run, so the lint layer always executes -- a cached build would exit 0
having linted nothing.
config verify is deliberately omitted: it fetches its JSON schema over
an unpinned live HTTPS call, which REPO_POLICIES.md forbids.
script/bootstrap no longer installs golangci-lint (goimports kept). The
main Dockerfile lint stage now invokes golangci-lint directly rather
than make lint, so building it is not docker-in-docker.
Model: opus-4-8
PASS — linting now runs only in Docker via the pinned Dockerfile.lint, the GATE_RUN build arg forces the lint layer to re-execute on every script/lint run (verified: two consecutive runs on an unchanged tree both ran the linter, and an injected unused function failed the build with that exact finding before reverting to clean), the main Dockerfile lint stage invokes golangci-lint directly while still gating the build via COPY --from=lint, config verify is deliberately omitted for its unpinned schema fetch, .golangci.yml is untouched, and both make check and the full docker build . are green.
Model: opus-4-8
PASS — linting now runs only in Docker via the pinned `Dockerfile.lint`, the `GATE_RUN` build arg forces the lint layer to re-execute on every `script/lint` run (verified: two consecutive runs on an unchanged tree both ran the linter, and an injected unused function failed the build with that exact finding before reverting to clean), the main `Dockerfile` lint stage invokes `golangci-lint` directly while still gating the build via `COPY --from=lint`, `config verify` is deliberately omitted for its unpinned schema fetch, `.golangci.yml` is untouched, and both `make check` and the full `docker build .` are green.
Model: opus-4-8
clawbot
merged commit d946fa68f9 into next2026-09-22 12:11:19 +02:00
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.
Every lint run now happens inside Docker, so the pinned linter (v2.12.2) is used everywhere rather than any host binary.
Changes:
Dockerfile.lint(FROM the pinned golangci-lint image) COPYs the tree and runsgolangci-lint run --config .golangci.yml ./...as a build step;script/lintis reduced to building it.GATE_RUNbuild arg carries a fresh value each run and the lint layer references it, so it always executes. Caching is waived.script/bootstrapno longer installs golangci-lint (docker is the only prerequisite now; the #184 goimports install is untouched).Dockerfilelint stage invokesgolangci-lintdirectly instead ofmake lint, avoiding docker-in-docker while still failing the full build fast on lint errors.config verifydecision: NOT run — it fetches its JSON schema over an unpinned live HTTPS call, which REPO_POLICIES.md's hash-pinning rule forbids with zero exceptions.Verification:
script/lintruns on an unchanged tree both executed the linter (~70s each to0 issues.), not cached.func negativeControlUnused is unused (unused); reverting returned0 issues..make checkgreen; fulldocker build .green.Disclosure: REPO_POLICIES.md still documents
RUN make lintin the lint stage; this 2026-08-09 owner ruling supersedes that for the lint step..golangci.ymlunchanged.Model: opus-4-8
PASS — linting now runs only in Docker via the pinned
Dockerfile.lint, theGATE_RUNbuild arg forces the lint layer to re-execute on everyscript/lintrun (verified: two consecutive runs on an unchanged tree both ran the linter, and an injected unused function failed the build with that exact finding before reverting to clean), the mainDockerfilelint stage invokesgolangci-lintdirectly while still gating the build viaCOPY --from=lint,config verifyis deliberately omitted for its unpinned schema fetch,.golangci.ymlis untouched, and bothmake checkand the fulldocker build .are green.Model: opus-4-8