review-go
Use when reviewing, debugging, or giving feedback on Go code in this repo (exercises/part2, website/tools, or any *.go file) or when asked for a "code review", "review this Go", "revisa este código Go
SKILL.md.opencode/skills/review-go/SKILL.md
GitHubGo Code Review
You review Go code like the strictest reviewer and the meanest test-designer combined. You think about what could break and whether the code would survive a test that actually checks it. You do not stop at "it compiles."
Steps
- Read the code first — read every file in scope in full before judging. Understand what it is for (grep for callers/uses) before reviewing how.
- Verify it builds and is formatted — from the package dir run
go vet ./...,go build ./...(orgofmt -l .), and fix anything mechanical before going deeper. In this repo, stdlib exercises without ago.modneedGO111MODULE=off(the parent.gitconfuses module mode); that "cannot find main module" error is expected, not a code bug. - Review the dimensions below.
- Test-thinking pass — for each concern, name the test that would catch it.
- Report in the output format at the bottom.
Review dimensions
- Correctness — does it do what it claims? Right protocol/algorithm, right boundaries, right ordering, right error semantics. Check off-by-one, empty-input, and single-element cases explicitly.
- Error handling — every error checked and handled meaningfully. No
swallowed errors (
_), no barepanicon recoverable input, errors wrapped with context (fmt.Errorf("...: %w", err)),deferon close that still surfaces errors where it matters. - Resource management — every
net.Conn,net.Listener,http.Responsebody,io.Reader, file, and goroutine cleaned up.defer r.Body.Close()present and correct. No leaked listeners, unclosed sockets, or files. - Concurrency — goroutines must be stoppable; channels closed exactly
once;
sync.WaitGroupcorrect; no busy-loops without backoff; shared state under mutex or confined; contexts respected (context.WithTimeout,SetDeadline). Watch for data races and double-close. - Idiomatic Go —
io.Copyover manual loops,net.JoinHostPortoverfmt.Sprintf("%s:%d", ...),bufio.Scannerwith error check,errors.Isfor unwrapping,strconvover hand-rolled parsing, table-driven tests. - Performance — allocations in hot loops,
strings.Builderover string concatenation in loops,sync.Poolonly when justified, avoid premature optimization (note it as a nit, not a blocker, unless measurable). - Security — no hardcoded secrets or keys, no shell injection (use
execwith args, neversh -con concatenated input), bounds-checked reads, no unbounded memory growth from untrusted input, TLS used where the context demands it,net/httptimeouts set on server and client.
Test-thinking checklist (the superpower)
For every concern ask: if I wrote a test, what would it break?
- Edge inputs — empty, oversized, truncated, malformed, maximum-length.
- Races — concurrent access, shared state, read/write from two goroutines on one connection.
- Timeouts/hangs — does a slow or silent peer block forever?
- Leaks — goroutines that outlive their scope, unclosed resources.
- Panics — does malformed input crash or return a clean error?
- Flakiness — fixed ports vs ephemeral
:0; would a timed test be flaky?
Output format
- Verdict — build/vet/gofmt result, then pass/fail per dimension (correctness, errors, resources, concurrency, idiom, performance, security).
- Issues prioritized:
- Critical — broken build, wrong behavior, race, leak, security hole.
- Important — missing cleanup, swallowed error, correctness gap.
- Style — naming, formatting, idiom nits.
Each with
file:line, the problem, and the fix as a code snippet.
- Test plan — the 3-6 tests you would write and exactly which bug each would expose.
- When asked to fix, apply edits with the Edit tool, then re-run the verify commands and confirm the code is clean before reporting done.