agentleFS
motola10motola10/claude-code-base/.claude/skills/go-standards/SKILL.md

go-standards

Skill1 starsChanged 5 months agoMITView on GitHub

Best-practice coding standards for Go code (manifest: go.mod). Self-contained — covers language baseline, package design, error handling, concurrency, a lean HTTP service section, security, logging, tooling (gofmt/go vet/golangci-lint), testing, docs. Referenced by the review agents on Go projects. Do NOT use for other languages.

3 other projects use a version of this.

Adopted by

Most recently taken up by

The file

Show its rules and text

We split this skill into the rules it gives an agent

19 rules. About 0 are common, 5 are distinctive, and 14 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈5

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 14

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Target: all Go source — libraries, CLIs, and HTTP/network services.

    line 48
  2. Distinctive:

    Self-contained: No language overlay; the HTTP-service section (§5) is part of this document.

    line 49
  3. Distinctive:

    Standard library first: Prefer the stdlib; add dependencies only when they earn their keep.

    line 50
  4. Very specific:

    GO-BASE-4 (SHOULD): Keep functions small and the happy path left-aligned: handle errors and edge cases early with guard clauses and return, …

    line 64
  5. Distinctive:

    GO-PKG-4 (MUST NOT): Create import cycles between packages.

    line 79
  6. Very specific:

    GO-ERR-2 (MUST): Add context when propagating with fmt.Errorf("...: %w", err) so the chain is inspectable.

    line 92
  7. Very specific:

    GO-ERR-5 (MUST NOT): Use panic for ordinary/expected error conditions.

    line 99
  8. Distinctive:

    GO-ERR-6 (SHOULD): Don't log-and-return the same error — log it once, at the layer that decides to stop propagating it (usually the top), …

    line 102
  9. Very specific:

    GO-CONC-2 (MUST): Every goroutine MUST have a known exit condition — no goroutine leaks.

    line 126
  10. Very specific:

    GO-CONC-4 (SHOULD): Prefer errgroup (golang.org/x/sync/errgroup) for fan-out/fan-in with error propagation and cancellation over …

    line 131
  11. Very specific:

    GO-API-4 (SHOULD): Default auth scheme is stateless JWT bearer (token in Authorization: Bearer), verified in middleware.

    line 154
  12. Very specific:

    GO-API-6 (SHOULD): Put database access behind a repository interface defined at the consumer (GO-PKG-2).

    line 160
  13. Very specific:

    GO-LOG-1 (MUST): Use structured logging via log/slog (stdlib).

    line 186
  14. Very specific:

    GO-LINT-3 (SHOULD): Treat build warnings and staticcheck findings as errors.

    line 200
  15. Very specific:

    GO-TEST-1 (MUST): Test with the standard testing package.

    line 207
  16. Very specific:

    GO-TEST-2 (SHOULD): Prefer table-driven tests with subtests (t.Run), and the standard library's plain if got != want { t.Errorf(...) } …

    line 209
  17. Very specific:

    GO-TEST-4 (SHOULD): Follow the test pyramid — many fast unit tests, fewer integration, few end-to-end.

    line 216
  18. Very specific:

    GO-TEST-5 (SHOULD): Use t.Helper() in test helpers, t.Cleanup() for teardown, and t.Parallel() where tests are independent.

    line 219
  19. Very specific:

    GO-DOC-1 (SHOULD): Write doc comments on every exported identifier, starting with the identifier's name (// User represents ...), per godoc …

    line 226

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Go Coding Standard (v1.0)

Status: Locked v1.0. Built from the locked reference template — same RFC-2119 constraint language, GO-AREA-N rule-ID format, and severity mapping as the other standards. Go is a language with a batteries-included standard library, so — like python.md — this is a self-contained standard: it covers the language and a lean HTTP-service section, rather than deferring runtime concerns to a separate framework overlay. Where it sets API/auth/logging defaults, it stays consistent with nodejs.md / fastapi.md so a polyglot codebase behaves the same way.

