agentsclimarketplace

Standards go

Skill pecigonzalo/agent-skills/skills/standards-go

Use this skill when writing or reviewing Go code or making Go architecture and API design decisions. Provides idiomatic Go patterns, error handling, resource management, generics, and design pattern guidance.From its SKILL.md

Install
npx -y skills add pecigonzalo/agent-skills --skill standards-go

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 28 days oldThe repository was created 28 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

16.0 KB, ~3.7k tokens by cl100k_base, as published. Nobody here has run it

Go Standards

Provides: Idiomatic Go patterns, error handling, resource management, naming/package conventions, API/type design, and lightweight Go-specific pattern guidance. For concurrency, testing, and performance, load dedicated subskills.

Primary references:

Quick Reference

Golden Rule: Explicit is better than implicit; clarity beats cleverness

Style principles (priority order):

PrincipleKey question
ClarityCan a reader understand what and why?
SimplicityIs this the simplest approach?
ConcisionIs the signal-to-noise ratio high?
MaintainabilityCan this be safely modified later?
ConsistencyDoes this match surrounding code?

Do:

  • Run gofmt/goimports on every save
  • Use MixedCaps for identifiers; avoid underscores (except test names and rare low-level interop)
  • Return error last; wrap with %w; check with errors.Is/errors.As (1.13+)
  • defer release immediately after acquisition
  • Pass context.Context as the first argument to blocking calls
  • Accept interfaces, return concrete types
  • Design zero values to be usable
  • Prefer standard helpers available in your Go version (slices, maps, cmp, min/max)
  • Use any instead of interface{} when unconstrained (1.18+)

Don't:

  • Hand-align code or use underscores in identifiers
  • Stutter exported names (bufio.BufReader → use bufio.Reader)
  • Discard errors with _ silently
  • Store context.Context in structs
  • Use panic as flow control
  • Use dot imports outside tests
  • Name packages util, common, or helpers
  • Use init() for anything beyond simple side-effect-free registration
  • Use naked returns in non-trivial functions
  • Define interfaces in consumers, not implementations
  • Use bare string/int context keys
  • Use http.NewRequest for outbound calls that must respect a deadline: use http.NewRequestWithContext

Key commands (only when needed):

go test ./...        # baseline validation
go test -race ./...  # when touching concurrency
go mod tidy          # when deps changed

Formatting & Tooling

  • Use goimports (or gofmt) on save; CI should reject unformatted files.
  • Use go vet ./... in CI.
  • Use golangci-lint as the unified linter runner when configured.
  • Keep //go:generate deterministic; track generator tool dependencies via tools.go + //go:build tools when needed.
  • Keep import groups simple: stdlib, external, internal (enforced by goimports).
  • Restrict blank imports (_) to real side-effect registration use cases.

Code Style

Reduce Nesting

Handle error cases and special conditions first; return early or continue to keep the happy path unindented.

Local Consistency

When multiple styles are acceptable and no rule applies, match the style of the surrounding file/package. Do not introduce a second convention without a strong reason.

Least Mechanism

Prefer the simplest tool that works:

  1. core language constructs (struct/slice/map/channel)
  2. standard library
  3. well-adopted libraries

Add dependencies and abstraction only when they clearly improve correctness, simplicity at call sites, or performance.

Control Flow Idioms

  • if with initializer: scope short-lived variables to the block: if err := file.Chmod(0664); err != nil { return err }.
  • := redeclaration rule: a variable in the same scope can reappear on the left of := if at least one other variable is new. Shadowing trap: := in an inner scope creates a new variable: the outer one is silently unchanged.
  • range over strings iterates runes (not bytes): for i, r := range s yields Unicode code points; i is the byte offset.
  • Switch: no implicit fallthrough; expression-less switch (switch { case cond: }) switches on true; comma-separated cases share a body; use labeled break to exit an enclosing loop from within a switch.

Reduce Scope of Variables

Declare variables as close as possible to their use. Prefer if/switch initializers to keep temporary values scoped to the block, and avoid pre-declaring var x far above where it is used.

Raw String Literals

Use raw string literals (backticks) to avoid hand-escaped strings: `unknown error:"test"` instead of "unknown error:\"test\"".

Naming & Packages

  • Package names: lowercase, single word, matches directory name. Avoid util, common, helpers, misc.
  • Exported names must not stutter: http.Client not http.HTTPClient; bufio.Reader not bufio.BufReader.
  • Use MixedCaps (camelCase / PascalCase) for identifiers; no underscores. Exceptions: Test*/Benchmark*/Example* in *_test.go; low-level OS/cgo interop.
  • Getters named as the field: Owner() not GetOwner(); setters: SetOwner(v). Use Compute/Fetch for expensive operations.
  • Single-method interfaces: suffix with -er (io.Reader, http.Handler); define at point of use, not in the implementing package.
  • Doc comments on every exported symbol: // FunctionName does X.

