Gox isn't your typical Go linter. Dropped onto Hacker News this week by Menta Systems, this static analyzer takes a fundamentally different approach: every rule is an error, not a warning, and opting out requires inline annotations with written justifications. The tool targets one specific audience—LLM agents writing Go code without human line-by-line review—and it shows in every design decision.
The Bug Class That Motivated Everything
The namedargs rule is gox's killer feature. It catches the swap-prone call site: transfer(orderID, userID) versus transfer(userID, orderID). Both compile. Both pass tests. Neither triggers a runtime error until your ledger looks like Swiss cheese. Gox forces inline /* paramName */ comments at call sites where two adjacent arguments share a basic type (string, int, bool), making parameter swapping a hard failure rather than silent corruption. Stdlib calls remain exempt because their conventions are well-understood, but user-defined functions get the full treatment. The tradeoff is explicit: more typing at the call site, near-zero bugs of this class—when AI agents generate code at tokens-per-second speed with no reviewer watching, "more typing" costs nothing.
Zero Dependencies and Fail-Closed Philosophy
Gox implements every rule from scratch using only go/ast, go/types, and go list. No golang.org/x/tools, no third-party linter packages, no transitive dependency hell to maintain. When a new Go version drops, Menta Systems notes there is nothing to update—a direct shot at tools that require constant dependency maintenance. The current rule set spans 11 analyzers: errcheck catches dropped error returns, shadow catches variable re-declarations (except ok), forcetypeassert flags non-comma-ok type assertions, noglobals prevents mutable package-level vars, banany restricts any/interface{} usage without justification, bodyclose tracks unclosed HTTP response bodies, contextcheck finds spurious context.Background()/TODO() calls inside functions already receiving a Context, and goroutine detects go f() invocations without visible synchronization primitives. Each rule defaults to error severity; each opt-out requires an annotation with a reason on the same line.
Claude Code Integration Out of the Box
Gox ships with built-in Claude Code integration that wires it directly into the agent's tool loop. Running gox install claude writes ~/.claude/gox-hook.sh and registers it as a PostToolUse hook in settings.json, triggering gox check . whenever Claude edits a .go file. If issues surface, the hook returns decision:block with full output—Claude must fix or annotate before continuing. The hook resolves via $GOX_BIN if set, otherwise ~/go/bin/gox, and activates in new sessions (or after opening /hooks in current ones). This is not a pre-commit hook you have to configure yourself; it's an opinionated gate that runs every time the AI touches code.
Performance on Large Codebases
On a 442-package monorepo spanning roughly 1,800 .go files, gox cold-runs in approximately 9.4 seconds with warm cache hits dropping to 2.6 seconds. The cache lives under $XDG_CACHE_HOME/gox/v2 (or ~/.cache/gox/v2), keyed by file mtime and analyzer set hash, with a --no-cache flag available for CI scenarios. Generated code files marked with // Code generated
How Gox Differs From the Established Players
Menta Systems draws a clear line: existing linters like golangci-lint, staticcheck, and revive are detectors that surface warnings for humans to decide. Gox is a gate designed for autonomous agents where surfacing a warning means it gets ignored unless something downstream refuses to proceed. The comparison table in the project README makes this explicit—default severity (error versus warning), opt-out mechanism (inline annotations with reasons versus regex/path config files), dependency footprint (stdlib only versus hundreds of transitive deps via golang.org/x/tools), and target audience (LLM agents versus humans in CI). If you already run golangci-lint, Menta Systems says keep it: "golangci-lint is the spell-checker, gox is the production gate."
Installation and Current Status
Install is a single command: go install github.com/mentasystems/gox/cmd/gox@latest. The tool exposes gox check ./... for analysis (exits 1 on any issue), gox list to see registered analyzers, gox build for check-then-build workflows, and gox test for check-then-test scenarios. Status remains experimental—expect breaking changes to annotation syntax until v1.0. Contributing guidelines enforce the zero-dependency philosophy: new rules must be implementable with Go stdlib plus go list -json calls; third-party linter imports are explicitly out of scope.
Key Takeaways
- Namedargs catches parameter-swap bugs that compile and pass tests but corrupt production state
- Zero external dependencies means no maintenance burden when Go versions update
- Claude Code integration runs gox check automatically on every file edit as a PostToolUse hook
- Every rule is an error with opt-outs requiring inline annotations containing written justifications
- Designed to complement golangci-lint, not replace it—gate versus detector
The Bottom Line
Gox represents a pragmatic shift in how we think about AI-generated code quality: stop surfacing warnings that autonomous agents will ignore and start failing builds until the agent provides explicit justification for each deviation. Namedargs alone justifies the entire project—if you've ever debugged a ledger mismatch caused by swapped string parameters, you understand why this class of bug deserves a hard stop rather than a yellow highlight in your IDE.