golang-style
Skill2 starsChanged 10 days agoBSD-3-ClauseView on GitHub
Write and review well-structured, safe, idiomatic Go (naming, formatting, function and package design, error handling, code structure, and the HTTP/CLI/store patterns used across this codebase). Use when writing new Go, reviewing a diff for structure and idioms, or deciding how to lay out a package, name things, handle errors, or shape a function. Complements golang-pro (which owns concurrency, channels, generics depth, pprof, and gRPC). Invoke for Go code structure, idiomatic Go, gofmt/golangci-lint, error wrapping, package layout, function design, or "make this more idiomatic".
1 other project uses a version of this.
Adopted by
Most recently taken up by
- czyt/tinyskillstheir own version, first seen Aug 12, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- czyt/tinyskills★ 7same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository13 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- mods/CLAUDE.mdCLAUDE.md
- webkit/CLAUDE.mdCLAUDE.md
- llms.txtllms.txt
- askSkill
- golang-proSkill
- handoffSkill
- harvestSkill
- humanizerSkill
- loomSkill
- presentSkill
- upgrade-noteSkill
- worklogSkill
The file
We split this skill into the rules it gives an agent
8 rules. About 0 are common, 3 are distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Very specific: line 30
Side effects at the edges: keep pure model and helpers in one file, the I/O shell in another.
- Distinctive: line 35
Docs: every package has a doc comment that states its contract.
- Very specific: line 59
Put main in cmd/<tool>/main.go as a thin shim over internal/cli.Execute().
- Very specific: line 67
Run golangci-lint run ./...
- Very specific: line 72
No functional-options (WithX) pattern.
- Very specific: line 73
No third-party logging (zap/logrus/slog adoption), assertion libraries (testify), or error libraries (pkg/errors) unless asked.
- Distinctive: line 75
No interface returned from a constructor.
- Distinctive: line 84
Reviewing: read the diff against the checklist below.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Golang Style
Write Go the way the house codebase already writes it: stdlib-first, compact, explicit, anti-magic. The house codebase is thismoon, the repo this skill ships from. "This codebase" and "this repo" in this skill and its references mean thismoon, even when the task is in another Go repo. This skill carries the house template (the cmd/ + internal/ layout, cobra CLIs, net/http servers, file-backed stores, fmt.Errorf("%w") errors, hermetic table tests) plus the idioms that keep it consistent. It reinforces what the code does well and tightens the few places it drifts.
Split with golang-pro: golang-pro owns concurrent systems (goroutine patterns, channel pipelines, deep generics, pprof, gRPC, microservices). This skill owns how code is structured and written: naming, formatting, function and package design, error handling, safety, and the repo's HTTP/CLI/store/MCP patterns. When a task is "build a concurrent worker pool", use golang-pro. When it is "is this package laid out right, are the errors wrapped, is this function shaped well", use this skill.
Where the two disagree, this skill wins. golang-pro is vendored beside this skill (skills/golang-pro, from jeffallan/claude-skills) and its generic advice conflicts with house style in several places. It teaches functional options (banned here, config structs), var _ Iface satisfaction asserts (not house style, see language.md), and a pkg/ public-library layout (house layout is cmd/ + internal/ only). It also puts context.Context on every blocking operation, where house style keeps it at process, exec, and HTTP boundaries (see safety.md). And it runs every test under -race, where house style adds -race for concurrent changes and scales testing to the risk (see testing.md). Take its concurrency, generics, and profiling content, and follow this skill on everything else.
House style in one screen
- Layout: one module per tool.
cmd/<tool>/main.gois thin and callsinternal/cli.Execute(). Everything else lives underinternal/, in packages named for their role (store,server,ticker,proxy,notify). Noutil/common/helpers. - Constructors:
New(...)returns a concrete*T, or(*T, error)when construction can fail. Never return an interface. - Config in, not options: pass an
Input/Config/Patchstruct, not a long parameter list and not functionalWithXoptions. Use pointer fields (*string) when "omitted" must differ from "cleared". - Interfaces at the consumer: define small interfaces (1–3 methods) in the package that consumes them, for a test seam. Accept interfaces, return concrete types.
- Errors: wrap with
%wwhenever there is an underlying error. Package-prefix sentinel messages (present: page not found). Map sentinels to status/exit at the boundary witherrors.Is/errors.As. Handle an error once: log it or return it, never both. - Side effects at the edges: keep pure model and helpers in one file, the I/O shell in another. Push
exec, file writes, notifications, and time to the edge behind a small interface or an injectednow func() time.Time. - Boundary parsing: parse and validate CLI, HTTP, config, and persisted input at the boundary. Pass typed, trusted values into the core and keep each invariant in one place.
- Lifetimes: pair acquired resources with cleanup, pass
context.Contextat real boundaries, and make every goroutine's exit condition visible. - Format + lint:
goimports+golines -m 100+gofumptbase;golangci-lint run ./...is the house linter. - Tests: stdlib
testingonly (no testify). Derive expected behavior from the contract, not the implementation. Use table tests,t.Helper(),t.TempDir(), and an injected clock for hermeticity. Add-racefor concurrent changes and fuzz parsers when their input risk warrants it. - Docs: every package has a doc comment that states its contract; every exported name has a doc comment starting with its name.
Reference guide
Load the file that matches the task.
| Topic | Reference | Load when |
| Package & project layout, file organization | references/structure.md | Laying out a tool, splitting packages, ordering a file |
| Naming | references/naming.md | Naming packages, types, funcs, receivers, errors |
| Format & lint toolchain | references/formatting.md | gofumpt/golines/goimports, golangci-lint, imports, go vet |
| Function & method design | references/functions.md | Input structs, receivers, returns, consumer interfaces |
| Error handling | references/errors.md | Wrapping, sentinels, errors.Is/As, custom types, layering |
| Safety | references/safety.md | Nil/zero values, defer, copying, context, single-writer |
| Language-level idioms | references/language.md | Panic/recover, init(), iota enums, embedding, type assertions, time values |
| Testing | references/testing.md | Table tests, helpers, injected clocks, httptest |
| HTTP services | references/http.md | net/http ServeMux, JSON helpers, shutdown, middleware |
| CLI (cobra) | references/cli.md | Root command, RunE builders, flags, build metadata |
| Stores & persistence | references/store.md | File-backed stores, model/store split, ~ expansion |
| MCP servers | references/mcp.md | go-sdk tool handlers, structured input/output |
Constraints
Do
- Put
mainincmd/<tool>/main.goas a thin shim overinternal/cli.Execute(); print the error once andos.Exit(1). - Wrap underlying errors with
%winfmt.Errorf(this is the one place the codebase drifts:worklog/internal/store/store.gouses%v; new and touched code uses%w). - Package-prefix sentinel error messages.
- Return concrete types from constructors; define interfaces where they are consumed.
- Pass an
Input/Config/Patchstruct instead of 4+ positional parameters. - Parse untrusted input at CLI, HTTP, config, and persistence boundaries before passing typed values inward.
- Make resource and goroutine lifetimes explicit; every acquired resource has cleanup and every goroutine has a visible exit condition.
- Inject
now func() time.Timeand uset.TempDir()so tests never touch the real$HOMEor wall clock. - Run
golangci-lint run ./...andgoimports/golines/gofumptbefore calling code done. - Give every package a doc comment and every exported name a name-leading doc comment.
Don't
- No
util,common,helpers, orbasepackages. Keep helpers unexported in the package that uses them. - No functional-options (
WithX) pattern; this codebase uses config structs. - No third-party logging (
zap/logrus/slogadoption), assertion libraries (testify), or error libraries (pkg/errors) unless asked. Match the stdlib-first stack. - No
log-and-returnof the same error. - No interface returned from a constructor; no interface defined next to its single implementation just in case.
- No
context.Contextthreaded through local-I/O store layers; keep it at process/exec/HTTP boundaries. - No
panicfor expected errors (input, I/O, network). Panic only on broken invariants (crypto/randfailure, missing embedded asset), package-prefixed; norecoveroutside a single top-level boundary. - No
init()beyond cobra command/flag registration ininternal/cli, and no mutable package-level state business logic writes to; state lives in a struct fromNew(...).
Workflow
Writing: scaffold the layout (structure.md) → name things (naming.md) → shape functions and constructors (functions.md) → wire the surface (http.md / cli.md / store.md / mcp.md) → handle errors (errors.md). Then cover the safety checklist (safety.md) and language-level idioms (language.md) → add hermetic tests (testing.md) → format and lint (formatting.md).
Reviewing: read the diff against the checklist below; cite the specific house pattern the code should match, with a file path from this repo as the example.
Review checklist: definition of done
cmd/<tool>/main.gois thin; the root cobra command setsSilenceUsage/SilenceErrors; errors print once.- Packages are role-named under
internal/; noutil/common. - Constructors return concrete
*T(or(*T, error)); interfaces are defined at the consumer. - 4+ parameters are grouped into an
Input/Configstruct; optional-vs-clear uses pointer fields. - Every
fmt.Errorfwith an underlying error uses%w; sentinels are package-prefixed; boundaries map them witherrors.Is/errors.As. - Side effects sit behind a small interface or injected dependency; the core is pure.
- Boundary input is parsed once into typed values; invariants and mutable state have a clear owner.
- Resource cleanup, context cancellation, and goroutine exit conditions are visible where applicable.
- Tests derive expectations from the contract, reproduce fixed bugs, and are hermetic (
t.TempDir, injected clock);-raceand fuzzing are used when the risk calls for them. - No panic on expected errors; no
init()logic; type assertions use comma-ok; durations aretime.Duration; serialized enums are strings. - Every package and exported name has a doc comment.
golangci-lint run ./...is clean; code isgofumpt+golines -m 100formatted.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