Documentation (godoc)

  • Comment style: Start with the name being documented; use a full sentence. Example: // A Request represents a request to run a command.
  • Package comment: Every package needs exactly one; place it in doc.go for large packages.
  • Parameters / config: Document only non-obvious behavior and edge cases.
  • Context cancellation: Implied: document only when behavior differs.
  • Concurrency: Read-only operations are assumed safe; mutating assumed unsafe. Add a note only when ambiguous.
  • Cleanup: Always state when the caller must release a resource.
  • Errors: Document sentinel errors and custom error types: use pointer form (*PathError) for errors.As targets.
  • Godoc formatting: Blank line between paragraphs; indent code blocks by two extra spaces.

Initialisms and Acronyms

Initialisms (URL, ID, HTTP, etc.) must be cased uniformly: ParseURL, HTTPClient, userID. Avoid mixed forms like userId or ParseUrl.

Avoid Predeclared Names

Do not name variables, parameters, fields, or methods after Go's predeclared identifiers (error, string, int, len, make, new, close). Shadowing creates subtle bugs.

Avoiding Repetition

Names should not feel redundant when read in full context. Consider the package qualifier, receiver type, and surrounding code: widget.New() not widget.NewWidget(); db.Load() not db.LoadFromDatabase().

API & Type Design

Read the API and type design guide when designing exported APIs, interfaces, constructors, options, or type sets.

Project Structure

cmd/myapp/main.go    # Minimal: wire dependencies and call into internal packages
internal/            # Private packages; cannot be imported by external modules
pkg/                 # Public library code (optional; omit if all consumers are internal)
api/                 # API definitions (OpenAPI specs, protobuf files)
configs/             # Configuration files
testdata/            # Test fixtures; ignored by go build
  • Keep main packages thin: business logic belongs in internal/.
  • Prefer internal/ over pkg/ unless you intentionally publish an importable API.
  • testdata/ is the conventional home for golden files, fixtures, and fuzz corpora.

File Organization

  • Group declarations: import (...), then const (...), var (...), type (...) when related.
  • Keep functions grouped by receiver; keep exported APIs first.
  • Place constructors (NewT/newT) right after the type definition, before methods.
  • Keep plain helper functions (no receiver) near the end of the file.

Build constraints and workspaces

  • Use //go:build syntax (not legacy // +build).
  • Use go work in multi-module repos when local cross-module iteration is needed; avoid committing go.work when modules are independently versioned.

Error Handling

  • Return error as the last return value. Never discard with _ without an explanatory comment.
  • Wrap errors for context: fmt.Errorf("open config: %w", err). Use %w (not %v) so callers can unwrap.
  • Check wrapped errors with errors.Is and errors.As (or errors.AsType if available in your project Go version).
  • Sentinel errors: declare as package-level vars (var ErrFoo = errors.New("foo")) so callers can match without string comparison.
  • Combine multiple errors with errors.Join(err1, err2) (1.20+) instead of manual concatenation.
  • Custom error types: define struct types when callers need structured fields; unwrap with errors.As.
  • panic is program-fatal. Use recover only at package or handler boundaries (e.g., HTTP middleware). Never use panic/recover as a substitute for returning errors.

Return the error Interface, Not a Concrete Type

Always return the error interface from exported functions. Returning a concrete type (e.g., *os.PathError) creates a typed-nil trap: a nil pointer compares non-nil as an interface value.

Error Strings

Error strings should be lowercase and should not end with punctuation. Exception: capitalize when beginning with an exported name or proper noun.

Avoid In-Band Errors

Do not use magic sentinel values (-1, "", nil) to signal failure. Use multiple return values: func Lookup(key string) (string, bool) or func Parse(key string) (int, error).

Indent Error Flow

Handle errors first and return early; do not put the normal path in an else branch. Avoid if x, err := f(); err != nil { ... } else { use x }: declare x separately when it lives beyond a few lines.

%v vs %w

  • Use %w for internal propagation where callers may match/unwrap.
  • Use %v at service boundaries where you intentionally hide internals.

Handle Errors Once

Each error must be handled exactly once. Never log and return the same error.

StrategyWhen to use
Wrap and returnCaller is better positioned to handle it
Log and degradeThe error is non-fatal; execution can continue
Match and handleYou can recover from specific conditions; return others
if err := db.QueryRow(ctx, q, id).Scan(&u); err != nil {
    if errors.Is(err, sql.ErrNoRows) {
        return nil, ErrNotFound
    }
    return nil, fmt.Errorf("get user %s: %w", id, err)
}

init() Rules

Avoid init(): prefer an explicit initialization function called by main(). When unavoidable (e.g., database/sql driver registration), init() must be: completely deterministic, free of ordering dependencies, must not read env vars or os.Args, and must not perform I/O.

Exit and log.Fatal

Call os.Exit or log.Fatal* only in main(). All other functions must return errors. Prefer the run() error pattern:

func main() {
    if err := run(); err != nil {
        log.Fatal(err)
    }
}

func run() error {
    // ... business logic returning errors ...
    return nil
}

