Go Ultimate Skill
SkillFiles & storageThe complete Go development skill. REQUIRED for ALL Go work — writing, refactoring, reviewing, generating, scaffolding, or discussing Go code, including any change to .go files. Use whenever the user mentions Go, Golang, go.mod, a Go package, or asks to build a Go backend service, CLI, library, script, MCP server (Model Context Protocol), or AI/LLM agent with tool calling or ReAct-style reasoning. Routes by project type to the right architecture, conventions, and review checklist. Highly opinionated; overrides generic Go style and lint guidance on conflicts.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Go Ultimate Skill skill
What this skill tells your AI
The instructions your AI receives, as published by djarvur/go-ultimate in skills/go-ultimate/SKILL.md and read by ahel’s review.
A single, opinionated skill for writing the best Go programs — synthesized from four general-Go skills, four agent/MCP donors (one donor, eino, contributes two documents), the Google and Uber style guides, and a repository/production-practice donor. Opinions represent the synthesized consensus; where the donors disagreed, this skill resolved the conflict per the precedence ladder below.
When this skill applies
Always, for any Go work: code generation, refactoring, code review,
architecture and style discussions, scaffolding, or any change to .go files.
It overrides generic Go style/lint guidance when they conflict.
Setup — resolving <skill-dir>
Several instructions in this skill reference <skill-dir> — the absolute path to
this installed skill directory. Resolve it once per session.
Primary rule: <skill-dir> is the directory containing this SKILL.md.
That always works, regardless of how the skill was installed. The bundled
detector is at <skill-dir>/scripts/goversion/main.go; the templates are at
<skill-dir>/assets/.
This skill ships a manifest for each supported harness (see the repo root), so it can be installed as a plugin on all of them. Each harness resolves the plugin root differently; use the row matching yours:
| Harness | <skill-dir> resolution |
|---|---|
| Claude Code (plugin) | ${CLAUDE_PLUGIN_ROOT}/skills/go-ultimate — the harness resolves this at runtime; the path includes a version directory, so do not hardcode it. |
| Codex (plugin) | ${PLUGIN_ROOT}/skills/go-ultimate — Codex exposes the plugin root via ${PLUGIN_ROOT} in hook/script contexts. |
| Cursor (plugin) | the plugin's skills/go-ultimate/ directory; Cursor installs plugins into its cache. Confirm the absolute path via Cursor's plugin UI. |
| Grok Build (plugin) | the plugin's skills/go-ultimate/ directory; Grok reads Claude-compatible plugin content. |
| GitHub Copilot CLI (plugin) | the plugin's skills/go-ultimate/ directory. |
| ZCode | ~/.zcode/skills/go-ultimate (or the workspace .zcode/skills/); ZCode also recognizes the .claude-plugin/ manifest. |
| OpenCode | the directory you copied skills/go-ultimate/ into (manual install — see README). |
| Any harness (manual clone) | the cloned skills/go-ultimate/ directory. |
The
<skill-dir>path matters for this skill. Unlike markdown-only skills, go-ultimate executes its bundled detector (scripts/goversion/main.go) and references itsassets/templates by path. If your harness does not expose the plugin root through a variable (Cursor, Grok, Copilot, OpenCode), locate the installedskills/go-ultimate/directory once and use that absolute path. As a fallback, the detector is a stdlib-only single file — copymain.gointo the target project and run it there if path resolution fails.
How to use this skill
- Detect the project's Go version by running the bundled detector
go run <skill-dir>/scripts/goversion/main.go <project-path>(it prints the bare version, e.g.1.24.3, and always exits 0 — falling back to the Go runtime version if nogo.modor nogodirective is found). Use features up to that version. See references/modern-go.md. - Identify the project type using the decision tree below, then load the matching reference.
- Follow the non-negotiable principles below — these always apply.
- On conflicts between references, apply the precedence rules at the end.
Project-type decision tree
Ask "what is the user building?" and route accordingly:
Is the code a single binary that the user runs?
├── Yes → Is it < ~300 lines with no external deps beyond stdlib?
│ ├── Yes → SCRIPT / TINY TOOL
│ │ → references/project-layouts.md § Scripts
│ │ → references/engineering-policy.md
│ └── No → CLI APPLICATION
│ → references/project-layouts.md § CLI
│ → references/engineering-policy.md
│
Is the code meant to be imported by other modules?
├── Yes → LIBRARY / MODULE
│ → references/libraries.md
│ → references/project-layouts.md § Library
│ → references/engineering-policy.md
│
Is the code a long-running server (HTTP/gRPC/messaging)?
├── Yes → BACKEND SERVICE
│ → references/architecture.md (mandatory)
│ → references/production-readiness.md (mandatory)
│ → references/project-layouts.md § Service
│ → references/engineering-policy.md
│
Is the code a server exposing tools/resources/prompts to LLMs over MCP?
├── Yes → MCP SERVER
│ → references/mcp-server.md (mandatory)
│ → references/project-layouts.md § Service or § CLI (stdio server = CLI-shaped)
│ → references/production-readiness.md (if hosted/long-running, not stdio)
│ → references/engineering-policy.md
│
Is the code an LLM-driven agent that calls tools / orchestrates multi-step reasoning?
├── Yes → AI AGENT
│ → references/agents.md (mandatory)
│ → references/project-layouts.md § CLI or § Service (depends on hosting)
│ → references/production-readiness.md (if hosted/long-running)
│ → references/engineering-policy.md
│
Is the code a code generator, linter, or analysis tool?
├── Yes → Treat as CLI APPLICATION or LIBRARY (whichever fits the distribution),
│ then see references/engineering-policy.md § Code generation
│
Otherwise → ask the user to clarify before proposing structure.
Regardless of type: when initializing a repository, adding CI, or reviewing
repository hygiene, also load
references/repo-and-ci.md — required files, ignore
baselines, go tool pinning, workflow shape, release stamping.
Non-negotiable principles (always apply)
These are the consensus backbone. Every Go file this skill touches obeys them.
-
Modern Go, version-gated. Use every feature up to the project's
go.modversion.anyoverinterface{}.errors.Is/Asover==.slices/maps/cmpover hand-rolled loops. See references/modern-go.md. -
No
pkg/directory. Ever. Library code lives at the module root; importable apps expose a publicport/package. Thepkg/convention is a kubernetes-era anti-pattern. See references/project-layouts.md. -
internal/for private code;cmd/<name>/for multiple binaries; flat for tiny tools. Start simple; grow deliberately. -
Context first, errors explicit.
func F(ctx context.Context, ...) (..., error). Wrap withfmt.Errorf("...: %w", err). Never compare errors with==. -
Thin adapters, fat-free imports. Business-logic packages never import
net/http,os, or transport SDKs. Adapters only translate formats and protocol shapes. -
Concurrency hygiene. Every goroutine has an exit condition (Context or WaitGroup). Use
errgroupfor parallel fan-out. Always test with-race. -
Accept interfaces, return structs. Interfaces are defined at the point of use, not the point of implementation. Small, single-method interfaces win.
-
Comments explain why, not what. Named, idiomatic, exported identifiers do the rest.
-
Typed contracts at boundaries. MCP tool args and agent inter-node data flow are typed structs (generics where the framework supports it), never
map[string]anyas the universal contract. See references/mcp-server.md and references/agents.md.
Quick reference (top rules, with link to detail)
| Rule | Detail |
|---|---|
| Detect Go version, use features up to it | modern-go.md |
| Pick layout by project type | project-layouts.md |
| Service architecture: bounded-context hexagonal | architecture.md |
package main: thin, run(ctx, cfg) error pattern, no testable logic in main() | engineering-policy.md |
| Config: Resolvable Config Struct (not Functional Options) | engineering-policy.md |
if x := f(); cond only when init is the condition; else separate statement | engineering-policy.md |
Errors: sentinels via errors.Is, typed via errors.As, wrap with %w, aggregate with errors.Join | engineering-policy.md |
Tests: vanilla testing, package xxx_test, TestF_suffixCamelCase names | testing.md |
Mocks: go.uber.org/mock (gomock) default; testify-mocks only if already on testify | testing.md |
| Review: Critical / Important / Suggestion / Positive buckets, What-Why-How per issue | code-review.md |
Libraries: README (rationale + honest comparison + payoff-first quick start) vs doc.go (contracts) | libraries.md |
go.mod: apps latest, libraries latest-1 | engineering-policy.md |
Lint: golangci-lint + govet + go test -race mandatory in CI | engineering-policy.md |
Naming: MixedCaps, initialism case (userID, HTTPClient), no Get prefix, no util/common package | engineering-policy.md |
%w only when the cause is intended as API; %v for a dependency's error crossing a public boundary | engineering-policy.md |
No mutable globals; no goroutines or I/O in init(); comma-ok on every type assertion | engineering-policy.md |
Fan-out is bounded (SetLimit/semaphore); channels unbuffered or size 1 | engineering-policy.md |
Repo must have LICENSE, README.md, AGENTS.md, ignore files, .golangci.yml, CI; tools pinned via go tool | repo-and-ci.md |
| Services: bounded calls, safe retries, stable error contract, liveness≠readiness, outbox, rolling-safe migrations | production-readiness.md |
MCP server: official go-sdk, typed tool handlers, two-channel errors, tool design as outcomes-not-operations | mcp-server.md |
AI agent: ReAct loop w/ bounded iterations, 6 topology archetypes, type-aligned composition (reject map[string]any between nodes) | agents.md |
Conflict precedence (which reference wins)
When two references seem to disagree:
- Layout / architecture / ports / wiring / modular monolith for services → architecture.md wins.
- Version-gated syntax (whether a feature exists in this Go version) → modern-go.md wins.
- Everything else (config, errors, testing, naming, linting, dependencies, CI) → engineering-policy.md wins.
- Library public-API concerns (semver, deprecation, doc.go split) → libraries.md wins for library projects.
- Code review output format → code-review.md wins.
- MCP servers in Go (SDK choice, tool-handler design, two-channel errors, pagination, middleware) → mcp-server.md wins.
- AI agents in Go (ReAct loop, multi-agent topology, typed data flow between nodes, state externalism) → agents.md wins.
- Runtime behavior of a long-running service (timeout/retry/idempotency policy, API error contract, liveness vs readiness, metric cardinality, migration safety, outbox) → production-readiness.md wins. It refines rule 3: engineering-policy sets the observability floor, this sets the service shape.
- Concrete repository and pipeline files (required files, ignore baselines,
workflow YAML,
go toolpinning, build stamping) → repo-and-ci.md wins. It also refines rule 3: engineering-policy states which gates are mandatory, this states how they are written.
The adapter carve-out (mcp-server.md § "Adapter
carve-out") refines rule 5 of the non-negotiable principles for MCP handlers
only: the handler package is an inbound adapter and may import mcp.*.
Project-file precedence (escalation rule)
When a project-level instruction file contradicts this skill, follow this order, stopping at the first match:
- Explicit user instruction in the current turn — always wins. If the user says "use Functional Options here," use them, even though the skill mandates Resolvable Config Struct.
- Project
AGENTS.md/CLAUDE.mdat the repo root — wins over this skill for project-specific conventions. A project that legitimately needspkg/(e.g. a kubernetes-style repo) says so there. - This skill — the default for any Go decision not addressed above.
- Generic Go style/lint guidance — lowest priority; this skill overrides it on conflicts by design.
If (1) and (2) are silent and the skill's rule feels wrong for the project, say so out loud before applying it — propose the deviation, name the rule it contradicts, and let the user decide. Do not silently override the skill, and do not silently apply it when a project file arguably contradicts it.
Verification
After applying this skill to a Go project, the project should pass:
go vet ./...
go build ./...
go test -race ./...
If any of these fail as a result of changes made under this skill, that is a
skill regression — surface it, do not paper over it. For new projects scaffolded
from assets/, the result should compile and test green before handing control
back to the user.
Evaluating the skill itself
Example prompts and expected behaviors for catching drift live in
evals/. Run them when the skill is updated. The audit
methodology that produced this skill is not shipped with it; the rules above are
the canonical source.
This skill is highly opinionated. Do not relitigate these rules at runtime —
apply them, and note any project-specific deviation in the project's own
AGENTS.md / CLAUDE.md if one exists.
Signals
- GitHub stars
- 22
- Forks
- 2
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
go-ultimate- Source
- github.com/djarvur/go-ultimate