On adoption this becomes .claude/skills/go-standards/SKILL.md + references/*.md.

Toolchain verified current as of 2026-06-13 (via Context7 + go.dev/GitHub): Go 1.26.x, golangci-lint 2.12.x. Rules are written version-agnostically; these are reference points, not pins.


How to read this document

Constraint language (RFC 2119)

  • MUST / MUST NOT — hard requirement; a violation is a blocking issue.
  • SHOULD / SHOULD NOT — strong recommendation; deviate only with a written // Justification:.
  • MAY — optional.

Rule IDs

Stable GO-AREA-NUMBER (e.g. GO-ERR-3). The reviewer MUST cite the rule ID. Never renumber.

Severity mapping

This document says…Reviewer severityGate
MUST/MUST NOT affecting safety (races/leaks) / securityCriticalBlocks merge
MUST/MUST NOT elsewhereCritical / Warning (by impact)Blocks if it risks correctness
SHOULD without justificationWarningShould fix
MAY / stylisticSuggestionNice to have

Scope & Assumptions

  1. Target: all Go source — libraries, CLIs, and HTTP/network services.
  2. Self-contained. No language overlay; the HTTP-service section (§5) is part of this document.
  3. Standard library first. Prefer the stdlib; add dependencies only when they earn their keep.
  4. Custom overrides: the project's custom-standards skill overrides this document on conflict.

1. Language Baseline & Modules

  • GO-BASE-1 (MUST): Build against a supported Go release (the current or previous major; Go's support window is the two most recent). Declare the minimum in go.mod via the go directive.
  • GO-BASE-2 (MUST): Manage dependencies with Go modules. Commit go.mod and go.sum; run go mod tidy so the module graph is minimal and reproducible. MUST NOT vendor selectively or edit go.sum by hand.
  • GO-BASE-3 (MUST): Code MUST be gofmt-clean (use gofmt/goimports). Formatting is not a matter of taste in Go — unformatted code fails review automatically.
  • GO-BASE-4 (SHOULD): Keep functions small and the happy path left-aligned: handle errors and edge cases early with guard clauses and return, rather than nesting the success path inside else.

2. Project & Package Design

  • GO-PKG-1 (SHOULD): Name packages for what they provide, short, lower-case, no underscores or plurals (user, not users/user_utils). Avoid generic catch-alls like util, common, base, helpers.
  • GO-PKG-2 (SHOULD): Accept interfaces, return concrete types. Define interfaces at the consumer side (where they're used), keep them small (1–3 methods), and don't pre-emptively abstract.
  • GO-PKG-3 (SHOULD): Export the minimum surface — keep identifiers unexported (lower-case) unless callers genuinely need them. The exported API is a contract.
  • GO-PKG-4 (MUST NOT): Create import cycles between packages. Restructure shared types into a lower-level package instead.
  • GO-PKG-5 (SHOULD): For services, keep main thin under cmd/<binary>/; put business logic in importable packages (e.g. internal/...). Use internal/ to enforce package boundaries the compiler checks.

3. Error Handling

  • GO-ERR-1 (MUST): Return error as the last return value and handle every error — check it, wrap it, or deliberately ignore it with a documented _ = and a reason. MUST NOT discard errors silently (golangci-lint's errcheck enforces this).
  • GO-ERR-2 (MUST): Add context when propagating with fmt.Errorf("...: %w", err) so the chain is inspectable. Don't restate the callee's message; add what this layer knows (operation, key).
  • GO-ERR-3 (MUST): Inspect wrapped errors with errors.Is (sentinel match) and errors.As (type match) — never string-match on err.Error().
  • GO-ERR-4 (SHOULD): Define sentinel errors (var ErrNotFound = errors.New(...)) or custom error types for conditions callers must branch on. Document which exported errors a function can return.
  • GO-ERR-5 (MUST NOT): Use panic for ordinary/expected error conditions. Reserve panic for truly unrecoverable programmer errors (impossible states). A library MUST NOT panic across its public API boundary — recover at the boundary and return an error if an internal panic is possible.
  • GO-ERR-6 (SHOULD): Don't log-and-return the same error — log it once, at the layer that decides to stop propagating it (usually the top), to avoid duplicate noise.
// ✅ GO-ERR-2/3: wrap with %w, inspect with errors.Is
func loadUser(ctx context.Context, id string) (*User, error) {
    u, err := repo.Get(ctx, id)
    if err != nil {
        if errors.Is(err, ErrNotFound) {
            return nil, fmt.Errorf("loadUser %s: %w", id, err)
        }
        return nil, fmt.Errorf("loadUser %s: query failed: %w", id, err)
    }
    return u, nil
}

4. Concurrency

  • GO-CONC-1 (MUST): Pass context.Context as the first parameter (ctx context.Context) on request-scoped and blocking calls; propagate it down and honor cancellation/deadlines. MUST NOT store a Context in a struct field. MUST NOT pass nil — use context.TODO() if you truly have none yet.
  • GO-CONC-2 (MUST): Every goroutine MUST have a known exit condition — no goroutine leaks. Tie lifetime to a context, a sync.WaitGroup, or channel close; don't spawn go f() and forget it.
  • GO-CONC-3 (MUST): Guard shared mutable state with a mutex or confine it to one goroutine and communicate via channels. The build/test pipeline MUST run the race detector (go test -race) in CI.
  • GO-CONC-4 (SHOULD): Prefer errgroup (golang.org/x/sync/errgroup) for fan-out/fan-in with error propagation and cancellation over hand-rolled WaitGroup + error plumbing.
  • GO-CONC-5 (SHOULD): The party that creates a channel owns closing it; close to signal "no more values," never to signal the receiver. Don't close a channel from the receiver side.
  • GO-CONC-6 (SHOULD): Capture loop variables explicitly when needed. (Go 1.22+ gives each iteration its own variable, but be explicit in any code that may build under older toolchains.)

5. HTTP Services & APIs

Cross-platform consistency: these mirror nodejs.md (NODE-NEST-14/15/16) and fastapi.md (FASTAPI-SEC-1/DOC-2) so auth, versioning, and the data layer behave the same across the stack.

  • GO-API-1 (SHOULD): Build HTTP services on the standard library net/http — the Go 1.22+ ServeMux supports method+pattern routing ("POST /v1/users/{id}"). A lightweight idiomatic router (e.g. chi) is a sanctioned alternative for middleware ergonomics; avoid heavyweight frameworks unless a clear need justifies them.
  • GO-API-2 (MUST): Propagate the request's context.Context (r.Context()) into every handler call, DB query, and downstream request, so client disconnects and timeouts cancel work.
  • GO-API-3 (MUST): Validate and treat all request input as untrusted — decode into typed structs, check fields, and reject malformed input with the right 4xx. Set timeouts on http.Server (ReadHeaderTimeout at minimum) to resist slow-client attacks.
  • GO-API-4 (SHOULD): Default auth scheme is stateless JWT bearer (token in Authorization: Bearer), verified in middleware; check authorization (roles/scopes), not just authentication. Sanctioned alternatives by context: httpOnly session cookies (browser-first) or an external IdP / OAuth2 provider. (Consistent with NODE-NEST-14 / FASTAPI-SEC-1.)
  • GO-API-5 (SHOULD): Version public APIs with URI versioning /v1 in the route pattern. (Consistent with NODE-NEST-15 / FASTAPI-DOC-2.)
  • GO-API-6 (SHOULD): Put database access behind a repository interface defined at the consumer (GO-PKG-2). Recommended default: sqlc (compile-time-typed SQL → Go) over pgx (Postgres driver) — Go idiom favors typed SQL over heavyweight ORMs. database/sql remains valid, and GORM is a sanctioned alternative where an ORM is genuinely wanted. The data layer is recommended not mandated, but these are required regardless of choice: parameterized queries (never string-built SQL — GO-SEC-1), the repository boundary (no raw queries in handlers), and versioned migrations via a migration tool (goose/golang-migrate). (Consistent with the repo-layer + migrations default in NODE-NEST-16 / FASTAPI-STRUCT-5.)

6. Security

  • GO-SEC-1 (MUST NOT): Build SQL with string concatenation/fmt.Sprintf. Use parameterized queries (db.QueryContext(ctx, "... WHERE id = $1", id)) — GO-API-6.
  • GO-SEC-2 (MUST NOT): Hard-code secrets. Load credentials/keys from the environment or a secret manager; never commit them.
  • GO-SEC-3 (MUST): Scan dependencies for known vulnerabilities with govulncheck in CI; keep modules patched.
  • GO-SEC-4 (SHOULD): Hash passwords with a memory-hard KDF (golang.org/x/crypto/bcrypt or argon2); use crypto/rand (never math/rand) for tokens, salts, and anything security-sensitive.

7. Logging & Observability

  • GO-LOG-1 (MUST): Use structured logging via log/slog (stdlib). MUST NOT use fmt.Println/ bare log for application logging in production code.
  • GO-LOG-2 (MUST): Log structured key/values with a level, and MUST NOT log secrets, tokens, or PII. (Consistent with NODE-LOG-2.)
  • GO-LOG-3 (SHOULD): Carry a request/trace ID on the context and attach it to logs for correlation; expose health/readiness endpoints for services. (Consistent with NODE-LOG-3/4.)

8. Tooling & Linting

  • GO-LINT-1 (MUST): go vet MUST pass in CI.
  • GO-LINT-2 (MUST): Lint with golangci-lint and a committed .golangci.yml; it MUST pass in CI. Enable at least errcheck, govet, staticcheck, ineffassign, and gosec.
  • GO-LINT-3 (SHOULD): Treat build warnings and staticcheck findings as errors; don't blanket-disable linters — suppress a single finding inline with a justified //nolint:<linter> // reason when truly warranted.

9. Testing

  • GO-TEST-1 (MUST): Test with the standard testing package. New or changed behavior ships with tests; the reviewer/QA agent treats changed logic with no test as insufficient coverage.
  • GO-TEST-2 (SHOULD): Prefer table-driven tests with subtests (t.Run), and the standard library's plain if got != want { t.Errorf(...) } style. An assertion helper (testify) is a sanctioned alternative for readability, but the stdlib style is the default (Go intentionally omits assertions to keep tests in plain Go).
  • GO-TEST-3 (MUST): Tests are deterministic and isolated — no reliance on real external network in unit tests, no order dependency, no shared mutable state. Concurrency-touching code MUST be tested with -race (GO-CONC-3).
  • GO-TEST-4 (SHOULD): Follow the test pyramid — many fast unit tests, fewer integration, few end-to-end. Target ≥ 80% coverage on changed code (not whole-repo) via go test -cover; coverage is a floor, not the goal. (Consistent with NODE-TEST-3 / PY-TEST-4.)
  • GO-TEST-5 (SHOULD): Use t.Helper() in test helpers, t.Cleanup() for teardown, and t.Parallel() where tests are independent.

10. Documentation

  • GO-DOC-1 (SHOULD): Write doc comments on every exported identifier, starting with the identifier's name (// User represents ...), per godoc convention.
  • GO-DOC-2 (SHOULD): Each package has a package comment (a // Package x ... doc) on one file explaining its purpose.

Resolved Decisions (v1.0)

#QuestionDecisionRule(s)
1HTTP routerstdlib net/http (1.22+ routing) default; chi sanctioned alternative; avoid heavyweight frameworks. Consistent with the "small sanctioned set" pattern (NODE-TEST-4), not a hard mandateGO-API-1
2Assertion librarystdlib testing + table-driven default; testify sanctioned. Matches Go's deliberate no-assertions stance + NODE-TEST-4 precedentGO-TEST-2
3DB layersqlc + pgx recommended default; GORM sanctioned ORM alt; database/sql valid. Library recommended not mandated, but parameterized queries + repo boundary + versioned migrations are required. Consistent with NODE-NEST-16 / FASTAPI-STRUCT-5GO-API-6, GO-SEC-1
4§5 scopeHTTP services kept self-contained in this standard — Go is a single standard among the nine (no framework overlay), unlike the python.md→fastapi.md split§5 GO-API-*

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.