Summary
The custom linter driver runs multichecker.Main(...) over ./cmd/... ./pkg/... (Makefile:725) under the CI host's default build (GOOS=linux, no -tags). go/packages therefore never loads files gated by other build constraints, so every //go:build js || wasm file — roughly 20 *_wasm.go production files across pkg/console, pkg/workflow, pkg/parser, pkg/styles, pkg/tty — is invisible to all 39 custom analyzers, including the 16 CI-enforced ones.
This is not theoretical. It has already let a real violation drift in.
Concrete proof: a hidden sprintfint true-positive
The default-build and wasm variants of renderContext diverged when the strconv.Itoa conversion was applied to only one side:
| File (build) |
Line |
Code |
pkg/console/console.go (default) |
110 |
lineNumWidth := len(strconv.Itoa(maxLineNum)) ✅ converted |
pkg/console/console_wasm.go (js||wasm) |
41 |
lineNumWidth := len(fmt.Sprintf("%d", maxLineNum)) ❌ un-migrated |
maxLineNum := err.Position.Line + len(err.Context)/2 is int (console_types.go:6 Line int), so console_wasm.go:41 is an exact sprintfint violation. The default sibling was already fixed; the wasm sibling was silently missed because the linter never analyzes it. Any of the 16 enforced analyzers could have similar undetected drift in the wasm implementation.
Recommendations
- Fix the concrete drift — convert
console_wasm.go:41 to match its sibling:
len(fmt.Sprintf("%d", maxLineNum)) → len(strconv.Itoa(maxLineNum))
- add
"strconv" to the imports of console_wasm.go (it currently imports only fmt, os, strings; fmt is still used elsewhere in the file, e.g. :47).
- Close the blind spot — add a second custom-lint pass covering the wasm build in
cgo.yml, e.g. run make golint-custom a second time with GOOS=js GOARCH=wasm (or a -tags variant) so *_wasm.go files are analyzed. Sequence after step 1 so the new pass starts green.
Validation checklist
Effort: S for the concrete fix; M for the CI second-pass wiring.
Generated by 🤖 Sergo - Serena Go Expert · 252.6 AIC · ⌖ 13.6 AIC · ⊞ 5.9K · ◷
Summary
The custom linter driver runs
multichecker.Main(...)over./cmd/... ./pkg/...(Makefile:725) under the CI host's default build (GOOS=linux, no-tags).go/packagestherefore never loads files gated by other build constraints, so every//go:build js || wasmfile — roughly 20*_wasm.goproduction files acrosspkg/console,pkg/workflow,pkg/parser,pkg/styles,pkg/tty— is invisible to all 39 custom analyzers, including the 16 CI-enforced ones.This is not theoretical. It has already let a real violation drift in.
Concrete proof: a hidden
sprintfinttrue-positiveThe default-build and wasm variants of
renderContextdiverged when thestrconv.Itoaconversion was applied to only one side:pkg/console/console.go(default)lineNumWidth := len(strconv.Itoa(maxLineNum))✅ convertedpkg/console/console_wasm.go(js||wasm)lineNumWidth := len(fmt.Sprintf("%d", maxLineNum))❌ un-migratedmaxLineNum := err.Position.Line + len(err.Context)/2isint(console_types.go:6 Line int), soconsole_wasm.go:41is an exactsprintfintviolation. The default sibling was already fixed; the wasm sibling was silently missed because the linter never analyzes it. Any of the 16 enforced analyzers could have similar undetected drift in the wasm implementation.Recommendations
console_wasm.go:41to match its sibling:len(fmt.Sprintf("%d", maxLineNum))→len(strconv.Itoa(maxLineNum))"strconv"to the imports ofconsole_wasm.go(it currently imports onlyfmt,os,strings;fmtis still used elsewhere in the file, e.g.:47).cgo.yml, e.g. runmake golint-customa second time withGOOS=js GOARCH=wasm(or a-tagsvariant) so*_wasm.gofiles are analyzed. Sequence after step 1 so the new pass starts green.Validation checklist
console_wasm.go:41usesstrconv.Itoa;strconvimported;go buildforGOOS=js GOARCH=wasm ./cmd/gh-aw-wasmstill compiles.*_wasm.gofiles in CI.Sprintf("%d", <int>)(or other enforced-linter patterns) remain in build-tagged files.Effort: S for the concrete fix; M for the CI second-pass wiring.