SuperAPI AI Directory

golang

Coding & development

View repository

Updated 10-15 20:29

About this skill

Go

Guidance for writing Go and for reviewing it, as named rules you can cite.

Knowledge lives in corpus/<area>.md. Each rule is one ## section carrying its priority, the rule, the reason, a worked example, what catches a violation, and its sources. Open the area you need. Do not read the corpus end to end.

Where these files are on disk. The installer puts the whole tree at ~/.agents/skills/golang/, or at <project>/.agents/skills/golang/ for a project install. Use that root to grep the corpus. references/companion-skills.md has the rule for resolving it from the installer's lockfile.

This skill never overrides a standard the organisation already has. It fills the gaps.

Precedence

First match wins, for the topic it covers only. A topic nothing above the corpus covers falls through to the corpus.

Rung Signal
0 A direct instruction from the person asking for the work
1 A rule already loaded in this session's context
2 A repository instruction file: AGENTS.md, CLAUDE.md, .cursor/rules/, .github/copilot-instructions.md
3 A loaded skill that declares it supersedes Go guidance
4 A Go standards document in the repository, or its .golangci.yml
5 This corpus

Rung 0 is the person in the conversation. "Six files, no more" or "skip the linter config this time" outranks everything below, for the topic it names and nothing else. Quote the instruction in any report that a rule went unmet because of it.

Rung 1 exists because an always-on rule injected into your context is invisible to a directory scan.

One exception runs the other way. corpus/docs.md#godoc-required-on-exported overrides a loaded no-comments rule for doc comments on exported names and packages, and for nothing else. That rule is written as a declared exception to that companion, so a rung-1 comment ban does not take it.

Say which rung applied and to what. "Field ordering follows AGENTS.md; everything else in this file follows the corpus" is the shape. Never discard the corpus because the organisation wrote one rule.

Before you start

Run the companion handshake once per repository: references/companion-skills.md. It detects no-comments and simple-language, reports active, skill-only, rule-only or absent, and tells the user what is missing when a human is there to read it. Neither companion blocks any work.

The result is kept at ~/.skill-golang/onboarding/<repo-normalized-path>/onboarding.json. Nothing is ever written inside the repository you are working on.

Two modes

Write mode. You are producing Go. Apply the corpus as you type. Open the area for what you are doing, not the whole thing.

Review mode. You are producing a report. You do not edit the code under review. The finding shape, the severity ladder, the rule links and the run directory are all fixed in references/review-contract.md.

The ask Mode
"add a retry to the client" write
"review this PR" review
"is this concurrency safe?" review — one finding, no edits
"fix what you just found" write

Decision tree

Find what you are doing. Open that file. Jump to that anchor.

Writing a function

Question Rule
How do I shape it? corpus/style.md#left-aligned-happy-path
Is it too big? corpus/style.md#size-gate-and-smells
var or :=? corpus/style.md#declarations-and-literals
What goes in the signature? corpus/style.md#function-signatures
What do I call it? corpus/naming.md#mixedcaps-and-initialisms
Should it be GetX? corpus/naming.md#no-get-prefix
What do I call the receiver? corpus/naming.md#receiver-and-variable-names
Does it need a doc comment? corpus/docs.md#godoc-required-on-exported
Can I explain it in a comment? corpus/docs.md#no-other-comments

Handling an error

Question Rule
Wrap it or log it? corpus/errors.md#wrap-or-log-never-both
Sentinel or typed? corpus/errors.md#sentinel-vs-typed
What does the string look like? corpus/errors.md#error-string-form
Go 1.26 type-safe matching corpus/errors.md#errors-as-type
Can I panic? corpus/safety.md#panic-policy

Nil, slices, maps, assertions

Question Rule
Empty slice: nil or []T{}? corpus/safety.md#nil-slices-at-the-boundary
Is this map safe? corpus/safety.md#map-write-and-concurrent-access
Why did my other slice change? corpus/safety.md#append-aliasing
Type assertion corpus/safety.md#type-assertion-comma-ok
Can I use init? corpus/safety.md#avoid-init-and-mutable-globals

Concurrency

Question Rule
Who stops this goroutine? corpus/concurrency.md#goroutine-lifetime-ownership
How big a channel buffer? corpus/concurrency.md#channel-buffer-one-or-none
How do I bound fan-out? corpus/concurrency.md#bounded-fan-out-errgroup
How do I prove no leak? corpus/concurrency.md#goroutine-leak-detection
WaitGroup boilerplate corpus/concurrency.md#waitgroup-go

Context

Question Rule
Where does ctx go? corpus/context.md#context-first-parameter
Cancellation and timeouts corpus/context.md#cancellation-propagation
Can I store it in a struct? corpus/context.md#no-context-in-structs
Passing values through it corpus/context.md#context-values-are-request-scoped

Interfaces and wiring

Question Rule
Where do I declare the interface? corpus/interfaces.md#interfaces-at-the-consumer
What does the constructor return? corpus/interfaces.md#accept-interfaces-return-structs
Pointer or value receiver? corpus/interfaces.md#pointer-vs-value-receivers
Does it need a constructor at all? corpus/interfaces.md#zero-value-usability
Do I need a DI framework? corpus/interfaces.md#wiring-hand-first-then-fx
Does this type satisfy that interface? corpus/interfaces.md#verify-interface-compliance

Project shape

