headroom.walls.sh · go
Go's strong conventions — table-driven tests, explicit error returns, interface-based design — are exactly the kind of patterns Claude Code applies consistently at scale. Writing 50 table test cases, adding error wrapping across 30 functions, or redesigning an interface to satisfy a new constraint: all systematic work that Claude Code handles well. This page covers Go-specific workflows.
## Build and test
- Build: go build ./...
- Test: go test ./...
- Vet: go vet ./...
- Lint: staticcheck ./...
- Race: go test -race ./...
## Conventions
- Error wrapping: fmt.Errorf("context: %w", err)
- No naked returns in functions longer than 3 lines
- All exported types and functions need doc comments
- Table-driven tests — no single-case test functions
Claude Code reads this at session start. It will use go test ./... as the verification step and apply error wrapping consistently rather than mixing styles.
Go's table-driven test pattern is idiomatic and Claude Code applies it correctly:
claude "add table-driven tests for the Parse function in pkg/parser/parser.go — cover happy paths, malformed input, empty input, and boundary cases. Run go test ./pkg/parser/... after."
Claude Code reads the function signature and returns, writes a []struct test table covering the cases you specify, and runs the tests to confirm they pass. It follows the existing test file style — if your project uses t.Run subtests, it will too.
Adding consistent error wrapping across a package:
claude "find all functions in pkg/storage/ that return errors without wrapping context. Add fmt.Errorf wrapping with a description of what operation failed. Run go vet after."
claude "the error messages in this package are inconsistent — some say 'failed to X', some say 'X failed', some say 'error X-ing'. Standardize them to 'failed to X: ...' format across pkg/api/."
Claude Code reads each function, finds the bare return err statements, and wraps them with a description of what the function was doing when the error occurred — not just the generic function name, but the specific operation.
Extracting interfaces from concrete types (the Go "accept interfaces, return structs" pattern):
claude "the database package passes a *sql.DB everywhere. Extract a DB interface with just the methods we actually call, and update the callers to use the interface. This will make the code testable with a mock."
claude "design a Cache interface that both the in-memory cache and the Redis cache should implement. Read both implementations first and extract the common method set."
Claude Code reads the concrete type usage, identifies which methods are actually called, and writes the minimal interface — not one method more than necessary.
claude "run go vet ./... and staticcheck ./... — fix every warning. Don't suppress them with nolint comments unless there's a genuine reason."
Claude Code works through vet and staticcheck output systematically. For each warning it reads the flagged code, understands why the linter flagged it, and fixes the underlying issue — not the symptom.
Common issues it fixes correctly:
claude "the worker pool in pkg/processor/pool.go uses a channel but leaks goroutines on context cancellation. Read the code and fix the cancellation handling."
claude "add a semaphore to limit concurrent goroutines in the batch processor — max 10 at a time. Use a buffered channel, not sync primitives."
claude "run go test -race ./... — there's a data race in the cache. Find it and fix it with proper synchronization."
For concurrency bugs, the race detector output is exactly the kind of structured error message Claude Code can act on — it names the goroutines and the memory address involved.
Go struct tags use backtick syntax. Claude Code handles them correctly:
claude "add json tags to all exported struct fields in pkg/models/ — use snake_case for the field names. Add omitempty to pointer and slice fields."
claude "add validate tags to the UserRequest struct fields using the go-playground/validator conventions: required, email, min, max."
Claude Code reads the struct, infers the correct tag values from field names and types, and writes idiomatic tags — including omitempty for optional fields and - for fields that should be excluded from marshaling.
claude "run go mod tidy and explain what changed — which dependencies were added, removed, or version-bumped."
claude "there's a dependency conflict between pkg/a and pkg/b on different versions of the same module. Read go.mod and go.sum, find the conflict, and resolve it with a replace directive or version upgrade."
Systematic Go work — adding tests, fixing vet warnings, wrapping errors across a package — accumulates Claude Code session budget faster than individual edits. Headroom shows your 5h session and 7d weekly utilization live in the macOS menu bar. No token, no API key — reads the file Claude Code writes to ~/.claude/.
Install in one line:
Color-coded from calm to amber to red. Know your headroom before a codebase-wide test sweep.
→ Writing tests with Claude Code
→ Refactoring with Claude Code
→ Claude Code + Zed editor
→ 5-hour session limit explained