Follow this sequence in order. Do not emit findings until every Pass below is satisfied.
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).
.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.
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”).
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.).
| 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. |
Report findings as:
[FILE:LINE] ISSUE_TITLE
Severity: Critical | Major | Minor | Informational
Description of the issue and why it matters.
| Issue Type | Reference |
|---|---|
| ------------ | ----------- |
| Missing error checks, wrapping, errors.Join | references/error-handling.md |
| Race conditions, channel misuse, goroutine lifecycle | references/concurrency.md |
| Interface pollution, naming, generics | references/interfaces.md |
| Resource leaks, defer misuse, slog, naming | references/common-mistakes.md |
_ = err without justifying comment)fmt.Errorf("...: %w", err))errors.Is/errors.As used instead of string matchingerrors.Join used for aggregating multiple errors (Go 1.20+)-er conventionany preferred over interface{} (Go 1.18+)any or code generationdefer immediately after creationdefer in loops without closure wrappinginit() functions avoided in favor of explicit initializationuser.UserService → user.Service)slog used over log for structured logging (Go 1.21+)return err)panic for recoverable errorsinterface{} instead of any in Go 1.18+ codebasesThese are acceptable Go patterns — reporting them wastes developer time:
_ = err with reason comment — Intentionally ignored errors with explanationany — For truly generic code or interop with untyped APIs//nolint directives with reason — Acceptable when accompanied by explanationtype Option func(T) with With constructors is idiomaticsync.Pool for hot paths — Acceptable for reducing allocation pressure in performance-critical codecontext.Background() in main/tests — Valid root context for top-level callsselect with default — Non-blocking channel operation, intentional patterni, err, ctx, ok are idiomatic GoOnly flag these issues when the specific conditions apply:
| Issue | Flag ONLY IF |
|---|---|
| ------- | -------------- |
| Missing error check | Error return is actionable (can retry, log, or propagate) |
| Goroutine leak | No context cancellation path exists for the goroutine |
| Missing defer | Resource isn't explicitly closed before next acquisition or return |
| Interface pollution | Interface has > 1 method AND only one consumer exists |
| Loop variable capture | go.mod specifies Go < 1.22 |
| Missing slog | go.mod specifies Go >= 1.21 AND code uses log package for structured output |
Satisfy step 4 in Review Workflow: load review-verification-protocol and complete its pre-report checks for each issue.
共 2 个版本