chore(lint): enable twenty low-noise linters and clear what they found - #6981
Merged
Conversation
Each of these reported at most a handful of findings on the current tree, so they cost one cleanup and then hold the line for free. They were picked by running every candidate linter against all six modules and keeping the ones the codebase already almost satisfies. Three finds were worth the exercise on their own. ErruthDeviceNoIdentity was missing a letter and now matches the NewErrAuthDeviceNoIdentity that wraps it. The Postgres URI was assembled with Sprintf, which produces an unparseable address the day the host is IPv6. Identity mixed pointer and value receivers, and WriteTo has to keep the pointer because it deliberately accepts a nil receiver, so WithoutUserScope copies through one instead. The Signature structs the agent marshals for public-key auth now carry explicit json tags. The server signs those bytes without parsing them, so the keys are internal to a single round-trip, and pinning them keeps a field rename from silently changing what gets signed.
otavio
force-pushed
the
chore/lint-tier0
branch
from
August 28, 2026 19:43
cacc299 to
a6c2d18
Compare
Member
Author
|
/review |
|
Claude finished @otavio's task in 1m 17s —— View job Code Review CompleteReviewed 22 files across code quality, security, testing, language patterns, and architecture — no new issues found. The code looks good as-is. A few notes I verified while reviewing (all clean, no action needed):
To request another review round, comment |
This was referenced Aug 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Enables twenty golangci-lint linters that the codebase already almost satisfies, and fixes the 29 findings they report.
Why
Conventions that only live in prose drift. I ran every candidate linter golangci-lint offers against all six modules and counted the findings; these twenty came back at zero to five each, so they cost one cleanup and then hold the line for free, on human commits and agent-written code alike.
Grouped in the config by what they defend:
sqlclosecheck,rowserrcheckdurationcheck,asasalint,makezero,nilnesserr,wastedassign,reassign,predeclared,recvcheck,fatcontext,nosprintfhostport,musttag,iotamixing,unqueryveterrname,intrange,usestdlibvars,mirror,exptostd,tparallelChanges
Three findings were worth the exercise on their own:
ErruthDeviceNoIdentitywas missing a letter. It now matches theNewErrAuthDeviceNoIdentityconstructor that wraps it (errname).Sprintf, which yields an unparseable address the day the host is IPv6. Nownet.JoinHostPort(nosprintfhostport).Identitymixed pointer and value receivers.WriteTokeeps the pointer because it deliberately tolerates a nil receiver — that nil check is load-bearing for the anonymous path — soWithoutUserScopecopies through a pointer receiver instead (recvcheck).The rest: three dead initialisations, three params shadowing the builtin
max, an unexported sentinel renamed toerrValidator, a missingt.Parallel(),x/exp/slicesswapped for the stdlib, and101forhttp.StatusSwitchingProtocols.golang.org/x/expwas only reachable through that one import, sogo mod tidydrops it from thetestsmodule.Signature json tags.
musttagflagged the four localSignaturestructs the agent marshals for public-key auth. The server hashes and signsreq.Datawithout ever parsing it, so the JSON keys are internal to a single round-trip and the tags are behaviour-preserving. They are worth pinning: a field rename would otherwise change what gets signed, silently.Not included
bodyclosewas in the original candidate set and is held back deliberately. Its six findings are all gorilla WebSocket dials that discard the*http.Response, so fixing them means changing handshake error paths in connection code. That belongs in its own change, not one whose premise is "these cost nothing".Testing
Under
golang:1.26.7-alpine3.24:golangci-lint run ./...reports0 issuesfor all seven entry points — root,server,agent,gateway,openapi,tests,pkggo build ./...clean for every module, plusagentunder both-tags dockerand-tags nativego test ./...passes for root,server, andagentunder-tags dockergo mod tidyleaves only the intendedx/expremovalhttps://claude.ai/code/session_01D4BSojj4fmh3ZQSZWkGbD8