Skip to content

guard: a build that cannot run is not a build that refused - #71

Merged
donislawdev merged 1 commit into
mainfrom
stability/linux-check-tags
Sep 6, 2026
Merged

guard: a build that cannot run is not a build that refused#71
donislawdev merged 1 commit into
mainfrom
stability/linux-check-tags

Conversation

@donislawdev

Copy link
Copy Markdown
Owner

Closes O182, which had been open with the cause unknown and was blocking linux-check as a pre-push gate. The repository half is the one file below. The other half is in tools/, which lives outside this repository.

O182 was not what it looked like

The recorded symptom: tools/linux-check.py failed five stored screens in a container while CI on real Linux passed the same commit, differing by at most 1 of 255 in one channel on 36 to 403 pixels out of 1 430 000. The leading guess was fonts missing from the image.

It was the build tags. golang.org/x/image/vector is the rasteriser on the screen-drawing path, and it picks its coverage accumulator on exactly that tag:

  • acc_amd64.go - //go:build !appengine && gc && !noasm - SIMD
  • acc_other.go - the fallback - pure Go

The two round antialiasing differently by one part in 255. linux-check.py built without the tags, so it compared the stored screens against a binary nobody ships. The screens and CI, which both pass the tags, were right all along.

Proven rather than argued. Same commit f492f79, same image, same container, same CPU, one variable:

build result
without -tags noasm FAIL - 36 and 403 pixels, at most 1 of 255
with -tags noasm PASS

Those are O182's recorded numbers to the digit. The header claim in linux-check.py that nothing from the image is used stands, and the identical to the byte measurement from 2026-08-23 is consistent - the tag did not exist until 2026-08-29.

What this PR fixes

Fixing the above surfaced a third thing underneath, and it is the part that belongs in this repository.

TestABuildWithoutTheBuildTagsRefusesAndSaysWhy shells out to the compiler and treats any error as the refusal it is looking for. A missing compiler arrives the same way. So in the container - which has no Go in it by design - it reported that the refusal does not name build tags, with the message empty, blaming the refusal rather than the environment. It was the only test of the whole suite to fail there.

This one cannot use the an error means skip shape that the other ten callers of the toolchain in this package use, because here an error is the answer. So it asks exec.LookPath first, the same idiom and for the same reason as TestABuildWithNoWindowInItSaysSoAndKeepsStandardOutputEmpty.

Textbook O118: a guard that stopped reaching the state it guards.

Checks

  • Still passes where a compiler exists, so the skip did not quietly make it a no-op
  • Its existing mutation still turns it red
  • amd64: the whole guard suite now passes in the container. arm64 is emulated and was still running when this was opened
  • preflight --quick green on all 12 checks

Found in passing, not fixed here

Several other tools still hand our packages to the compiler without the tags, and since 15c2c2e that does not compile at all. tools/format-status.py is confirmed broken by running it, and preflight's coverage check had the same omission - it is not part of --quick, which is why a green quick run never showed it. Both are fixed in the tools/ commit. The rest is a sweep worth doing on its own.

🤖 Generated with Claude Code

TestABuildWithoutTheBuildTagsRefusesAndSaysWhy shells out to the compiler and
treats any error as the refusal it is looking for. A missing compiler arrives
the same way, so on a machine with no Go it reported that the refusal "does
not name build tags" - with the message empty, blaming the refusal rather
than the environment.

Measured on 2026-09-06: that is exactly what it did in the container
tools/linux-check.py uses, which has no Go in it by design. It was the only
test of the whole suite to fail there.

This one cannot use the "an error means skip" shape the other ten callers of
the toolchain use, because here an error is the answer. So it asks
exec.LookPath first, the same idiom and for the same reason as
TestABuildWithNoWindowInItSaysSoAndKeepsStandardOutputEmpty.

Still passes where a compiler exists, and its existing mutation still turns it
red, so the skip did not quietly make it a no-op.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@donislawdev
donislawdev merged commit 0a0ef24 into main Sep 6, 2026
18 checks passed
@donislawdev
donislawdev deleted the stability/linux-check-tags branch September 6, 2026 19:24
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