Question Rule
Where do files go? corpus/layout.md#progressive-module-layout
What do I call the package? corpus/layout.md#domain-not-layer-package-names
Should this be exported? corpus/layout.md#unexport-aggressively
Which libraries? corpus/dependencies.md#stdlib-first-tier-policy
New project corpus/dependencies.md#greenfield-stack-offer
go.mod and go.sum corpus/dependencies.md#go-mod-hygiene

Tests

Question Rule
Test or code first? corpus/testing.md#tdd-red-before-green
How do I structure the test? corpus/testing.md#table-driven-subtests
Can it run in parallel? corpus/testing.md#parallel-when-safe
Fake or generated mock? corpus/testing.md#test-doubles-fake-or-mock
Timers and goroutines in a test corpus/testing.md#synctest-for-time-and-goroutines
Comparing structs corpus/testing.md#go-cmp-for-comparison
What runs in CI? corpus/testing.md#race-detector-in-ci

Security

Question Rule
Building a query corpus/security.md#parameterized-sql
Credentials corpus/security.md#secrets-never-in-source
Rendering HTML corpus/security.md#contextual-escaping-html-template
Reading config corpus/security.md#typed-config-validated-at-startup
Known vulnerabilities corpus/security.md#vulnerability-scanning

Performance

Question Rule
Is this worth optimising? corpus/performance.md#measure-before-optimising
Preallocating a slice corpus/performance.md#slice-capacity-hints
Ordering struct fields corpus/performance.md#struct-field-order-readability-first
Writing a benchmark corpus/performance.md#benchmarks-with-b-loop
Go 1.26 garbage collector corpus/performance.md#green-tea-gc

Running in production

Question Rule
Which logger? corpus/observability.md#slog-is-the-default-logger
What do I log? corpus/observability.md#what-to-log-and-at-what-level
Several log destinations corpus/observability.md#slog-multihandler
Traces and metrics corpus/observability.md#tracing-and-metrics
Which HTTP or RPC stack? corpus/api.md#transport-chosen-at-bootstrap
Calling another service corpus/api.md#http-client-is-stateless
Serving HTTP corpus/api.md#handler-and-server-hygiene
RPC practice corpus/api.md#rpc-practices-per-transport
Querying a database corpus/data.md#context-aware-queries-and-pooling
Transactions corpus/data.md#transaction-and-rollback-discipline
Schema changes corpus/data.md#migrations-are-versioned

Tooling and language level

Question Rule
Linter configuration corpus/tooling.md#golangci-lint-baseline
go fix corpus/tooling.md#go-fix-is-a-reviewed-local-step
Renaming across files corpus/tooling.md#gopls-for-renames-and-references
What CI runs corpus/tooling.md#ci-gates
Which Go versions corpus/modernization.md#version-baseline-two-releases
slices, maps, cmp corpus/modernization.md#slices-maps-cmp-packages
new(expr) corpus/modernization.md#new-expr
Range over int and iterators corpus/modernization.md#range-over-int-and-iterators

Reviewing

Question Rule
What does a finding look like? corpus/review.md#review-finding-contract
What do I look at first? corpus/review.md#review-scope-and-order
How do I justify a finding? corpus/review.md#review-cites-the-rule

The rules that always apply

Seventeen rules are P0. A P0 governs on contradiction.

Rule In one line
corpus/onboarding.md#companion-skills-handshake Detect the companions once per repository, then carry on either way
corpus/onboarding.md#corporate-standards-precedence A standard the organisation has beats this corpus, one topic at a time
corpus/onboarding.md#write-and-review-modes Decide which mode you are in before reading anything else
corpus/docs.md#godoc-required-on-exported Every exported name and every package gets a doc comment
corpus/docs.md#no-other-comments No other comment, in any Go file you touch
corpus/errors.md#wrap-or-log-never-both Handle an error once
corpus/safety.md#panic-policy Panic only for programmer error, before the process serves traffic
corpus/concurrency.md#goroutine-lifetime-ownership Whoever starts a goroutine owns its exit
corpus/interfaces.md#interfaces-at-the-consumer The interface belongs to the package that calls it
corpus/layout.md#progressive-module-layout Flat, then internal/, then cmd/. Never pkg/
corpus/testing.md#tdd-red-before-green The test fails before the code makes it pass
corpus/security.md#parameterized-sql Never concatenate input into SQL
corpus/security.md#secrets-never-in-source No credential in the repository, the image, or a log line
corpus/performance.md#measure-before-optimising No optimisation without a before and after number
corpus/dependencies.md#stdlib-first-tier-policy Standard library, then golang.org/x, then a stated reason
corpus/modernization.md#version-baseline-two-releases Go 1.25 and 1.26; a newer feature carries since: and shows the older form
corpus/review.md#review-finding-contract Severity, location, rule link, what is wrong, the fix

Version baseline

The corpus targets Go 1.25 and Go 1.26.

A rule needing the newer release carries - since: 1.26 under its heading and shows the 1.25 form in a second **Good (1.25)** block. Read the go directive in the repository's go.mod to know which form compiles there.

The examples in this corpus were checked against go1.25.11. Blocks on a since: 1.26 rule were not compiled; they were checked against the Go 1.26 release notes by hand, and each such rule says so.

What this does not cover

Any language other than Go. CI platform configuration beyond naming the commands to run. Deployment, container images and orchestration. Product decisions. Where a repository has its own Go standard, that standard wins on its own topics — see the precedence table.

The non-Go files a Go change ships — a compose.yaml, a Dockerfile, a CI workflow — get no guidance from this corpus. The companions still reach them, because neither is about Go: apply no-comments and simple-language to every file in the change, not only the .go ones.