go-functions — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited go-functions (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
A function's surface is read more often than its body. Optimize for the reader: predictable ordering in the file, signatures that scan, no hidden bool flags.
/* name */ comments at call sites.go vet can check the format.type Server struct{ ... }
func NewServer(...) *Server { ... } // constructor next to type
func (s *Server) Start(ctx context.Context) error { ... } // exported
func (s *Server) Stop() error { ... }
func (s *Server) acceptLoop() { ... } // unexported
func parseAddr(s string) (string, error) { ... } // file-local helperRules:
// Fits on one line — keep it on one line
func Sum(xs []int) int
// Too long — break with every param on its own line
func (r *Repo) SaveTransaction(
ctx context.Context,
userID string,
tx Transaction,
opts ...SaveOption,
) (string, error) {
...
}The trailing comma is required and gofmt-stable.
// Bad — what does `true` mean?
NewServer(":8080", true, 30, false)
// Better — call-site comments
NewServer(":8080", true /* tls */, 30 /* maxConn */, false /* readonly */)
// Best — named types or options
NewServer(":8080", WithTLS(), WithMaxConn(30))When a single bool is genuinely binary and obvious from the function name (SetVerbose(true)), it's fine.
Read references/signatures.md for return-value styles, naked returns, function-as-parameter formatting, and the variadic-options call-site shape.
// Bad
func process(r *io.Reader) { ... }
// Good
func process(r io.Reader) { ... }An interface value already carries a pointer-sized data word. *io.Reader is a pointer to an interface — almost always a mistake.
Functions that accept a format string should end in f:
func Logf(format string, args ...any)go vet then checks that %s, %d, etc. match the argument types.
When formatting strings into errors or logs, prefer %q:
return fmt.Errorf("unknown key %q", key) // unknown key "foo\nbar"%q quotes and escapes; %s plus manual quoting ("key \"" + key + "\"") is fragile.
Read references/printf-and-stringer.md for%vvs%svs%q, implementingfmt.Stringersafely, avoidingString()infinite recursion, andfmt.Formatter.
db.Open(addr,
db.WithCache(false),
db.WithLogger(log),
db.WithRetries(3),
)Each option on its own line, trailing comma. Use this layout whenever the call doesn't fit on a single line.
A constructor immediately follows its type. Use the short form when no error is possible:
type Counter struct{ n int }
func NewCounter() *Counter { return &Counter{} }Return an error when construction can fail:
func NewClient(addr string) (*Client, error) { ... }Don't expose a half-built type through a constructor that "always succeeds" but requires Init() afterward.
| Anti-pattern | Why it hurts | Do this instead |
|---|---|---|
| Methods scattered randomly in the file | Hard to navigate | Group by type, exported-first |
| Five-argument wrapped signature with no trailing comma | gofmt keeps reformatting | Trailing comma |
func process(r *io.Reader) | Pointer to interface | Pass io.Reader |
Log(msg string, format bool, ...) | Combines two concerns; vet blind | Separate Log and Logf |
Open(":8080", true, false, 30) | Unreadable booleans | Named options or /* */ comments |
fmt.Errorf("got %s", key) for arbitrary key | Special chars unclear in output | %q |
Returning *MyError (concrete pointer) | Typed-nil interface trap | Return error |
/* */ commentsf%q when formatting arbitrary strings(*T, error) when construction can fail — no half-built objectsfmt.Stringer, recursion traps, fmt.Formatter~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.