Skip to content
Web apps

Go service rules

Go rules for agents: wrapped errors with errors.Is, context first, owned goroutines, 1.22+ routing, timeouts, and gofmt, vet and go test -race as the gate.

Verified install Not agent-tested v1.0.0 MIT updated go
Equips
  • 1 1 Rules
  • 1 1 Skills
  • – 0 MCP

Go is simple enough that agents produce working code fast, and idiomatic enough that reviewers spot the shortcuts: errors compared by string, goroutines with no way to stop, the default HTTP client with no timeout, a router library for what the standard mux now does. This loadout writes down the conventions from Effective Go and the Go blog, uses Go 1.22's method and path patterns, and ships a handler skill whose example and table-driven tests the verifier runs under the race detector.

What's in it

  • gofmt, go vet and go test -race as the done-gate
  • Errors wrapped with %w and checked with errors.Is / errors.As
  • context first; every goroutine has an owner and a stop
  • Go 1.22+ ServeMux patterns; no router library needed
  • Server and client timeouts, size-limited JSON bodies

You'll need

  • Tools: go
Level 1 · automated

Verification

Verified install

Checked at commit c77eea0 · 9 passed, 0 failed, 1 not applicable

CheckResultWhat we found
Listinglisting.yaml matches the schema and declares every file in the folder. Pass
Schema valid; 6 files declared, none missing or extra
  • tested.status: untested (agent tests are separate from Level 1)
Files parseJSON parses; SKILL.md and .mdc front matter is valid YAML with the fields each agent needs; code fences are closed. Pass All 6 files parse; front matter valid
AdaptersCLAUDE.md imports @AGENTS.md, GEMINI.md imports @./AGENTS.md, and both match the generator. Pass
CLAUDE.md and GEMINI.md import AGENTS.md and are up to date
  • CLAUDE.md: matches the generator
  • GEMINI.md: matches the generator
Install pathsEvery file lands where each agent documents it, with no collisions, and the laid-out project is re-discovered correctly. Pass
Correct paths for all 6 agents; layouts re-discovered
  • Claude Code: 5 files, 1 skill in .claude/skills/
  • Codex CLI: 4 files, 1 skill in .agents/skills/
  • Cursor: 4 files, 1 skill in .agents/skills/
  • Gemini CLI: 5 files, 1 skill in .agents/skills/
  • Antigravity CLI: 4 files, 1 skill in .agents/skills/
  • GitHub Copilot: 4 files, 1 skill in .agents/skills/
MCP configmcp.json is structurally valid, converts to each agent's format, declares no literal secrets, and referenced packages exist on npm/PyPI. Not applicable No MCP servers in this loadout
Safety scanThe intake scanner finds no credentials, risky shell, hidden Unicode or prompt-injection wording, and the listing's network flag is honest. Pass
Clean: no credentials, risky shell or hidden text
  • Scanner intake-precheck/1: verdict clean; network no (listing says yes)
ReferencesLinks and file paths between the loadout's files resolve, including for each agent's installed layout. Pass 1 reference between files resolves for every agent
Size limitsFile count and sizes are within the submission limits; SKILL.md bodies stay under 500 lines. Pass
6 files, 7.4 KB total; largest skills/go-http-handler/references/handler.go 2.7 KB
  • Limits: 30 files, 32 KB per file, 128 KB total, 500 lines per skill or rule
LicenceA recognised SPDX licence, with the licence text available. Pass MIT, by Agent Loadout; text in the repository LICENSE
Starter buildA minimal fixture project with the loadout applied installs and builds or type-checks, and the loadout's own code examples compile. Pass
The go-http-handler skill's example handler and table-driven tests drop into a Go module: gofmt and go vet are clean and all seven status-code cases pass under the race detector
  • Applied 9 loadout files at every agent's paths
  • ✓ place the example: bash -c mkdir -p items && cp .agents/skills/go-http-handler/references/handler.go .agents/skills/go-http-handler/references/handler_test.go items/ && echo placed
  • ✓ gofmt -l: bash -c out=$(gofmt -l items); if [ -n "$out" ]; then echo "unformatted: $out"; exit 1; fi; echo gofmt ok
  • ✓ go vet: go vet ./...
  • ✓ go test -race: go test -race -count=1 -v ./...
  • Covers: Go 1.22+ method and path patterns with r.PathValue
  • Covers: MaxBytesReader and DisallowUnknownFields on JSON bodies
  • Covers: Wrapped sentinel error mapped to 404 with errors.Is; internal errors logged with slog
  • Covers: Table-driven httptest tests, race detector clean

