Go + Standard Toolchain
Category: Tech Stack · Areas: all
Description
Category
tech-stack
Areas
all
Slot
language-runtime
Components
- Language: Go (version pinned in
go.mod) - Build system:
go build/go test(standard toolchain) - Formatter:
gofmt(non-negotiable) - Linter:
golangci-lintwith.golangci.ymlconfig - Security scanner:
gosec+govulncheck - CLI framework: Cobra (for CLI projects)
- Testing:
go testwith build tags for test levels
Constraints
- All code must pass
gofmt -l .(zero diff) - All code must pass
go vet ./... - All code must pass
golangci-lint runwith project.golangci.yml - Errors must be wrapped with context:
fmt.Errorf("context: %w", err)— no nakedreturn err - No
panicoutside ofmain()or initialization — return errors - Pass
context.Contextas first parameter to functions that do I/O or may be cancelled - Define interfaces in the consuming package, not the providing package
- Version metadata embedded at build time via
-ldflags "-X main.Version=..." govulncheck ./...must pass (no known vulnerabilities)
Lint Policy (golangci-lint baseline)
Enabled linters:
govet(withenable-all, disablefieldalignment)staticcheckineffassignmisspellunconvertgosec(severity: high, confidence: high)gocritic(diagnostic, performance, style tags)
Disabled linters (too opinionated):
wsl,wrapcheck,varnamelen,nlreturn,exhaustructparalleltest,testpackage,mnd,funlen
Generated files (.pb.go, .gen.go, mock_*.go) excluded from linting.
When to use
All Go projects — CLIs, services, libraries. The standard toolchain and
go fmt are universal; golangci-lint + gosec are the quality layer on top.
Artifact Impact
Selecting this concern requires these artifacts to change (a selected concern absent from them is drift):
- ADR: Go + standard toolchain (gofmt, golangci-lint, gosec, govulncheck) as the language-runtime
- TD: error-wrapping, context-passing, interface-in-consumer conventions; lint baseline
Practices by activity
Agents working in any of these activities inherit the practices below through runtime work context, such as a DDx bead context digest.
Requirements (Frame activity)
- Specify minimum Go version in
go.mod - Identify test levels needed: unit, integration (VCR/stubbed), functional (binary), E2E (live)
- If the project hits external HTTP APIs, plan for VCR recording in integration tests
Design
- Package layout:
cmd/for CLI entry points,internal/for application logic - Define interfaces in the consumer package; return concrete types where practical
- Use minimal, consumer-driven interfaces
- Guard shared state explicitly; prefer immutable data; use
errgroupfor concurrent work - Embed version metadata:
Version,BuildTime,GitCommitvia-ldflags
Implementation
- Formatting:
go fmt ./...(run before every commit — enforced bygofmt -l .check) - Error wrapping:
fmt.Errorf("context: %w", err)— always add context - Sentinel errors: define with
errors.Newfor expected conditions; compare witherrors.Is - Concurrency: pass
context.Contextfirst; useerrgroup.WithContextfor fan-out; avoid goroutine leaks - Logging: structured with
log/slog(stdlib) or project-chosen structured logger; nofmt.Print*in library code - No
panicoutside startup; inmain(), convert panics to fatal log + exit
Testing
- Run with:
go test ./... - Race detection:
go test -race ./...for concurrent code - Build tags for test levels:
- (no tag): fast unit tests, no external deps
-tags=integration: VCR playback, no live APIs-tags=functional: built binary CLI tests-tags=e2e: live API tests (requires credentials)
- Table-driven tests for pure functions
- HTTP stubs: VCR cassette recording (
VCR_MODE=recordto capture,VCR_MODE=playbackfor CI) - Use
testify/assertortestify/requirefor assertions; not baret.Fatalcomparisons - Coverage:
go test -coverprofile=coverage.out ./...+go tool cover -func; 80% threshold
Quality Gates (pre-commit / CI)
go fmt ./...(orgofmt -l .check)go vet ./...golangci-lint rungosec ./...(high severity/confidence)govulncheck ./...go test -race ./...(unit + integration tags)
Dependency Management
go mod tidyafter any dependency changego mod downloadfor reproducible builds- No vendoring unless required by deployment constraints
govulncheck ./...before releases