1# Go baseline
2
3Start from Amolith's strict Go baseline, then adapt it deliberately with the
4user and the project in front of you. This file is for Go tooling,
5architecture, libraries, tests, packaging, and build workflow, not for copying a
6boilerplate blindly.
7
8## Go operating mode
9
101. Inspect `go.mod`, existing task runner, build files, packaging files, UI
11 surface, and tests.
122. Classify the project: library, CLI, TUI, MCP server, light web app, Wails
13 desktop app, frontend-heavy app, service, or some mix.
143. Start from the strict baseline, then relax, remove, or add further pieces only
15 when the project needs them.
164. Verify each slice with the narrowest useful `mise run ...` task.
17
18Do not introduce Taskfiles or justfiles by default. If an older project uses
19Task or just, translate the useful commands into `mise.toml` unless the user
20explicitly asks to keep the old runner.
21
22## Defaults
23
24Default to:
25
26- `mise.toml` for tools and tasks
27- `golangci-lint fmt` for formatting
28- `golangci-lint run --enable-only modernize --fix ./...` for modernization
29- `golangci-lint run --fix` for lint fixes
30- `govulncheck ./...` for vulnerability scanning
31- slower, race-enabled tests in development: `go test -v -race -count=5 -p=3
32 -timeout=5m ./...`, with `CGO_ENABLED=1` for the test task
33- pure-Go static release builds for CLIs, TUIs, and MCP servers when the project
34 does not require CGO
35- explicit build/install tasks for binaries
36- nFPM when shipping native Linux packages
37- small packages with domain names, not generic `utils`
38- standard library first unless a preferred library clearly fits
39- Amolith's licensing convention when the project does not already say
40 otherwise: CC0 for docs/examples/config/prompt text, MutuaL for meaningful code
41
42Use this `.golangci.toml` shape unless the project already has a stronger local
43configuration. Replace the module path placeholders with the module from
44`go.mod`:
45
46```toml
47version = "2"
48
49[linters]
50enable = ["bodyclose", "errcheck", "errorlint", "exhaustive", "gocognit", "govet", "ineffassign", "modernize", "nilerr", "nilnil", "noctx", "revive", "staticcheck", "unused"]
51
52[linters.settings.gocognit]
53min-complexity = 15
54
55[[linters.settings.revive.rules]]
56name = "file-length-limit"
57arguments = [{ max = 1000, skip-comments = true, skip-blank-lines = true }]
58
59[[linters.settings.revive.rules]]
60name = "max-control-nesting"
61arguments = [5]
62
63[formatters]
64enable = ["goimports", "gofumpt", "gci", "golines"]
65
66[formatters.settings.goimports]
67local-prefixes = ["<module-path>"]
68
69[formatters.settings.gofumpt]
70module-path = "<module-path>"
71
72[formatters.settings.gci]
73sections = ["standard", "default", "localmodule"]
74
75[formatters.settings.golines]
76max-len = 120
77```
78
79Default away from:
80
81- Taskfiles and justfiles in new setup
82- clix/kong, even when another Go skill recommends it; use stdlib flags for tiny
83 tools and Cobra + Fang for user-facing CLIs
84- generated wrappers around one command
85- large frontend stacks for light server-rendered pages
86- configuration frameworks when direct parsing is enough
87- hidden global state unless a test seam restores it with `t.Cleanup`
88
89Use generic Go skills for implementation details, but this skill wins for
90Amolith-specific setup choices: mise, golangci-lint formatting/fixing,
91modernize, static build shape, CLI framework, packaging, Wails frontend stack,
92web styling posture, and explicit gocuke adoption.
93
94Gocuke is an explicit project choice. Ask whether the project wants gocuke/BDD
95automation; if yes, load the gocuke skill after behaviour is formulated. If no,
96use ordinary Go tests.