원클릭으로
go-quality
Go code quality rules and standards for kattle project. Apply when writing or reviewing Go code.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Go code quality rules and standards for kattle project. Apply when writing or reviewing Go code.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Create a git worktree for a new TASK. Use when starting a new feature, fix, or refactor task that requires isolated development.
macOS native memory analysis tools (leaks, heap, vmmap, Instruments). Use for native app memory debugging.
Memory profile snapshot capture and baseline comparison. Use for verification after memory optimization.
Go application memory profiling and analysis. Use when investigating memory leaks or high memory usage.
React/TypeScript code quality rules for kattle frontend. Apply when writing or reviewing frontend code.
Run Go and frontend tests for kattle project. Use after code changes to verify correctness.
| name | go-quality |
| description | Go code quality rules and standards for kattle project. Apply when writing or reviewing Go code. |
| disable-model-invocation | true |
| user-invocable | false |
| allowed-tools | Read, Edit, Write, Grep, Glob |
These rules apply to all Go code in the kattle project. Use this skill when writing, reviewing, or refactoring Go code.
Always check and handle errors explicitly. Never ignore errors with _.
// ❌ BAD
data, _ := os.ReadFile(path)
// ✅ GOOD
data, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("failed to read file %s: %w", path, err)
}
Use %w for error wrapping (Go 1.13+). This allows error chain inspection with errors.Is() and errors.As().
// ❌ BAD
return fmt.Errorf("failed to create client: %v", err)
// ✅ GOOD
return fmt.Errorf("failed to create client: %w", err)
Never panic in library code. Only panic in main() or init() functions.
Only export what's needed by external packages. Check usage before exporting:
internal/ package? Use lowercase (unexported)cmd/ or external consumers? Use uppercase (exported)// ❌ BAD: Unnecessarily exported
func InternalHelper() {}
// ✅ GOOD: Unexported when internal-only
func internalHelper() {}
// ✅ GOOD: Exported for external use
func ListContexts() ([]string, error) {}
Always use defer for cleanup. Lock/unlock, file closing, and resource release must use defer.
// ❌ BAD
mu.Lock()
doWork()
mu.Unlock()
// ✅ GOOD
mu.Lock()
defer mu.Unlock()
doWork()
// ✅ GOOD: Close resources with defer
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
Use sync.RWMutex for read-heavy workloads. Acquire read locks for queries, write locks for mutations.
// ✅ GOOD: Read lock for reads
clientSetsMu.RLock()
cs, exists := clientSets[contextName]
clientSetsMu.RUnlock()
// ✅ GOOD: Write lock for writes
clientSetsMu.Lock()
defer clientSetsMu.Unlock()
clientSets[contextName] = cs
Use double-check pattern for cached values to prevent race conditions:
// ✅ GOOD: Check without lock, then recheck after acquiring lock
mu.RLock()
if val, exists := cache[key]; exists {
mu.RUnlock()
return val, nil
}
mu.RUnlock()
mu.Lock()
defer mu.Unlock()
// Double-check after acquiring write lock
if val, exists := cache[key]; exists {
return val, nil
}
cache[key] = newValue
return newValue, nil
Prevent goroutine leaks: Use context for cancellation, never fire-and-forget goroutines.
// ✅ GOOD: Goroutine respects context cancellation
go func(ctx context.Context) {
for {
select {
case <-ctx.Done():
return
default:
doWork()
}
}
}(ctx)
Pass context.Context as the first parameter in functions that perform I/O or network operations.
// ✅ GOOD: Accept context parameter
func FetchData(ctx context.Context, url string) error {
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
// ...
}
Pass context down the call stack. Never create a new context.Background() in the middle of execution.
// ❌ BAD: Creating new context
func handler() {
ctx := context.Background()
fetchData(ctx)
}
// ✅ GOOD: Using passed context
func handler(ctx context.Context) {
fetchData(ctx)
}
Always check for nil before dereferencing pointers or accessing map values.
// ❌ BAD: Potential nil dereference
result := config.Clusters[name].Server
// ✅ GOOD: Explicit nil check
cluster, exists := config.Clusters[name]
if !exists || cluster == nil {
return fmt.Errorf("cluster %s not found", name)
}
result := cluster.Server
Write table-driven tests for complex logic. Structure tests with clear test cases, inputs, and expected outputs.
func TestIndexesToRanges(t *testing.T) {
tests := []struct {
name string
input []int
expected [][2]int
wantErr bool
}{
{"empty", []int{}, [][2]int{}, false},
{"single", []int{0}, [][2]int{{0, 0}}, false},
{"consecutive", []int{0, 1, 2}, [][2]int{{0, 2}}, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := indexesToRanges(tt.input)
if (result == nil) != tt.wantErr {
t.Errorf("got %v, want error=%v", result, tt.wantErr)
}
// Assert result == tt.expected
})
}
}
Before committing Go code, verify:
%wdefer used for all cleanup operations (locks, files, resources)defer unlockcontext.Context passed down call stack (not created in middle of execution)gofmt, golint, go vet, and go testApply this skill when: