Go baseline
Start from Amolith's strict Go baseline, then adapt it deliberately with the user and the project in front of you. This file is for Go tooling, architecture, libraries, tests, packaging, and build workflow, not for copying a boilerplate blindly.
Go operating mode
- Inspect
go.mod, existing task runner, build files, packaging files, UI surface, and tests. - Classify the project: library, CLI, TUI, MCP server, light web app, Wails desktop app, frontend-heavy app, service, or some mix.
- Start from the strict baseline, then relax, remove, or add further pieces only when the project needs them.
- Verify each slice with the narrowest useful
mise run ...task.
Do not introduce Taskfiles or justfiles by default. If an older project uses
Task or just, translate the useful commands into mise.toml unless the user
explicitly asks to keep the old runner.
Defaults
Default to:
mise.tomlfor tools and tasksgolangci-lint fmtfor formattinggolangci-lint run --enable-only modernize --fix ./...for modernizationgolangci-lint run --fixfor lint fixesgovulncheck ./...for vulnerability scanning- slower, race-enabled tests in development:
go test -v -race -count=5 -p=3 -timeout=5m ./..., withCGO_ENABLED=1for the test task - pure-Go static release builds for CLIs, TUIs, and MCP servers when the project does not require CGO
- explicit build/install tasks for binaries
- nFPM when shipping native Linux packages
- small packages with domain names, not generic
utils - standard library first unless a preferred library clearly fits
- Amolith's licensing convention when the project does not already say otherwise: CC0 for docs/examples/config/prompt text, MutuaL for meaningful code
Use this .golangci.toml shape unless the project already has a stronger local
configuration. Replace the module path placeholders with the module from
go.mod:
version = "2"
[linters]
enable = ["bodyclose", "errcheck", "errorlint", "exhaustive", "gocognit", "govet", "ineffassign", "modernize", "nilerr", "nilnil", "noctx", "revive", "staticcheck", "unused"]
[linters.settings.gocognit]
min-complexity = 15
[[linters.settings.revive.rules]]
name = "file-length-limit"
arguments = [{ max = 1000, skip-comments = true, skip-blank-lines = true }]
[[linters.settings.revive.rules]]
name = "max-control-nesting"
arguments = [5]
[formatters]
enable = ["goimports", "gofumpt", "gci", "golines"]
[formatters.settings.goimports]
local-prefixes = ["<module-path>"]
[formatters.settings.gofumpt]
module-path = "<module-path>"
[formatters.settings.gci]
sections = ["standard", "default", "localmodule"]
[formatters.settings.golines]
max-len = 120
Default away from:
- Taskfiles and justfiles in new setup
- clix/kong, even when another Go skill recommends it; use stdlib flags for tiny tools and Cobra + Fang for user-facing CLIs
- generated wrappers around one command
- large frontend stacks for light server-rendered pages
- configuration frameworks when direct parsing is enough
- hidden global state unless a test seam restores it with
t.Cleanup
Use generic Go skills for implementation details, but this skill wins for Amolith-specific setup choices: mise, golangci-lint formatting/fixing, modernize, static build shape, CLI framework, packaging, Wails frontend stack, web styling posture, and explicit gocuke adoption.
Gocuke is an explicit project choice. Ask whether the project wants gocuke/BDD automation; if yes, load the gocuke skill after behaviour is formulated. If no, use ordinary Go tests.