Files
2026-08-31 15:08:33 -03:00

4.4 KiB

agents.md

Code Style

  • Follow standard Go conventions: gofmt, goimports, and golangci-lint.
  • Keep packages small and focused. Name them short, lowercase, no underscores.
  • Avoid unnecessary abstractions — prefer simple, readable code over clever code.
  • Define interfaces at the point of use, not the point of implementation. Keep them small.

Error Handling

  • Always handle errors explicitly — never ignore them with _.
  • Wrap errors with context: fmt.Errorf("doing X: %w", err).
  • Use errors.Is / errors.As for matching, not string comparison.
  • Reserve panic for unrecoverable programmer mistakes, not runtime errors.

Concurrency

  • Pass context.Context as the first argument to any blocking or I/O function.
  • Never store a Context in a struct. Never use context.Background() deep in business logic.
  • Always manage goroutine lifecycles — use errgroup, sync.WaitGroup, or channels.
  • Protect shared state with mutexes or by confining it to a single goroutine.

Testing

  • Write table-driven tests using t.Run for clarity and coverage.
  • Use the standard testing package. Reach for testify only when it genuinely reduces noise.
  • Prefer real implementations over mocks where feasible (e.g., httptest, in-memory stores).
  • Keep tests close to the code they test; use _test packages for black-box testing.
  • Benchmark with testing.B before optimizing anything.

Dependencies & Modules

  • Keep go.mod tidy — run go mod tidy before committing.
  • Minimize external dependencies; prefer the standard library.
  • Pin versions explicitly and review dependency updates carefully.

General

  • Measure before optimizing. Use pprof for profiling.
  • Log at boundaries (entry/exit of services), not inside every function.
  • Prefer explicit over implicit — avoid init() and global state.

API Design

  • Propagate context.Context through every layer of an API — from handler to store.
  • Never drop context mid-call or substitute it with context.Background() silently.
  • Honor context cancellation and deadlines in all I/O and long-running operations.
  • Design APIs so callers can always pass a context; if a function does I/O, it takes a ctx.

Documentation

  • Document every exported type, function, method, and constant — no exceptions.
  • Follow Go doc conventions: start the comment with the name of the thing being documented.
  • Package-level comments should explain purpose and usage, not implementation details.
  • Include examples (Example* functions) for non-trivial exported APIs.
// UserStore retrieves and persists user records.
type UserStore interface { ... }

// GetByID returns the user with the given ID, or ErrNotFound if absent.
func (s *store) GetByID(ctx context.Context, id string) (*User, error) { ... }

Testing (expanded)

  • Write tests as you write code — not after, not when asked. Tests are not optional.
  • Every exported function and critical internal path must have at least one test.
  • Cover edge cases, error paths, and boundary conditions — not just the happy path.
  • Use t.Helper() in shared test utilities to keep failure output pointing at the call site.
  • Integration tests live in test/ or behind a build tag (e.g., //go:build integration).

Microservice Readiness

  • Expose /healthz (liveness) and /readyz (readiness) endpoints on a dedicated port.
  • Liveness indicates the process is alive; readiness indicates it can serve traffic.
  • Handle SIGTERM and SIGINT with graceful shutdown: stop accepting new requests, finish in-flight work, release resources, then exit.
  • Set explicit timeouts on http.Server: ReadTimeout, WriteTimeout, IdleTimeout.
  • Use errgroup with a context to coordinate shutdown across goroutines cleanly.
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGTERM, syscall.SIGINT)
defer stop()

Security

  • Never log secrets, tokens, passwords, or PII — scrub them before logging.
  • Validate and sanitize all external input; never trust data from outside the process boundary.
  • Use crypto/rand for all randomness that touches security; never math/rand.
  • Enforce TLS for all external communication; keep cipher suites and TLS version current.
  • Follow the principle of least privilege for service accounts, DB roles, and IAM policies.
  • Scan dependencies for known CVEs regularly (e.g., govulncheck).
  • Set strict timeouts on all outbound HTTP clients — never use the default zero-timeout client.