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
Verification
| Check | Result | What we found |
|---|---|---|
| Listinglisting.yaml matches the schema and declares every file in the folder. | Pass | Schema valid; 6 files declared, none missing or extra
|
| 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
|
| 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
|
| 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
|
| 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
|
| 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
|
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/.
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
| File | Goes to |
|---|---|
AGENTS.md | AGENTS.md |
CLAUDE.md | CLAUDE.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.
Codex CLI reads AGENTS.md and skills from .agents/skills/.
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 .agents/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 .agents/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 .agents/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
| File | Goes to |
|---|---|
AGENTS.md | AGENTS.md |
skills/go-http-handler/SKILL.md | .agents/skills/go-http-handler/SKILL.md |
skills/go-http-handler/references/handler.go | .agents/skills/go-http-handler/references/handler.go |
skills/go-http-handler/references/handler_test.go | .agents/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.
Cursor reads AGENTS.md + .cursor/rules/*.mdc and skills from .agents/skills/.
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 .agents/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 .agents/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 .agents/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
| File | Goes to |
|---|---|
AGENTS.md | AGENTS.md |
skills/go-http-handler/SKILL.md | .agents/skills/go-http-handler/SKILL.md |
skills/go-http-handler/references/handler.go | .agents/skills/go-http-handler/references/handler.go |
skills/go-http-handler/references/handler_test.go | .agents/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.
Gemini CLI reads GEMINI.md (imports AGENTS.md with @./AGENTS.md) and skills from .agents/skills/.
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 GEMINI.md https://loadout.jnw-it.com/raw/go-service/1.0.0/GEMINI.md curl -fsSL --create-dirs -o .agents/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 .agents/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 .agents/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
| File | Goes to |
|---|---|
AGENTS.md | AGENTS.md |
GEMINI.md | GEMINI.md |
skills/go-http-handler/SKILL.md | .agents/skills/go-http-handler/SKILL.md |
skills/go-http-handler/references/handler.go | .agents/skills/go-http-handler/references/handler.go |
skills/go-http-handler/references/handler_test.go | .agents/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.
Antigravity CLI reads AGENTS.md (read natively; GEMINI.md is also read) and skills from .agents/skills/.
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 .agents/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 .agents/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 .agents/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
| File | Goes to |
|---|---|
AGENTS.md | AGENTS.md |
skills/go-http-handler/SKILL.md | .agents/skills/go-http-handler/SKILL.md |
skills/go-http-handler/references/handler.go | .agents/skills/go-http-handler/references/handler.go |
skills/go-http-handler/references/handler_test.go | .agents/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.
GitHub Copilot reads AGENTS.md and skills from .agents/skills/.
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 .agents/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 .agents/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 .agents/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
| File | Goes to |
|---|---|
AGENTS.md | AGENTS.md |
skills/go-http-handler/SKILL.md | .agents/skills/go-http-handler/SKILL.md |
skills/go-http-handler/references/handler.go | .agents/skills/go-http-handler/references/handler.go |
skills/go-http-handler/references/handler_test.go | .agents/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
# 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
# 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
# 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
---
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
// 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
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
Credits
Public work that inspired this loadout. The wording here is our own; follow the links for the originals.
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.