Skip to main content
ClaudeWave
Skill74 repo starsupdated 7d ago

go-code-review

The go-code-review skill systematically audits Go code for idiomatic patterns, error handling, concurrency safety, and common mistakes by reading full function context, checking the go.mod version directive, applying version-gated advice for Go 1.18+ generics, 1.20+ errors.Join, and 1.21+ slog, then verifying findings against a structured protocol before reporting issues with severity levels.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/existential-birds/beagle /tmp/go-code-review && cp -r /tmp/go-code-review/plugins/beagle-go/skills/go-code-review ~/.claude/skills/go-code-review
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# Go Code Review

## Review Workflow

Follow this sequence **in order**. Do not emit findings until every **Pass** below is satisfied.

1. **Baseline `go.mod`** — Open `go.mod` and read the `go` directive.  
   **Pass:** You can state the exact `go X.YY` value (in the review preamble or working notes). Apply version-gated advice only when it matches this baseline (loop capture pre-1.22, `slog`/structured logging from 1.21, `errors.Join` from 1.20).

2. **Read surrounding code** — For each changed `.go` file, read full functions or logical units that contain the edits, not only the diff hunk.  
   **Pass:** At least one full enclosing function (or package-level `init`/var block) containing the change was read per changed file.

3. **Scope the checklist** — Decide which [Review Checklist](#review-checklist) blocks apply (error handling, concurrency, interfaces/types, resources, naming). Load [references](#quick-reference) for those blocks; skip blocks that are irrelevant to the diff.  
   **Pass:** The review (or working notes) lists which checklist blocks you applied, or marks blocks N/A with a one-line reason tied to the diff (e.g. “no concurrency in change”).

4. **Pre-report verification** — Load and follow [review-verification-protocol](../review-verification-protocol/SKILL.md).  
   **Pass:** The protocol’s **Pre-Report Verification Checklist** is satisfied for each finding you will report (actual code read, surrounding context checked, “wrong” vs “different style” distinguished, etc.).

## Hard gates (same sequence, shorter)

| Step | Objective pass condition |
| --- | --- |
| 1 | `go X.YY` from `go.mod` is recorded before version-specific advice. |
| 2 | Full enclosing context read per changed file, not diff-only. |
| 3 | In-scope checklist blocks listed or N/A with diff-tied reason; references opened as needed. |
| 4 | `review-verification-protocol` completed for every reported issue. |

## Output Format

Report findings as:

```text
[FILE:LINE] ISSUE_TITLE
Severity: Critical | Major | Minor | Informational
Description of the issue and why it matters.
```

## Quick Reference

| Issue Type | Reference |
|------------|-----------|
| Missing error checks, wrapping, errors.Join | [references/error-handling.md](references/error-handling.md) |
| Race conditions, channel misuse, goroutine lifecycle | [references/concurrency.md](references/concurrency.md) |
| Interface pollution, naming, generics | [references/interfaces.md](references/interfaces.md) |
| Resource leaks, defer misuse, slog, naming | [references/common-mistakes.md](references/common-mistakes.md) |

## Review Checklist

### Error Handling
- [ ] All errors checked (no `_ = err` without justifying comment)
- [ ] Errors wrapped with context (`fmt.Errorf("...: %w", err)`)
- [ ] `errors.Is`/`errors.As` used instead of string matching
- [ ] `errors.Join` used for aggregating multiple errors (Go 1.20+)
- [ ] Zero values returned alongside errors

### Concurrency
- [ ] No goroutine leaks (context cancellation or shutdown signal exists)
- [ ] Channels closed by sender only, exactly once
- [ ] Shared state protected by mutex or sync types
- [ ] WaitGroups used to wait for goroutine completion
- [ ] Context propagated through call chain
- [ ] Loop variable capture handled (pre-Go 1.22 codebases only)

### Interfaces and Types
- [ ] Interfaces defined by consumers, not producers
- [ ] Interface names follow `-er` convention
- [ ] Interfaces minimal (1-3 methods)
- [ ] Concrete types returned from constructors
- [ ] `any` preferred over `interface{}` (Go 1.18+)
- [ ] Generics used where appropriate instead of `any` or code generation

### Resources and Lifecycle
- [ ] Resources closed with `defer` immediately after creation
- [ ] HTTP response bodies always closed
- [ ] No `defer` in loops without closure wrapping
- [ ] `init()` functions avoided in favor of explicit initialization

### Naming and Style
- [ ] Exported names have doc comments
- [ ] No stuttering names (`user.UserService` → `user.Service`)
- [ ] No naked returns in functions > 5 lines
- [ ] Context passed as first parameter
- [ ] `slog` used over `log` for structured logging (Go 1.21+)

## Severity Calibration

### Critical (Block Merge)
- Unchecked errors on I/O, network, or database operations
- Goroutine leaks (no shutdown path)
- Race conditions on shared state (concurrent map access without sync)
- Unbounded resource accumulation (defer in loop, unclosed connections)

### Major (Should Fix)
- Errors returned without context (bare `return err`)
- Missing WaitGroup for spawned goroutines
- `panic` for recoverable errors
- Context not propagated to downstream calls

### Minor (Consider Fixing)
- `interface{}` instead of `any` in Go 1.18+ codebases
- Missing doc comments on exports
- Stuttering names
- Slice not preallocated when size is known

### Informational (Note Only)
- Suggestions to add generics where code generation exists
- Refactoring ideas for interface design
- Performance optimizations without measured impact

## When to Load References

- Reviewing error return patterns → error-handling.md
- Reviewing goroutines, channels, or sync types → concurrency.md
- Reviewing type definitions, interfaces, or generics → interfaces.md
- General review (resources, naming, init, performance) → common-mistakes.md

## Valid Patterns (Do NOT Flag)

These are acceptable Go patterns — reporting them wastes developer time:

- **`_ = err` with reason comment** — Intentionally ignored errors with explanation
- **Empty interface / `any`** — For truly generic code or interop with untyped APIs
- **Naked returns in short functions** — Acceptable in functions < 5 lines with named returns
- **Channel without close** — When consumer stops via context cancellation, not channel close
- **Mutex protecting struct fields** — Even if accessed only via methods, this is correct encapsulation
- **`//nolint` directives with reason** — Acceptable when accompanied by explanation
- **Defer in loop*
release-tagSlash Command

tag and push a release after the release PR is merged

releaseSlash Command

create a release PR (auto-detects previous tag)

deepagents-architectureSkill

Guides architectural decisions for Deep Agents applications. Use when deciding between Deep Agents vs alternatives, choosing backend strategies, designing subagent systems, or selecting middleware approaches.

deepagents-code-reviewSkill

Reviews Deep Agents code for bugs, anti-patterns, and improvements. Use when reviewing code that uses create_deep_agent, backends, subagents, middleware, or human-in-the-loop patterns. Catches common configuration and usage mistakes.

deepagents-implementationSkill

Implements agents using Deep Agents. Use when building agents with create_deep_agent, configuring backends, defining subagents, adding middleware, or setting up human-in-the-loop workflows.

langgraph-architectureSkill

Guides architectural decisions for LangGraph applications. Use when deciding between LangGraph vs alternatives, choosing state management strategies, designing multi-agent systems, or selecting persistence and streaming approaches.

langgraph-code-reviewSkill

Reviews LangGraph code for bugs, anti-patterns, and improvements. Use when reviewing code that uses StateGraph, nodes, edges, checkpointing, or other LangGraph features. Catches common mistakes in state management, graph structure, and async patterns.

langgraph-implementationSkill

Implements stateful agent graphs using LangGraph. Use when building graphs, adding nodes/edges, defining state schemas, implementing checkpointing, handling interrupts, or creating multi-agent systems with LangGraph.