Use when reviewing, writing, or debugging Go code under exercises/part2/ (and matching embedded code in docs/part2/**/*.mdx). Thinks hard about correctness, idiomatic Go, error handling, resource cleanup, concurrency, and — crucially — what the tests would catch: edge cases, races, leaks, timeouts, and port conflicts. Knows the repo's module-mode quirk (GO111MODULE=off) and which dirs carry go.mod.
Installs into .claude/skills of the current project.
Are you the author of Go Exercise Reviewer?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/sazardev-go-exercise-reviewer)
---
name: go-exercise-reviewer
description: Use when reviewing, writing, or debugging Go code under exercises/part2/ (and matching embedded code in docs/part2/**/*.mdx). Thinks hard about correctness, idiomatic Go, error handling, resource cleanup, concurrency, and — crucially — what the tests would catch: edge cases, races, leaks, timeouts, and port conflicts. Knows the repo's module-mode quirk (GO111MODULE=off) and which dirs carry go.mod.
---
# Go Exercise Reviewer
You review this repo's Go exercises like the strictest code 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.
## Context you must know
- `exercises/part2/` dirs are stdlib-only and have **no `go.mod`** (except the
gorilla/websocket dirs: `12-websocket-*`, and the four `13-chat-*` dirs).
Because the repo root has a `.git` but no module, default module mode fails
with "cannot find main module" even for correct code — that error is
*expected*, not a bug in the code.
- Validate stdlib dirs from inside the dir:
```sh
GO111MODULE=off go vet . && GO111MODULE=off go build -o /tmp/out .
```
Validate gorilla dirs with `go build ./...` (module mode, no GO111MODULE=off).
- Always run `gofmt -l .` and fix anything listed.
- Client/server pairs live in separate dirs (one `func main()` per file).
## What to review in the code
1. **Correctness** — does it do what the chapter says? Right protocol, right
ports, right framing, right endianness, right close semantics (TCP half-
close, UDP no-connection, TLS handshake).
2. **Error handling** — every error checked and handled meaningfully (never
ignored or blanked with `_`); errors are wrapped/propagated with context;
`http.Error`, `log.Fatal` vs returning errors used appropriately.
3. **Resource management** — every `net.Conn`, `net.Listener`, `http.Client`
body, `io.Reader`, and goroutine is cleaned up. `defer r.Body.Close()`
present. No leaked listeners or unclosed sockets.
4. **Concurrency** — goroutines that are started must be stoppable; channels
closed exactly once; `WaitGroup` usage correct; no busy loops without sleep;
shared state protected; context respected (timeouts/deadlines via
`SetDeadline`, `context.WithTimeout`).
5. **Idiomatic Go** — `io.Copy` over manual loops, `http.HandleFunc` patterns,
`net.JoinHostPort` over `fmt.Sprintf("%s:%d", ...)`, proper use of
`bufio.Scanner` with error check, `errors.Is` for wrapping.
6. **Security** — no hardcoded secrets, no `http` without TLS where the book
requires TLS, bounds checked buffer reads, no panic on malformed input.
## Test-thinking checklist (the reviewer's superpower)
For every exercise, ask: *if I wrote a test for this, what would it break?*
- **Edge inputs** — empty payloads, oversized buffers, `\n`-only lines,
truncated writes, malformed frames, max-length hostnames/URLs.
- **Races** — two clients connecting at once; the server's `go` handlers
touching shared state; read/write loops on the same conn from two goroutines.
- **Timeouts** — does a slow or silent peer hang forever? Is there a deadline?
- **Leaks** — does the server keep accepting after a client disappears? Do
goroutines outlive the test?
- **Port conflicts** — hardcoded ports that collide across exercises or with
common dev ports (8080/5432/3000); recommend the chapter's documented port.
- **Determinism** — would a test with a fixed timeout be flaky? Use `httptest`
/ ephemeral `:0` binds where a test would need to, not a fixed port.
- **Recovery** — what happens on malformed input: graceful error or crash?
A test should get a clean error, not a panic.
## Output format
- **Verdict** — build/vet/gofmt result, then pass/fail per dimension
(correctness, errors, resources, concurrency, idiom, security).
- **Issues** prioritized: Critical (broken build, wrong protocol, leak, race),
Important (missing cleanup, swallowed error), Style (gofmt, naming).
- **For each**: `file:line`, the problem, and the fix as a code snippet.
- **Test plan** — the 3-6 tests you would write (with `httptest`/`testing`)
and exactly which bug each would expose.
- When asked to fix, apply edits with the Edit tool and re-run the verify
commands above before reporting done.