What this means: a script checked the files themselves: they parse, they install where each agent looks, any MCP config is sound, the safety scan is clean, references between files resolve, and, where a free and repeatable fixture exists, a small starter project builds with the loadout applied. No AI agent was run. Per-agent results ("tested with agent") are separate and stay untested until an agent actually runs.

Install

Choose your agent. Run the commands from your project root, or download a zip already laid out in the right folders.

Claude Code reads CLAUDE.md (imports AGENTS.md with @AGENTS.md) and skills from .claude/skills/.

Download zip
curl -fsSL --create-dirs -o AGENTS.md https://loadout.jnw-it.com/raw/go-service/1.0.0/AGENTS.md
curl -fsSL --create-dirs -o CLAUDE.md https://loadout.jnw-it.com/raw/go-service/1.0.0/CLAUDE.md
curl -fsSL --create-dirs -o .claude/skills/go-http-handler/SKILL.md https://loadout.jnw-it.com/raw/go-service/1.0.0/skills/go-http-handler/SKILL.md
curl -fsSL --create-dirs -o .claude/skills/go-http-handler/references/handler.go https://loadout.jnw-it.com/raw/go-service/1.0.0/skills/go-http-handler/references/handler.go
curl -fsSL --create-dirs -o .claude/skills/go-http-handler/references/handler_test.go https://loadout.jnw-it.com/raw/go-service/1.0.0/skills/go-http-handler/references/handler_test.go
FileGoes to
AGENTS.mdAGENTS.md
CLAUDE.mdCLAUDE.md
skills/go-http-handler/SKILL.md.claude/skills/go-http-handler/SKILL.md
skills/go-http-handler/references/handler.go.claude/skills/go-http-handler/references/handler.go
skills/go-http-handler/references/handler_test.go.claude/skills/go-http-handler/references/handler_test.go

Already have an AGENTS.md or CLAUDE.md? The commands above overwrite it — download the file instead and merge the sections you want.

Files

Rules AGENTS.md Go rules for errors, concurrency, HTTP and dependencies. 33 lines
Download Raw
# AGENTS.md: Go service

Go module. Check the `go` directive in `go.mod` before using newer language or standard library features.

## Commands
- Build: `go build ./...`. Tests: `go test -race ./...`. Vet: `go vet ./...`.
- Format: `gofmt -l .` must print nothing (or `goimports` if the project uses it).
- Lint, if `.golangci.yml` exists: `golangci-lint run`.
- Done means: gofmt clean, vet clean, tests green with `-race`.

## Errors
- Return errors; never `panic` on input. Wrap with context: `fmt.Errorf("load user %d: %w", id, err)`.
- Compare with `errors.Is` and `errors.As`, never by string. Define sentinel errors (`var ErrNotFound = errors.New(...)`)
  for conditions callers handle.
- Handle every error once: either return it or log it, not both.

## Concurrency
- `context.Context` is the first parameter of anything that does I/O or may block. Respect cancellation.
- Every goroutine has an owner and a way to stop (context, closed channel or `errgroup`). No fire-and-forget goroutines.
- Shared state behind a mutex or owned by one goroutine. `go test -race` must stay clean.

## HTTP
- Go 1.22+ routing: `mux.HandleFunc("GET /items/{id}", h)` and `r.PathValue("id")`. Do not add a router library for that.
- Servers set timeouts (`ReadHeaderTimeout` at least). Clients use a `http.Client` with `Timeout`, never the default client
  for external calls.
- Write JSON with the right `Content-Type` and status; decode with a size limit (`http.MaxBytesReader`).

## Dependencies and style
- Standard library first. Ask before adding a module; then `go get <module>@<version>` and `go mod tidy`.
- Logging with `log/slog`, structured key-value pairs. No secrets in logs.
- Table-driven tests with `t.Run`; `net/http/httptest` for handlers. New handlers: use the `go-http-handler` skill.
- Small interfaces, defined where they are used. Accept interfaces, return structs.
Adapter CLAUDE.md Imports AGENTS.md for Claude Code. 10 lines
Download Raw
# CLAUDE.md

@AGENTS.md

## Claude Code notes
- Skills from this loadout live in `.claude/skills/`: `go-http-handler`. Use them when their description matches the task.
- Follow AGENTS.md above; where this file and AGENTS.md disagree, AGENTS.md wins.

<!-- From the Agent Loadout "Go service rules" v1.0.0 — https://loadout.jnw-it.com/loadouts/go-service/ -->
Adapter GEMINI.md Imports AGENTS.md for Gemini CLI. 10 lines
Download Raw
# GEMINI.md

@./AGENTS.md

## Gemini CLI notes
- Skills from this loadout live in `.agents/skills/`: `go-http-handler`. Use them when their description matches the task.
- Follow AGENTS.md above; where this file and AGENTS.md disagree, AGENTS.md wins.

