dimetron / design-review
Deep design review of Go codebase — naming, structure, consistency, interfaces, error handling. Scores each dimension and provides actionable fixes.
Design Review
Perform a comprehensive design review of the Go codebase. Evaluate code quality, naming conventions, consistency, and architectural patterns. Produce a scored report with actionable improvements.
When to use
Use this skill when:
- Auditing overall design quality before a major refactor or release
- Onboarding to an unfamiliar Go codebase and need a structured assessment
- Comparing codebase against Go idioms after a period of rapid development
Do NOT use for:
- Reviewing a single PR or uncommitted diff (use
code-reviewinstead) - Writing new code or fixing bugs
- Running linters/tests for CI gating (use
code-reviewinstead)
Relationship to code-review
| Aspect | design-review | code-review |
|---|---|---|
| Scope | Entire codebase or package | Changed files only |
| Action | Read-only audit, scored report | Fix issues, enforce gates |
| Focus | Architecture, patterns, idioms | Correctness, coverage, linting |
| Output | Scorecard + recommendations | Pass/fail gates + fixes applied |
Dimensions
Score each dimension 1-10 and provide specific file:line references for issues found.
1. Naming Conventions
- Exported types/functions follow Go conventions (MixedCaps, no underscores)
- Package names are short, lowercase, singular (not
utils,helpers,common) - Interface names use
-ersuffix where appropriate (Reader,Writer) - Receiver names are short (1-2 chars), consistent within type
- Variable names: short in small scopes, descriptive in large scopes
- Acronyms are all-caps (
ID,URL,HTTP, notId,Url,Http) - Test function names follow
TestFuncName_Scenariopattern - Constants use MixedCaps, not SCREAMING_SNAKE
2. Package Design
- Packages have clear, singular responsibility
- No circular dependencies
- Internal packages used appropriately for implementation details
- Package-level doc comments present
- No God packages (too many responsibilities)
- Reasonable file sizes (flag files > 500 lines)
3. Interface Design
- Interfaces are small (1-3 methods preferred)
- Interfaces defined where consumed, not where implemented
- No unnecessary interface pollution (concrete types are fine)
- Accept interfaces, return structs
io.Reader,io.Writer,fmt.Stringerused where applicable
4. Error Handling
- Errors wrapped with context using
fmt.Errorf("...: %w", err) - Custom error types where callers need to inspect errors
- No swallowed errors (unchecked
errreturns) - Sentinel errors are
var ErrFoo = errors.New(...)not string comparison - Error messages are lowercase, no punctuation, no "failed to" prefix
5. Concurrency Patterns
- Goroutines have clear ownership and lifecycle
- Channels used for communication, mutexes for state
context.Contextpropagated correctly- No goroutine leaks (all goroutines have exit paths)
sync.WaitGrouporerrgroupused for fan-out
6. API Consistency
- Similar operations use similar signatures across packages
- Config structs vs option functions used consistently
- Constructor functions follow
NewFoopattern - Consistent use of pointer vs value receivers within a type
- Method ordering: constructor, public methods, private methods
7. Code Organization
- One primary type per file (type + methods)
- Test files mirror source files (
foo.go/foo_test.go) - Constants and vars at top of file
init()functions avoided (or justified)- Build tags and platform files follow conventions
8. Documentation
- Exported functions have doc comments starting with function name
- Package doc comments present
- Complex algorithms have inline comments explaining why
- No stale/misleading comments
- Examples in tests for complex APIs
Procedure
Set scope first:
- Determine target scope from command args (
/design-review, package path, or--focus) - Apply default include/exclude rules from the Scope section
- Note any skipped areas explicitly in the report
- Determine target scope from command args (
Scan structure: Use
Glob(**/*.go) to map the package layout.
UseShellwithgo list ./...to enumerate packages andwc -lfor line counts.Automated checks: Run in parallel:
go vet ./...— catch common mistakesgolangci-lint run ./...(if available) — extended lint checks- Check for
//nolintdirectives and their justifications - If a tool is unavailable, continue review and mark that check as "skipped"
Naming audit: Use
Grepto sample each package:- Search for naming violations: pattern
Id[^s]instead ofID,Url[^s]instead ofURL - Use
Readto check receiver name consistency per type - Verify exported function doc comments
- Check package names against conventions
- Search for naming violations: pattern
Interface audit: Use
Grepfortype \w+ interfaceto find all interface definitions:- Count methods per interface (flag > 5 methods)
- Check if interfaces are defined at consumer or producer
- Look for interface embedding depth
Error handling audit: Sample error paths:
Grepfor unchecked errors:_, _ =or bare function calls- Check error wrapping:
%wvs%vvs%s - Look for string-based error checking vs sentinel/type errors
Consistency audit: Compare patterns across packages:
- Constructor patterns:
Grepforfunc Newacross all packages and compare signatures - Config patterns (struct vs options)
- Logging patterns (structured vs printf)
- Test patterns (table-driven vs individual)
- Constructor patterns:
Cross-reference: Use tooling for efficiency:
- Dead code:
Grepfor unexported function definitions, thenGrepfor call sites within the package - Duplicates: compare function signatures across packages
- Inconsistent patterns doing the same thing differently
- Dead code:
Validate report before output: Self-check the report against these gates:
- Every scored dimension has at least one finding with a
file:linereference, or an explicit "no issues found" note - Every Top 5 item has a before/after code snippet or an exact command to run
- Key Strengths section has at least 2 entries with file references
- Overall score matches the weighted average (recalculate to confirm)
- No dimension is scored without evidence — if you can't find evidence, mark
N/A
If any gate fails, fix the report before presenting it.
- Every scored dimension has at least one finding with a
Scope
- Default include:
*.gofiles in requested scope - Default exclude:
vendor/,testdata/, generated files (// Code generated), and protobuf outputs (for example*.pb.go) unless explicitly requested Optional focus flags:
--include-teststo include test style and coverage patterns in scoring--include-generatedto include generated code in analysis
- If scope is narrowed (for example
internal/tui), score only that scope and state this clearly
Project-Specific Checks (pi-go)
In addition to general Go review, check:
- ADK compliance: uses
model.LLM,tool.Tool,session.Service— no custom abstractions wrapping ADK - Provider pattern: all providers under
internal/provider/implement the same interface consistently - Tool registration: tools created via
tool.NewFunctionTool, registered intools.CoreTools() - Session format: JSONL append-only, implements
session.Service - Error retry: transient LLM errors use
internal/agent/retry.gopatterns - TUI conventions: Bubble Tea v2 imports from
charm.land/bubbletea/v2, not the oldgithub.com/charmbracelet/bubbleteapath - No external runtime deps: binary must be self-contained
- No
init()functions: prefer explicit initialization
Scoring Model
Use these weights for overall score:
- Naming Conventions: 15%
- Package Design: 15%
- Interface Design: 15%
- Error Handling: 20%
- Concurrency Patterns: 10%
- API Consistency: 10%
- Code Organization: 10%
- Documentation: 5%
Calibration:
| Score | Meaning |
|---|---|
| 9-10 | Stdlib/kubernetes quality — exemplary, publishable as reference |
| 7-8 | Production quality — minor issues, follows idioms well |
| 5-6 | Functional — noticeable gaps, inconsistencies, or missing patterns |
| 3-4 | Below standard — systematic issues, needs refactoring |
| 1-2 | Problematic — fundamental design issues |
Rules:
- Score each dimension
1-10using the calibration table above - Allow
N/Awhen a dimension does not apply to the reviewed scope - Compute overall as weighted average of applicable dimensions only
- Round overall score to 1 decimal place
Output Format
Present results as a scorecard table, then detailed findings per dimension.
## Scorecard
| Dimension | Score | Notes |
|---------------------|-------|---------------------------------|
| Naming Conventions | X/10 | brief note |
| Package Design | X/10 | brief note |
| Interface Design | X/10 | brief note |
| Error Handling | X/10 | brief note |
| Concurrency | X/10 | brief note |
| API Consistency | X/10 | brief note |
| Code Organization | X/10 | brief note |
| Documentation | X/10 | brief note |
|---------------------|-------|---------------------------------|
| **Overall** | X/10 | weighted average (1 decimal) |
## Key Strengths
1. **[Title]** — why it's good + `file:line` reference
2. ...
(minimum 2 strengths required)
## Top 5 Actionable Improvements
1. **[Title]** (impact: high/medium/low, effort: high/medium/low)
- Confidence: high/medium/low
- What: one-sentence description of the problem
- Where: `file:line` references (every affected location)
- Why: what breaks, degrades, or confuses without the fix
- How: concrete fix — include before/after code snippet
// before
func GetUserId() string { ... }
// after
func GetUserID() string { ... }`
... (repeat for each — every item MUST have a before/after snippet or exact command)
Detailed Findings
Naming Conventions (X/10)
Issues (each must have evidence):
| # | Location | Issue | Suggested fix |
|---|---|---|---|
| 1 | file.go:42 | userId should be userID | Rename to userID |
| ... | ... | ... | ... |
What's working well: brief note on what this dimension does right.
... (repeat per dimension — every scored dimension MUST have the issues table)
## Guidelines
- DO NOT make changes — this is a read-only audit
- **Evidence is mandatory**: every finding must include a `file:line` reference. For systemic issues, provide at least one concrete example plus a count ("12 occurrences across 4 packages")
- **Fixes must be concrete**: "improve naming" is not a fix; `rename userId to userID in store.go:42` is
- **Before/after required**: every Top 5 improvement must include a code snippet showing the current state and the proposed fix
- Be fair: note strengths as well as weaknesses in every dimension
- Prioritize by impact: focus on issues that affect maintainability
- Prioritize repository conventions and Effective Go first; use stdlib/well-known projects as secondary tie-breakers
- Score honestly — use the calibration table; 7/10 is good, 10/10 means stdlib-quality
- **No empty dimensions**: if a dimension is scored, it must have the issues table populated. If no issues are found, state "no issues found" explicitly and justify the score
- **Report is incomplete if**: any scored dimension lacks evidence, any Top 5 item lacks a before/after snippet, or the weighted average doesn't match the computed overall score
## Parallel Execution Strategy
For codebases with 5+ packages, split work across subagents:
1. **Main agent**: scan structure (step 2), run automated checks (step 3), produce final report
2. **Subagent per package group**: steps 4-7 (naming, interface, error, consistency audits)
- Group small packages together (< 3 files each)
- Each subagent returns dimension scores + findings for its packages
3. **Main agent**: merge subagent findings, resolve cross-package issues (step 8), compute final scores
## Examples
- `/design-review` — Full design review of entire codebase
- `/design-review internal/tui` — Review only the TUI package
- `/design-review --focus naming` — Review only naming conventions