Resource Management

  • defer release immediately after acquisition: f, err := os.Open(name); if err != nil { ... }; defer f.Close().
  • Deferred call arguments are evaluated at the defer statement, not at call time.
  • Pass context.Context as the first argument to blocking/cancellable functions. Do not store context in structs.
  • Check errors from Close() on write paths (e.g., gzip.Writer, bufio.Writer).

Context Patterns

  • No custom context types. Always accept context.Context; embedding extra methods breaks composability.
  • Data placement order: function parameters → receiver fields → package-level globals → context values. Context values are only for request-scoped, cross-cutting data (request IDs, trace IDs, auth tokens).
  • Context immutability: safe to pass the same ctx to multiple sequential or concurrent calls.
  • context.Background(): only at program entry points (main, top-level goroutines, tests). Everywhere else, accept and forward ctx.
  • Always defer cancel() immediately after deriving a context.
  • Use http.NewRequestWithContext (never http.NewRequest) so outbound requests respect the caller's deadline.

Typed context keys: never use bare string or int as a key:

// Unexported type scoped to this package: impossible for other packages to collide
type contextKey string

const (
    requestIDKey contextKey = "requestID"
    userIDKey    contextKey = "userID"
)

func WithRequestID(ctx context.Context, id string) context.Context {
    return context.WithValue(ctx, requestIDKey, id)
}

func RequestID(ctx context.Context) (string, bool) {
    id, ok := ctx.Value(requestIDKey).(string)
    return id, ok
}

Generics (1.18+)

Use generics to remove true type-parameterized duplication; do not reach for them by default.

  • Prefer concrete types and small interfaces first.
  • Use minimal constraints (any, comparable, or narrow union constraints).
  • Avoid generic data structures unless they provide clear ergonomic or correctness benefits beyond stdlib helpers.
  • Do not use any where an interface better expresses behavior.

Modern Go by Version

Check project Go version first (go.mod). Prefer modern stdlib functionality available in that version.

High-value defaults to prefer when available:

  • slices/maps/cmp helpers over manual loops and boilerplate
  • min/max, clear, and other builtins over ad-hoc patterns
  • improved context/test APIs (With*Cause, t.Context(), etc.)
  • modern loop and ServeMux idioms in newer Go versions

High-value examples often not auto-fixed by modernize:

  • API boundaries: use slices.Clone / maps.Clone to avoid aliasing mutable caller state.
  • HTTP routing: use method-aware http.ServeMux patterns and r.PathValue where supported.
  • Cancellation semantics: prefer context.WithTimeoutCause / context.WithDeadlineCause when error attribution matters.
  • Tests/benchmarks: use t.Context() and b.Loop() when your Go version supports them.
  • WaitGroup ergonomics: prefer wg.Go(fn) in newer Go versions.

When uncertain about version behavior, verify with official Go release notes.


Skill Loading Triggers

SituationAlso load
Writing any Go codestandards-code
Writing Go tests, benchmarks, fuzz testsstandards-go-testing, standards-testing
Goroutines, channels, sync, context patternsstandards-go-concurrency
Profiling, tracing, allocation, GC tuningstandards-go-performance, standards-observability
Auth, secrets, user input, cryptostandards-security
Implementing features/fixes (TDD)role-developer
API/package/service designrole-architect
Go PR reviewrole-code-review

Verification Checklist

  • No formatting/lint/vet failures (prefer repo task runner; use golangci-lint when configured)
  • Required tests pass
  • Concurrency changes were race-checked when goroutines/sync were touched
  • Dependency metadata is clean when dependencies changed

Note: file list is sampled.

What ships with it: 1 file

7.8 KB alongside SKILL.md

references/

Gives 0 of the 12 instructions most architecture codebase skills give in ~3.7k tokens

Counted across 811 of the 1,134 authors here whose files we hold, read 2026-08-07

  • Ask the user which candidate to explorein 45 of 811, across 15 files
  • Apply the deletion test to suspected shallow modulesin 43 of 811, across 15 files
  • Read any relevant architecture decision records firstin 31 of 811, across 8 files
  • Use exact glossary terms in every suggestionin 30 of 811, across 10 files
  • Accept dependencies instead of creating themin 24 of 811, across 5 files
  • Include before and after visualisations for each candidatein 24 of 811, across 5 files
  • Read the domain glossary before exploringin 24 of 811, across 6 files
  • Return results instead of producing side effectsin 23 of 811, across 4 files
  • Explore the codebase for shallow modules and frictionin 23 of 811, across 3 files
  • Introduce seams only where things varyin 22 of 811, across 3 files
  • Reduce the number of methodsin 21 of 811, across 2 files
  • Design deep modules with small interfacesin 21 of 811, across 3 files

Said here and by no other author read

  • run gofmt on every save
  • return errors as the last value
  • wrap errors with percent w
  • defer resource release immediately after acquisition
  • accept interfaces and return concrete types
  • return early to reduce nesting

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 326,614. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.