<!-- From the Agent Loadout "Go service rules" v1.0.0 — https://loadout.jnw-it.com/loadouts/go-service/ -->
Skill skills/go-http-handler/SKILL.md Add an HTTP handler with tests. 16 lines
Download Raw
---
name: go-http-handler
description: Add a Go net/http handler with 1.22+ routing, a size-limited JSON body, wrapped errors mapped to status codes and table-driven httptest tests. Use when adding or changing an HTTP endpoint.
---

# Go HTTP handler

1. Read how the service builds its `http.ServeMux` and stores dependencies (usually a struct with methods).
2. Follow `references/handler.go`: a method on the server struct, `r.PathValue` for path parameters,
   `http.MaxBytesReader` plus `json.Decoder` with `DisallowUnknownFields` for bodies.
3. Map errors to status codes in one place: `errors.Is(err, ErrNotFound)` gives 404, validation 400, everything else 500
   with the detail logged through `slog`, not sent to the client.
4. Register the route with method and pattern: `mux.HandleFunc("POST /items", s.createItem)`.
5. Tests like `references/handler_test.go`: table-driven, `httptest.NewRecorder`, one row per status code.
6. Run `gofmt -l .`, `go vet ./...` and `go test -race ./...`. Report the results.
Skill file skills/go-http-handler/references/handler.go Example handlers with routing and error mapping. 107 lines
Download Raw
// Package items is an example of a net/http handler set: Go 1.22+ routing, limited JSON bodies, errors mapped to status.
package items

import (
	"encoding/json"
	"errors"
	"fmt"
	"log/slog"
	"net/http"
	"strconv"
	"sync"
)

// ErrNotFound is returned when an item does not exist.
var ErrNotFound = errors.New("item not found")

// Item is the public representation of an item.
type Item struct {
	ID         int    `json:"id"`
	Name       string `json:"name"`
	PricePence int    `json:"price_pence"`
}

// Server holds dependencies for the handlers.
type Server struct {
	mu    sync.Mutex
	items map[int]Item
	log   *slog.Logger
}

// NewServer returns a Server with an empty store.
func NewServer(log *slog.Logger) *Server {
	return &Server{items: map[int]Item{}, log: log}
}

// Routes registers the handlers on a new mux.
func (s *Server) Routes() *http.ServeMux {
	mux := http.NewServeMux()
	mux.HandleFunc("POST /items", s.createItem)
	mux.HandleFunc("GET /items/{id}", s.getItem)
	return mux
}

func (s *Server) find(id int) (Item, error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	it, ok := s.items[id]
	if !ok {
		return Item{}, fmt.Errorf("find %d: %w", id, ErrNotFound)
	}
	return it, nil
}

func (s *Server) getItem(w http.ResponseWriter, r *http.Request) {
	id, err := strconv.Atoi(r.PathValue("id"))
	if err != nil {
		http.Error(w, "id must be a number", http.StatusBadRequest)
		return
	}
	it, err := s.find(id)
	if err != nil {
		s.fail(w, err)
		return
	}
	writeJSON(w, http.StatusOK, it)
}

func (s *Server) createItem(w http.ResponseWriter, r *http.Request) {
	r.Body = http.MaxBytesReader(w, r.Body, 1<<20)
	dec := json.NewDecoder(r.Body)
	dec.DisallowUnknownFields()
	var in struct {
		Name       string `json:"name"`
		PricePence int    `json:"price_pence"`
	}
	if err := dec.Decode(&in); err != nil {
		http.Error(w, "invalid JSON body", http.StatusBadRequest)
		return
	}
	if in.Name == "" || in.PricePence < 0 {
		http.Error(w, "name is required and price_pence must be 0 or more", http.StatusBadRequest)
		return
	}
	s.mu.Lock()
	it := Item{ID: len(s.items) + 1, Name: in.Name, PricePence: in.PricePence}
	s.items[it.ID] = it
	s.mu.Unlock()
	writeJSON(w, http.StatusCreated, it)
}

// fail maps errors to status codes in one place. Internal detail is logged, not sent.
func (s *Server) fail(w http.ResponseWriter, err error) {
	switch {
	case errors.Is(err, ErrNotFound):
		http.Error(w, "not found", http.StatusNotFound)
	default:
		s.log.Error("request failed", "err", err)
		http.Error(w, "internal error", http.StatusInternalServerError)
	}
}

func writeJSON(w http.ResponseWriter, status int, v any) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(status)
	_ = json.NewEncoder(w).Encode(v)
}
Skill file skills/go-http-handler/references/handler_test.go Table-driven httptest tests. 39 lines
Download Raw
package items

import (
	"io"
	"log/slog"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"
)

func TestHandlers(t *testing.T) {
	srv := NewServer(slog.New(slog.NewTextHandler(io.Discard, nil)))
	h := srv.Routes()

	tests := []struct {
		name, method, path, body string
		want                     int
	}{
		{"create", "POST", "/items", `{"name":"Tea","price_pence":250}`, http.StatusCreated},
		{"read created", "GET", "/items/1", "", http.StatusOK},
		{"missing", "GET", "/items/99", "", http.StatusNotFound},
		{"bad id", "GET", "/items/abc", "", http.StatusBadRequest},
		{"unknown field", "POST", "/items", `{"name":"Tea","colour":"red"}`, http.StatusBadRequest},
		{"negative price", "POST", "/items", `{"name":"Tea","price_pence":-1}`, http.StatusBadRequest},
		{"wrong method", "DELETE", "/items/1", "", http.StatusMethodNotAllowed},
	}
	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			req := httptest.NewRequest(tc.method, tc.path, strings.NewReader(tc.body))
			rec := httptest.NewRecorder()
			h.ServeHTTP(rec, req)
			if rec.Code != tc.want {
				t.Fatalf("%s %s: got %d, want %d (%s)", tc.method, tc.path, rec.Code, tc.want, rec.Body.String())
			}
		})
	}
}

All files: source zip · Licence MIT · By Agent Loadout · First listed

Installing and testing

How do I install Go service rules in Claude Code?

From your project root, put AGENTS.md, CLAUDE.md, skills/go-http-handler/SKILL.md at .claude/skills/go-http-handler/SKILL.md, skills/go-http-handler/references/handler.go at .claude/skills/go-http-handler/references/handler.go, skills/go-http-handler/references/handler_test.go at .claude/skills/go-http-handler/references/handler_test.go. The "Claude Code" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/go-service/claude-code.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.

How do I install Go service rules in Codex CLI?

From your project root, put AGENTS.md, skills/go-http-handler/SKILL.md at .agents/skills/go-http-handler/SKILL.md, skills/go-http-handler/references/handler.go at .agents/skills/go-http-handler/references/handler.go, skills/go-http-handler/references/handler_test.go at .agents/skills/go-http-handler/references/handler_test.go. The "Codex CLI" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/go-service/codex.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.

How do I install Go service rules in Cursor?

From your project root, put AGENTS.md, skills/go-http-handler/SKILL.md at .agents/skills/go-http-handler/SKILL.md, skills/go-http-handler/references/handler.go at .agents/skills/go-http-handler/references/handler.go, skills/go-http-handler/references/handler_test.go at .agents/skills/go-http-handler/references/handler_test.go. The "Cursor" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/go-service/cursor.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.

How do I install Go service rules in Gemini CLI?

From your project root, put AGENTS.md, GEMINI.md, skills/go-http-handler/SKILL.md at .agents/skills/go-http-handler/SKILL.md, skills/go-http-handler/references/handler.go at .agents/skills/go-http-handler/references/handler.go, skills/go-http-handler/references/handler_test.go at .agents/skills/go-http-handler/references/handler_test.go. The "Gemini CLI" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/go-service/gemini-cli.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.

How do I install Go service rules in Antigravity CLI?

From your project root, put AGENTS.md, skills/go-http-handler/SKILL.md at .agents/skills/go-http-handler/SKILL.md, skills/go-http-handler/references/handler.go at .agents/skills/go-http-handler/references/handler.go, skills/go-http-handler/references/handler_test.go at .agents/skills/go-http-handler/references/handler_test.go. The "Antigravity CLI" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/go-service/antigravity-cli.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.

How do I install Go service rules in GitHub Copilot?

From your project root, put AGENTS.md, skills/go-http-handler/SKILL.md at .agents/skills/go-http-handler/SKILL.md, skills/go-http-handler/references/handler.go at .agents/skills/go-http-handler/references/handler.go, skills/go-http-handler/references/handler_test.go at .agents/skills/go-http-handler/references/handler_test.go. The "GitHub Copilot" tab on this page has the curl commands, or download https://loadout.jnw-it.com/download/go-service/copilot.zip, which is already laid out. Do not overwrite an existing AGENTS.md or CLAUDE.md; merge it.

Has Go service rules been tested?

It passed the Level 1 automated install checks on 2026-10-17: the files parse, install to each agent's documented paths, and pass the safety scan. No AI agent has run it yet, so no agent pass or fail is claimed.

More for Claude Code, Codex, Cursor, Gemini CLI, Antigravity CLI and GitHub Copilot.