Commit 768330e2d1c1

Vincent Demeester <vincent@sbr.pm>
2025-12-04 16:23:40
feat: Add comprehensive workflows to Golang skill
- Add 8 workflows covering full Go development lifecycle - Build workflow for compilation and cross-platform builds - Test workflow for testing, coverage, and race detection - Benchmark workflow for performance measurement and profiling - Lint workflow for code quality and formatting - Deps workflow for dependency management and security - Debug workflow for debugging with delve and troubleshooting - Profile workflow for advanced performance optimization - Generate workflow for code generation and mocking Signed-off-by: Vincent Demeester <vincent@sbr.pm>
1 parent 89314ef
dots/.config/claude/skills/golang/workflows/Benchmark.md
@@ -0,0 +1,393 @@
+# Benchmark Workflow
+
+Run Go benchmarks to measure and optimize performance.
+
+## When to Use
+
+- "benchmark go code"
+- "measure performance"
+- "run benchmarks"
+- "profile performance"
+- "compare benchmark results"
+
+## Quick Commands
+
+### Basic Benchmarking
+```bash
+# Run all benchmarks
+go test -bench=.
+
+# Run benchmarks in specific package
+go test -bench=. ./internal/handlers
+
+# Run specific benchmark
+go test -bench=BenchmarkMyFunction
+
+# Run benchmarks matching pattern
+go test -bench=BenchmarkUser.*
+```
+
+### With Memory Statistics
+```bash
+# Show memory allocations
+go test -bench=. -benchmem
+
+# Example output:
+# BenchmarkFunction-8   1000000    1234 ns/op    512 B/op    5 allocs/op
+#                       ^^^^^^^^^  ^^^^^^^^^^^   ^^^^^^^^^   ^^^^^^^^^^^^^
+#                       iterations  ns/operation  bytes/op    allocations/op
+```
+
+### Benchmark Time Control
+```bash
+# Run for specific duration (default 1s)
+go test -bench=. -benchtime=10s
+
+# Run specific number of iterations
+go test -bench=. -benchtime=1000x
+
+# Quick benchmark (shorter duration)
+go test -bench=. -benchtime=100ms
+```
+
+## Writing Benchmarks
+
+### Basic Benchmark
+```go
+func BenchmarkMyFunction(b *testing.B) {
+    // Setup (not timed)
+    input := generateInput()
+
+    // Reset timer to exclude setup
+    b.ResetTimer()
+
+    // Run function b.N times
+    for i := 0; i < b.N; i++ {
+        myFunction(input)
+    }
+}
+```
+
+### Benchmark with Table Tests
+```go
+func BenchmarkParse(b *testing.B) {
+    benchmarks := []struct {
+        name  string
+        input string
+    }{
+        {"small", "small input"},
+        {"medium", "medium sized input string"},
+        {"large", strings.Repeat("large ", 1000)},
+    }
+
+    for _, bm := range benchmarks {
+        b.Run(bm.name, func(b *testing.B) {
+            for i := 0; i < b.N; i++ {
+                parse(bm.input)
+            }
+        })
+    }
+}
+```
+
+### Parallel Benchmarks
+```go
+func BenchmarkParallel(b *testing.B) {
+    b.RunParallel(func(pb *testing.PB) {
+        for pb.Next() {
+            // Code to benchmark
+            doWork()
+        }
+    })
+}
+```
+
+### Reporting Custom Metrics
+```go
+func BenchmarkCustomMetrics(b *testing.B) {
+    var totalBytes int64
+
+    for i := 0; i < b.N; i++ {
+        data := processData()
+        totalBytes += int64(len(data))
+    }
+
+    // Report custom metric
+    b.ReportMetric(float64(totalBytes)/float64(b.N), "bytes/op")
+}
+```
+
+## Profiling with Benchmarks
+
+### CPU Profiling
+```bash
+# Generate CPU profile
+go test -bench=. -cpuprofile=cpu.prof
+
+# Analyze CPU profile
+go tool pprof cpu.prof
+
+# Interactive pprof commands:
+# top10       - Show top 10 functions
+# list Func   - Show source for function
+# web         - Generate graph (requires graphviz)
+# pdf         - Generate PDF (requires graphviz)
+
+# Generate CPU profile visualization
+go tool pprof -http=:8080 cpu.prof
+```
+
+### Memory Profiling
+```bash
+# Generate memory profile
+go test -bench=. -memprofile=mem.prof
+
+# Analyze memory profile
+go tool pprof mem.prof
+
+# Show allocations
+go tool pprof -alloc_space mem.prof
+
+# Show in-use memory
+go tool pprof -inuse_space mem.prof
+```
+
+### Block Profiling
+```bash
+# Profile blocking operations
+go test -bench=. -blockprofile=block.prof
+
+# Analyze
+go tool pprof block.prof
+```
+
+### Mutex Profiling
+```bash
+# Profile mutex contention
+go test -bench=. -mutexprofile=mutex.prof
+
+# Analyze
+go tool pprof mutex.prof
+```
+
+## Comparing Benchmarks
+
+### Using benchstat
+```bash
+# Install benchstat
+go install golang.org/x/perf/cmd/benchstat@latest
+
+# Run baseline benchmark
+go test -bench=. -count=10 > old.txt
+
+# Make changes and run new benchmark
+go test -bench=. -count=10 > new.txt
+
+# Compare results
+benchstat old.txt new.txt
+
+# Example output:
+# name        old time/op  new time/op  delta
+# Function-8  123ns ± 2%   98ns ± 1%   -20.33% (p=0.000 n=10+10)
+```
+
+### Manual Comparison
+```bash
+# Run benchmark multiple times for stability
+go test -bench=BenchmarkMyFunc -count=5
+
+# Save to file
+go test -bench=. -benchmem > benchmark.txt
+
+# Compare manually
+# name                time/op    mem/op    allocs/op
+# Before: 1234ns     512B       5
+# After:  987ns      256B       3
+# Delta:  -20%       -50%       -40%
+```
+
+## Advanced Techniques
+
+### Sub-Benchmarks
+```go
+func BenchmarkComplexOperation(b *testing.B) {
+    sizes := []int{10, 100, 1000, 10000}
+
+    for _, size := range sizes {
+        b.Run(fmt.Sprintf("size-%d", size), func(b *testing.B) {
+            data := make([]int, size)
+            b.ResetTimer()
+
+            for i := 0; i < b.N; i++ {
+                processSlice(data)
+            }
+        })
+    }
+}
+```
+
+### Stopping and Starting Timer
+```go
+func BenchmarkWithSetup(b *testing.B) {
+    for i := 0; i < b.N; i++ {
+        b.StopTimer()
+        // Expensive setup not timed
+        data := generateExpensiveData()
+        b.StartTimer()
+
+        // This is timed
+        process(data)
+    }
+}
+```
+
+### Setting Bytes Processed
+```go
+func BenchmarkProcess(b *testing.B) {
+    data := make([]byte, 1024*1024) // 1MB
+
+    b.SetBytes(int64(len(data)))
+    b.ResetTimer()
+
+    for i := 0; i < b.N; i++ {
+        process(data)
+    }
+    // Will report MB/s
+}
+```
+
+## Common Patterns
+
+### Benchmark HTTP Handler
+```go
+func BenchmarkHandler(b *testing.B) {
+    handler := setupHandler()
+    req := httptest.NewRequest("GET", "/users", nil)
+
+    b.ResetTimer()
+
+    for i := 0; i < b.N; i++ {
+        w := httptest.NewRecorder()
+        handler.ServeHTTP(w, req)
+    }
+}
+```
+
+### Benchmark with Pool
+```go
+var bufferPool = sync.Pool{
+    New: func() interface{} {
+        return new(bytes.Buffer)
+    },
+}
+
+func BenchmarkWithPool(b *testing.B) {
+    for i := 0; i < b.N; i++ {
+        buf := bufferPool.Get().(*bytes.Buffer)
+        buf.Reset()
+
+        // Use buffer
+        processWithBuffer(buf)
+
+        bufferPool.Put(buf)
+    }
+}
+```
+
+### Benchmark Allocations
+```go
+func BenchmarkAllocations(b *testing.B) {
+    b.ReportAllocs() // Equivalent to -benchmem
+
+    for i := 0; i < b.N; i++ {
+        // Code that allocates
+        _ = make([]int, 100)
+    }
+}
+```
+
+## Makefile Example
+
+```makefile
+.PHONY: bench
+bench:
+	go test -bench=. -benchmem ./...
+
+.PHONY: bench-cpu
+bench-cpu:
+	go test -bench=. -cpuprofile=cpu.prof
+	go tool pprof -http=:8080 cpu.prof
+
+.PHONY: bench-mem
+bench-mem:
+	go test -bench=. -memprofile=mem.prof
+	go tool pprof -http=:8080 mem.prof
+
+.PHONY: bench-compare
+bench-compare:
+	@echo "Running baseline benchmarks..."
+	go test -bench=. -count=10 -benchmem > bench-old.txt
+	@echo "Make your changes, then run: make bench-compare-new"
+
+.PHONY: bench-compare-new
+bench-compare-new:
+	@echo "Running new benchmarks..."
+	go test -bench=. -count=10 -benchmem > bench-new.txt
+	benchstat bench-old.txt bench-new.txt
+```
+
+## Best Practices
+
+1. **Run multiple iterations**: Use `-count=5` or higher for stable results
+2. **Use benchstat**: For statistical comparison of results
+3. **Reset timer after setup**: Exclude setup time with `b.ResetTimer()`
+4. **Report allocations**: Always use `-benchmem` to see memory impact
+5. **Benchmark real scenarios**: Use realistic data and workloads
+6. **Run on consistent hardware**: Same machine, same load for comparisons
+7. **Profile before optimizing**: Find bottlenecks with pprof
+8. **Benchmark alternatives**: Compare different implementations
+9. **Document baseline**: Save benchmark results in version control
+10. **Use sub-benchmarks**: Test different input sizes and scenarios
+
+## Interpreting Results
+
+### Time/Operation
+- Lower is better
+- Represents average time per operation
+- Compare before/after optimization
+
+### Allocations/Operation
+- Fewer is better
+- Each allocation has overhead
+- Reducing allocations improves performance
+
+### Bytes/Operation
+- Fewer is better
+- Memory allocations cause GC pressure
+- Optimize hot paths to reduce allocations
+
+### MB/s (when using SetBytes)
+- Higher is better
+- Throughput measurement
+- Useful for I/O operations
+
+## Common Flags
+
+| Flag | Purpose |
+|------|---------|
+| `-bench=.` | Run all benchmarks |
+| `-benchmem` | Show memory stats |
+| `-benchtime=Xs` | Run for X seconds |
+| `-benchtime=Nx` | Run N iterations |
+| `-count=N` | Run benchmarks N times |
+| `-cpuprofile=file` | Write CPU profile |
+| `-memprofile=file` | Write memory profile |
+| `-blockprofile=file` | Write block profile |
+| `-mutexprofile=file` | Write mutex profile |
+
+## Resources
+
+- [Benchmarking in Go](https://pkg.go.dev/testing#hdr-Benchmarks)
+- [benchstat Tool](https://pkg.go.dev/golang.org/x/perf/cmd/benchstat)
+- [pprof Tool](https://github.com/google/pprof)
+- [Go Performance](https://go.dev/doc/diagnostics#profiling)
dots/.config/claude/skills/golang/workflows/Build.md
@@ -0,0 +1,251 @@
+# Build Workflow
+
+Build Go applications with proper flags, cross-compilation, and optimization.
+
+## When to Use
+
+- "build go project"
+- "compile go binary"
+- "cross compile"
+- "build for linux/windows/mac"
+
+## Quick Commands
+
+### Basic Build
+```bash
+# Build current package
+go build
+
+# Build with output name
+go build -o myapp
+
+# Build specific package
+go build ./cmd/myapp
+
+# Build and install to $GOPATH/bin
+go install ./cmd/myapp
+```
+
+### Cross-Compilation
+```bash
+# Build for Linux (from any OS)
+GOOS=linux GOARCH=amd64 go build -o myapp-linux
+
+# Build for Windows
+GOOS=windows GOARCH=amd64 go build -o myapp.exe
+
+# Build for macOS (Intel)
+GOOS=darwin GOARCH=amd64 go build -o myapp-darwin-amd64
+
+# Build for macOS (Apple Silicon)
+GOOS=darwin GOARCH=arm64 go build -o myapp-darwin-arm64
+
+# Build for ARM (Raspberry Pi)
+GOOS=linux GOARCH=arm GOARM=7 go build -o myapp-arm
+```
+
+### Common GOOS/GOARCH Combinations
+| Target | GOOS | GOARCH |
+|--------|------|--------|
+| Linux 64-bit | linux | amd64 |
+| Linux 32-bit | linux | 386 |
+| Linux ARM | linux | arm64 |
+| Windows 64-bit | windows | amd64 |
+| macOS Intel | darwin | amd64 |
+| macOS Apple Silicon | darwin | arm64 |
+| FreeBSD | freebsd | amd64 |
+
+## Build Flags
+
+### Optimization Flags
+```bash
+# Reduce binary size (strip debug info)
+go build -ldflags="-s -w" -o myapp
+
+# Add version information
+go build -ldflags="-X main.version=1.0.0 -X main.commit=$(git rev-parse HEAD)" -o myapp
+```
+
+**Common ldflags:**
+- `-s` - Omit symbol table and debug info
+- `-w` - Omit DWARF symbol table
+- `-X` - Set string variable value
+
+### Build Tags
+```bash
+# Build with specific tags
+go build -tags=prod
+
+# Multiple tags
+go build -tags="prod,mysql"
+
+# Build without CGO
+CGO_ENABLED=0 go build
+```
+
+### Race Detection
+```bash
+# Build with race detector (testing only, slower)
+go build -race
+```
+
+### Trimpath for Reproducible Builds
+```bash
+# Remove absolute paths from binary
+go build -trimpath
+```
+
+## Build Modes
+
+### Static Binary (No Dependencies)
+```bash
+# Build completely static binary
+CGO_ENABLED=0 GOOS=linux go build -a -ldflags="-s -w" -o myapp
+```
+
+**Flags explained:**
+- `CGO_ENABLED=0` - Disable CGO (C dependencies)
+- `-a` - Force rebuild of all packages
+- `-ldflags="-s -w"` - Strip debug info
+
+### Shared Library
+```bash
+# Build as shared library (.so)
+go build -buildmode=c-shared -o mylib.so
+```
+
+### Plugin
+```bash
+# Build as plugin
+go build -buildmode=plugin -o myplugin.so
+```
+
+## Common Patterns
+
+### Multi-Binary Project
+```bash
+# Build all binaries in cmd/
+for dir in cmd/*/; do
+    binary=$(basename "$dir")
+    go build -o "bin/$binary" "./$dir"
+done
+```
+
+### Build Script with Version
+```bash
+#!/bin/bash
+VERSION=$(git describe --tags --always --dirty)
+COMMIT=$(git rev-parse --short HEAD)
+DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
+
+go build -ldflags="-X main.version=${VERSION} \
+                    -X main.commit=${COMMIT} \
+                    -X main.date=${DATE}" \
+         -o myapp
+```
+
+### Embed Version in Code
+```go
+// main.go
+package main
+
+var (
+    version = "dev"
+    commit  = "unknown"
+    date    = "unknown"
+)
+
+func main() {
+    fmt.Printf("Version: %s\nCommit: %s\nBuilt: %s\n", version, commit, date)
+}
+```
+
+## Makefile Example
+
+```makefile
+BINARY_NAME=myapp
+VERSION=$(shell git describe --tags --always --dirty)
+COMMIT=$(shell git rev-parse --short HEAD)
+DATE=$(shell date -u +%Y-%m-%dT%H:%M:%SZ)
+
+LDFLAGS=-ldflags="-s -w -X main.version=${VERSION} -X main.commit=${COMMIT} -X main.date=${DATE}"
+
+.PHONY: build
+build:
+	go build ${LDFLAGS} -o ${BINARY_NAME}
+
+.PHONY: build-all
+build-all:
+	GOOS=linux GOARCH=amd64 go build ${LDFLAGS} -o ${BINARY_NAME}-linux-amd64
+	GOOS=darwin GOARCH=amd64 go build ${LDFLAGS} -o ${BINARY_NAME}-darwin-amd64
+	GOOS=darwin GOARCH=arm64 go build ${LDFLAGS} -o ${BINARY_NAME}-darwin-arm64
+	GOOS=windows GOARCH=amd64 go build ${LDFLAGS} -o ${BINARY_NAME}-windows-amd64.exe
+
+.PHONY: clean
+clean:
+	rm -f ${BINARY_NAME}*
+```
+
+## Troubleshooting
+
+### CGO Issues
+```bash
+# If you get CGO errors, disable it
+CGO_ENABLED=0 go build
+
+# Or install required C libraries
+# For SQLite on Ubuntu/Debian:
+sudo apt-get install gcc libsqlite3-dev
+```
+
+### Module Issues
+```bash
+# Ensure modules are downloaded
+go mod download
+
+# Verify modules
+go mod verify
+
+# Clean module cache
+go clean -modcache
+```
+
+### Build Cache
+```bash
+# Clean build cache
+go clean -cache
+
+# Build without cache
+go build -a
+```
+
+## Best Practices
+
+1. **Always use `go.mod`**: Don't use `GOPATH` mode
+2. **Pin versions**: Use `go.mod` to lock dependency versions
+3. **Use `-trimpath`**: For reproducible builds
+4. **Static binaries for containers**: Use `CGO_ENABLED=0` for Docker
+5. **Version your binaries**: Embed version info with `-ldflags`
+6. **Test cross-compilation**: Ensure it works for all target platforms
+7. **Optimize for production**: Use `-ldflags="-s -w"` to reduce size
+
+## Integration with CI/CD
+
+### GitHub Actions Example
+```yaml
+- name: Build
+  run: |
+    go build -ldflags="-s -w" -o myapp
+
+- name: Build for multiple platforms
+  run: |
+    GOOS=linux GOARCH=amd64 go build -o myapp-linux
+    GOOS=darwin GOARCH=amd64 go build -o myapp-darwin
+    GOOS=windows GOARCH=amd64 go build -o myapp.exe
+```
+
+## Resources
+
+- [Go Build Command](https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies)
+- [Build Modes](https://pkg.go.dev/cmd/go#hdr-Build_modes)
+- [Cross Compilation](https://go.dev/doc/install/source#environment)
dots/.config/claude/skills/golang/workflows/Debug.md
@@ -0,0 +1,343 @@
+# Debug Workflow
+
+Debug Go applications using delve debugger and other debugging techniques.
+
+## When to Use
+
+- "debug go code"
+- "use delve"
+- "troubleshoot go program"
+- "debug race condition"
+- "inspect goroutines"
+
+## Quick Commands
+
+### Using delve
+```bash
+# Install delve
+go install github.com/go-delve/delve/cmd/dlv@latest
+
+# Debug current package
+dlv debug
+
+# Debug with arguments
+dlv debug -- arg1 arg2
+
+# Debug tests
+dlv test
+
+# Attach to running process
+dlv attach <pid>
+
+# Debug specific test
+dlv test -- -test.run TestMyFunction
+```
+
+## Delve Commands
+
+### Breakpoints
+```
+# Set breakpoint at function
+break main.main
+b main.main
+
+# Set breakpoint at file:line
+break main.go:42
+b main.go:42
+
+# Set conditional breakpoint
+break main.go:42 if x > 5
+
+# List breakpoints
+breakpoints
+bp
+
+# Clear breakpoint
+clear 1
+
+# Clear all breakpoints
+clearall
+```
+
+### Execution Control
+```
+# Continue execution
+continue
+c
+
+# Step over (next line)
+next
+n
+
+# Step into (follow function call)
+step
+s
+
+# Step out (return from function)
+stepout
+
+# Restart
+restart
+r
+```
+
+### Inspection
+```
+# Print variable
+print varName
+p varName
+
+# Print with format
+p fmt.Sprintf("%#v", varName)
+
+# List local variables
+locals
+
+# List function arguments
+args
+
+# Show current goroutines
+goroutines
+
+# Show stack trace
+stack
+bt
+
+# List source code
+list
+l
+
+# List around specific line
+list main.go:42
+```
+
+### Goroutine Debugging
+```
+# List all goroutines
+goroutines
+
+# Switch to goroutine
+goroutine <id>
+
+# Show goroutine stack
+goroutine <id> bt
+```
+
+## Print Debugging
+
+### Strategic Logging
+```go
+import "log"
+
+func problematicFunction() {
+    log.Printf("DEBUG: Entering function, value=%v", someValue)
+
+    // Complex logic
+    result := compute()
+    log.Printf("DEBUG: After compute, result=%v", result)
+
+    return result
+}
+```
+
+### Using fmt.Printf
+```go
+// Quick debug prints
+fmt.Printf("DEBUG: x=%#v\n", x)          // Detailed format
+fmt.Printf("DEBUG: type=%T value=%v\n", x, x)  // Type and value
+```
+
+### Conditional Debug Output
+```go
+const debug = false
+
+func debugPrintf(format string, args ...interface{}) {
+    if debug {
+        log.Printf("DEBUG: "+format, args...)
+    }
+}
+
+func myFunction() {
+    debugPrintf("Processing %d items", len(items))
+}
+```
+
+## Race Condition Debugging
+
+### Detect Races
+```bash
+# Build with race detector
+go build -race
+
+# Run with race detector
+go run -race main.go
+
+# Test with race detector
+go test -race ./...
+```
+
+### Race Detector Output
+```
+==================
+WARNING: DATA RACE
+Read at 0x00c000100000 by goroutine 7:
+  main.read()
+      /path/to/file.go:10 +0x44
+
+Previous write at 0x00c000100000 by goroutine 6:
+  main.write()
+      /path/to/file.go:15 +0x56
+==================
+```
+
+### Fix Races with Mutex
+```go
+// Before (race condition)
+var counter int
+
+func increment() {
+    counter++  // Race!
+}
+
+// After (safe)
+var (
+    counter int
+    mu      sync.Mutex
+)
+
+func increment() {
+    mu.Lock()
+    defer mu.Unlock()
+    counter++
+}
+```
+
+## Debugging Patterns
+
+### Panic Recovery
+```go
+defer func() {
+    if r := recover(); r != nil {
+        fmt.Printf("Recovered from panic: %v\n", r)
+        debug.PrintStack()
+    }
+}()
+```
+
+### Detailed Stack Traces
+```go
+import "runtime/debug"
+
+func logPanic() {
+    if r := recover(); r != nil {
+        log.Printf("Panic: %v\n%s", r, debug.Stack())
+    }
+}
+```
+
+### Debugging HTTP Handlers
+```go
+func debugMiddleware(next http.Handler) http.Handler {
+    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+        log.Printf("Request: %s %s", r.Method, r.URL.Path)
+
+        // Capture response
+        rec := httptest.NewRecorder()
+        next.ServeHTTP(rec, r)
+
+        log.Printf("Response: %d", rec.Code)
+
+        // Copy to actual response
+        for k, v := range rec.Header() {
+            w.Header()[k] = v
+        }
+        w.WriteHeader(rec.Code)
+        w.Write(rec.Body.Bytes())
+    })
+}
+```
+
+## Environment Variables for Debugging
+
+```bash
+# Enable detailed GC logging
+GODEBUG=gctrace=1 go run main.go
+
+# Show goroutine scheduling
+GODEBUG=schedtrace=1000 go run main.go
+
+# Show memory allocator
+GODEBUG=allocfreetrace=1 go run main.go
+
+# Multiple debug settings
+GODEBUG=gctrace=1,schedtrace=1000 go run main.go
+```
+
+## VSCode Integration
+
+### launch.json Example
+```json
+{
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "Debug Package",
+            "type": "go",
+            "request": "launch",
+            "mode": "debug",
+            "program": "${workspaceFolder}",
+            "args": ["arg1", "arg2"]
+        },
+        {
+            "name": "Debug Test",
+            "type": "go",
+            "request": "launch",
+            "mode": "test",
+            "program": "${workspaceFolder}",
+            "args": ["-test.run", "TestMyFunction"]
+        }
+    ]
+}
+```
+
+## Common Issues
+
+### Deadlock Detection
+```go
+// Go runtime detects deadlocks
+fatal error: all goroutines are asleep - deadlock!
+
+goroutine 1 [chan receive]:
+main.main()
+    /path/to/file.go:10 +0x50
+```
+
+### Memory Leaks
+```bash
+# Profile memory
+go test -memprofile=mem.prof
+
+# Analyze
+go tool pprof mem.prof
+
+# Look for:
+# - Growing heap
+# - Goroutine leaks
+# - Unclosed resources
+```
+
+## Best Practices
+
+1. **Use delve for complex issues**: More powerful than print debugging
+2. **Enable race detector in tests**: Catch concurrency bugs early
+3. **Log strategically**: Don't over-log, focus on problem areas
+4. **Use proper log levels**: Debug, Info, Warn, Error
+5. **Reproduce in tests**: Write failing test before debugging
+6. **Check goroutine leaks**: Use pprof to inspect goroutines
+7. **Validate assumptions**: Use assertions and invariants
+
+## Resources
+
+- [Delve Debugger](https://github.com/go-delve/delve)
+- [Debugging with Go](https://go.dev/doc/diagnostics)
+- [Race Detector](https://go.dev/doc/articles/race_detector)
dots/.config/claude/skills/golang/workflows/Deps.md
@@ -0,0 +1,294 @@
+# Deps Workflow
+
+Manage Go module dependencies, updates, and security.
+
+## When to Use
+
+- "add go dependency"
+- "update dependencies"
+- "go mod tidy"
+- "check for vulnerabilities"
+- "vendor dependencies"
+
+## Quick Commands
+
+### Adding Dependencies
+```bash
+# Add latest version
+go get github.com/pkg/errors
+
+# Add specific version
+go get github.com/pkg/errors@v0.9.1
+
+# Add from specific commit
+go get github.com/pkg/errors@commit-hash
+
+# Add package and update go.mod
+go get -u github.com/pkg/errors
+```
+
+### Updating Dependencies
+```bash
+# Update all dependencies
+go get -u ./...
+
+# Update specific dependency
+go get -u github.com/pkg/errors
+
+# Update to latest patch
+go get -u=patch ./...
+
+# Update direct dependencies only
+go get -u -t ./...
+```
+
+### Module Maintenance
+```bash
+# Tidy modules (remove unused, add missing)
+go mod tidy
+
+# Verify dependencies
+go mod verify
+
+# Download dependencies
+go mod download
+
+# View dependency graph
+go mod graph
+
+# Explain why module is needed
+go mod why github.com/pkg/errors
+```
+
+### Vendoring
+```bash
+# Create vendor directory
+go mod vendor
+
+# Verify vendor matches go.mod
+go mod vendor -v
+
+# Build using vendor
+go build -mod=vendor
+
+# List vendored packages
+go list -m -json all
+```
+
+## Viewing Dependencies
+
+### List Modules
+```bash
+# List all dependencies
+go list -m all
+
+# List direct dependencies only
+go list -m -f '{{if not .Indirect}}{{.Path}}{{end}}' all
+
+# List outdated dependencies
+go list -u -m all
+
+# Show module details
+go list -m -json github.com/pkg/errors
+```
+
+### Dependency Tree
+```bash
+# Install go-mod-graph-chart
+go install github.com/nikolaydubina/go-mod-graph-chart@latest
+
+# Generate dependency graph
+go mod graph | go-mod-graph-chart > deps.svg
+```
+
+## Security
+
+### Vulnerability Scanning
+```bash
+# Install govulncheck
+go install golang.org/x/vuln/cmd/govulncheck@latest
+
+# Check for vulnerabilities
+govulncheck ./...
+
+# Check specific package
+govulncheck -package github.com/pkg/errors ./...
+```
+
+### Update go.sum
+```bash
+# go.sum should be committed
+git add go.sum
+
+# If go.sum is out of sync
+go mod tidy
+```
+
+## Dependency Replacement
+
+### Local Replacement
+```bash
+# Replace with local version (for development)
+go mod edit -replace github.com/pkg/errors=../local/errors
+
+# Remove replacement
+go mod edit -dropreplace github.com/pkg/errors
+```
+
+### Fork Replacement
+```bash
+# Replace with fork
+go mod edit -replace github.com/original/pkg=github.com/yourfork/pkg@version
+```
+
+### go.mod Example
+```go
+module github.com/yourorg/yourproject
+
+go 1.21
+
+require (
+    github.com/pkg/errors v0.9.1
+    github.com/spf13/cobra v1.7.0
+)
+
+require (
+    // Indirect dependencies
+    github.com/spf13/pflag v1.0.5 // indirect
+)
+
+replace (
+    // Local development
+    github.com/internal/lib => ../lib
+)
+```
+
+## Version Pinning
+
+### Pin to Specific Version
+```bash
+# Use exact version
+go get github.com/pkg/errors@v0.9.1
+
+# Pin in go.mod
+go mod edit -require=github.com/pkg/errors@v0.9.1
+```
+
+### Upgrade Constraints
+```bash
+# Latest version compatible with go.mod
+go get -u github.com/pkg/errors
+
+# Latest minor version
+go get -u=patch github.com/pkg/errors
+```
+
+## Cleaning Up
+
+### Remove Unused Dependencies
+```bash
+# Tidy removes unused
+go mod tidy
+
+# Check what will be removed
+go mod tidy -v
+```
+
+### Clear Module Cache
+```bash
+# Clean entire cache
+go clean -modcache
+
+# Clean specific module
+go clean -modcache -n
+```
+
+## Makefile Example
+
+```makefile
+.PHONY: deps
+deps:
+	go mod download
+	go mod verify
+
+.PHONY: deps-update
+deps-update:
+	go get -u ./...
+	go mod tidy
+
+.PHONY: deps-tidy
+deps-tidy:
+	go mod tidy
+	go mod verify
+
+.PHONY: deps-vendor
+deps-vendor:
+	go mod vendor
+
+.PHONY: deps-vuln
+deps-vuln:
+	govulncheck ./...
+
+.PHONY: deps-graph
+deps-graph:
+	go mod graph | go-mod-graph-chart > deps.svg
+```
+
+## Best Practices
+
+1. **Always run `go mod tidy`**: After dependency changes
+2. **Commit go.sum**: Essential for reproducibility
+3. **Verify before deploying**: Run `go mod verify`
+4. **Check vulnerabilities**: Use govulncheck regularly
+5. **Use semantic versions**: Prefer tagged versions over commits
+6. **Review updates**: Check changelogs before updating
+7. **Vendor for critical projects**: Consider vendoring for stability
+8. **Pin major versions**: Avoid unexpected breaking changes
+
+## CI/CD Integration
+
+### GitHub Actions
+```yaml
+- name: Download dependencies
+  run: go mod download
+
+- name: Verify dependencies
+  run: go mod verify
+
+- name: Check for vulnerabilities
+  run: |
+    go install golang.org/x/vuln/cmd/govulncheck@latest
+    govulncheck ./...
+
+- name: Check tidy
+  run: |
+    go mod tidy
+    git diff --exit-code go.mod go.sum
+```
+
+## Troubleshooting
+
+### Dependency Conflicts
+```bash
+# Show why dependency is needed
+go mod why github.com/pkg/errors
+
+# Check dependency graph
+go mod graph | grep github.com/pkg/errors
+```
+
+### Checksum Mismatch
+```bash
+# Update checksums
+go mod tidy
+
+# Clear cache and retry
+go clean -modcache
+go mod download
+```
+
+## Resources
+
+- [Go Modules Reference](https://go.dev/ref/mod)
+- [govulncheck](https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck)
+- [Go Module Wiki](https://github.com/golang/go/wiki/Modules)
dots/.config/claude/skills/golang/workflows/Generate.md
@@ -0,0 +1,286 @@
+# Generate Workflow
+
+Code generation with go generate, mocking, and other generation tools.
+
+## When to Use
+
+- "generate go code"
+- "run go generate"
+- "create mocks"
+- "generate from protobuf"
+- "use stringer"
+
+## Quick Commands
+
+### go generate
+```bash
+# Run generators in current package
+go generate
+
+# Run in all packages
+go generate ./...
+
+# Verbose output
+go generate -v ./...
+
+# Dry run
+go generate -n ./...
+
+# Run specific generator
+go generate -run mockgen ./...
+```
+
+## Common Generators
+
+### Stringer (Enum String Methods)
+```go
+//go:generate stringer -type=Status
+type Status int
+
+const (
+    Pending Status = iota
+    Active
+    Completed
+)
+
+// Generates: status_string.go with String() method
+```
+
+```bash
+# Install
+go install golang.org/x/tools/cmd/stringer@latest
+
+# Generate
+go generate ./...
+
+# Usage
+s := Active
+fmt.Println(s.String()) // "Active"
+```
+
+### mockgen (Mock Interfaces)
+```go
+//go:generate mockgen -destination=mocks/mock_database.go -package=mocks . Database
+
+type Database interface {
+    Get(id string) (*User, error)
+    Save(user *User) error
+}
+```
+
+```bash
+# Install
+go install github.com/golang/mock/mockgen@latest
+
+# Generate mocks
+go generate ./...
+
+# Use in tests
+mockDB := mocks.NewMockDatabase(ctrl)
+mockDB.EXPECT().Get("123").Return(user, nil)
+```
+
+### protoc (Protocol Buffers)
+```proto
+// user.proto
+syntax = "proto3";
+package api;
+
+message User {
+    string id = 1;
+    string name = 2;
+}
+```
+
+```go
+//go:generate protoc --go_out=. --go_opt=paths=source_relative user.proto
+```
+
+```bash
+# Install
+go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
+
+# Generate
+go generate ./...
+```
+
+### Embed (Static Files)
+```go
+//go:embed templates/*.html
+var templates embed.FS
+
+//go:embed static/*
+var static embed.FS
+
+func main() {
+    data, _ := templates.ReadFile("templates/index.html")
+}
+```
+
+## Advanced Generators
+
+### sqlc (SQL to Go)
+```yaml
+# sqlc.yaml
+version: "2"
+sql:
+  - schema: "schema.sql"
+    queries: "queries.sql"
+    engine: "postgresql"
+    gen:
+      go:
+        package: "db"
+        out: "db"
+```
+
+```go
+//go:generate sqlc generate
+```
+
+### Wire (Dependency Injection)
+```go
+//go:build wireinject
+
+//go:generate wire
+
+func InitializeApp() (*App, error) {
+    wire.Build(
+        NewDatabase,
+        NewUserService,
+        NewApp,
+    )
+    return nil, nil
+}
+```
+
+### oapi-codegen (OpenAPI)
+```go
+//go:generate oapi-codegen -package api -generate types,server openapi.yaml > api.gen.go
+```
+
+## Generator Directives
+
+### Syntax
+```go
+//go:generate command arg1 arg2
+```
+
+### Examples
+```go
+// Generate stringer
+//go:generate stringer -type=Color
+
+// Multiple commands
+//go:generate mockgen -destination=mocks/mock.go . Interface
+//go:generate gofmt -w mocks/mock.go
+
+// With environment variables
+//go:generate sh -c "VERSION=$(git describe) envsubst < version.tmpl > version.go"
+
+// Conditional generation
+//go:generate echo "Generating..."
+```
+
+## Makefile Integration
+
+```makefile
+.PHONY: generate
+generate:
+	go generate ./...
+	gofmt -w .
+
+.PHONY: generate-mocks
+generate-mocks:
+	go generate -run mockgen ./...
+
+.PHONY: generate-proto
+generate-proto:
+	protoc --go_out=. --go_opt=paths=source_relative api/*.proto
+
+.PHONY: generate-check
+generate-check:
+	go generate ./...
+	git diff --exit-code
+
+.PHONY: clean-generated
+clean-generated:
+	find . -name "*.gen.go" -delete
+	find . -name "*_string.go" -delete
+```
+
+## Best Practices
+
+1. **Commit generated code**: Makes builds reproducible
+2. **Run before building**: Ensure generated code is current
+3. **Use specific versions**: Pin generator tool versions
+4. **Document generators**: Comment what each directive does
+5. **Format generated code**: Run gofmt after generation
+6. **Check in CI**: Verify generated code is up-to-date
+7. **Separate generated files**: Use .gen.go suffix
+
+## CI/CD Integration
+
+### GitHub Actions
+```yaml
+- name: Install generators
+  run: |
+    go install golang.org/x/tools/cmd/stringer@latest
+    go install github.com/golang/mock/mockgen@latest
+
+- name: Run generators
+  run: go generate ./...
+
+- name: Check for changes
+  run: |
+    if [[ `git status --porcelain` ]]; then
+      echo "Generated code is out of date"
+      git diff
+      exit 1
+    fi
+```
+
+## Common Patterns
+
+### Version Embedding
+```go
+//go:generate sh -c "echo 'package main\n\nconst Version = \"'$(git describe --tags)'\"' > version.go"
+
+func main() {
+    fmt.Println("Version:", Version)
+}
+```
+
+### Interface Verification
+```go
+//go:generate go run check_interfaces.go
+
+// Verify implementation
+var _ http.Handler = (*MyHandler)(nil)
+```
+
+### Template Expansion
+```go
+//go:generate go run gen_template.go
+
+// gen_template.go
+package main
+
+import "text/template"
+
+const tmpl = `// Code generated. DO NOT EDIT.
+package {{.Package}}
+
+type {{.Name}} struct {}`
+
+func main() {
+    // Generate code from template
+}
+```
+
+## Resources
+
+- [go generate](https://go.dev/blog/generate)
+- [stringer](https://pkg.go.dev/golang.org/x/tools/cmd/stringer)
+- [mockgen](https://github.com/golang/mock)
+- [embed](https://pkg.go.dev/embed)
+- [protobuf](https://protobuf.dev/)
dots/.config/claude/skills/golang/workflows/Lint.md
@@ -0,0 +1,227 @@
+# Lint Workflow
+
+Check code quality, formatting, and common mistakes with Go linting tools.
+
+## When to Use
+
+- "lint go code"
+- "format go files"
+- "check code quality"
+- "run gofmt"
+- "run golangci-lint"
+
+## Quick Commands
+
+### Formatting
+```bash
+# Format all Go files
+gofmt -w .
+
+# Check formatting (don't write)
+gofmt -d .
+
+# List files needing formatting
+gofmt -l .
+
+# Format and organize imports
+goimports -w .
+```
+
+### Go Vet
+```bash
+# Vet current package
+go vet
+
+# Vet all packages
+go vet ./...
+
+# Vet specific package
+go vet ./internal/handlers
+```
+
+### golangci-lint
+```bash
+# Install
+go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
+
+# Run all linters
+golangci-lint run
+
+# Auto-fix issues
+golangci-lint run --fix
+
+# Run specific linters
+golangci-lint run --enable=gosec,exhaustive
+
+# Fast mode (skip cached)
+golangci-lint run --fast
+```
+
+## Common Linters
+
+### Static Analysis
+- **staticcheck**: Comprehensive static analysis
+- **gosec**: Security issues
+- **errcheck**: Unchecked errors
+- **govet**: Official Go vet
+- **ineffassign**: Ineffectual assignments
+
+### Code Quality
+- **gocyclo**: Cyclomatic complexity
+- **gocognit**: Cognitive complexity
+- **dupl**: Code duplication
+- **goconst**: Repeated string constants
+- **unconvert**: Unnecessary type conversions
+
+### Style
+- **gofmt**: Code formatting
+- **goimports**: Import organization
+- **revive**: Flexible linter (golint replacement)
+- **stylecheck**: Style recommendations
+
+## Configuration
+
+### .golangci.yml Example
+```yaml
+run:
+  timeout: 5m
+  tests: true
+
+linters:
+  enable:
+    - gofmt
+    - goimports
+    - govet
+    - staticcheck
+    - errcheck
+    - gosec
+    - ineffassign
+    - unconvert
+    - goconst
+    - revive
+
+linters-settings:
+  goimports:
+    local-prefixes: github.com/yourorg/yourrepo
+
+  govet:
+    check-shadowing: true
+
+  revive:
+    rules:
+      - name: exported
+        disabled: true
+
+issues:
+  exclude-use-default: false
+  max-issues-per-linter: 0
+  max-same-issues: 0
+```
+
+## Common Fixes
+
+### Unused Variables
+```go
+// Bad
+func example() {
+    x := 5
+    // x never used
+}
+
+// Good
+func example() {
+    _ = 5  // Explicitly unused
+}
+```
+
+### Error Checking
+```go
+// Bad
+file, _ := os.Open("file.txt")
+
+// Good
+file, err := os.Open("file.txt")
+if err != nil {
+    return err
+}
+defer file.Close()
+```
+
+### Import Organization
+```go
+// Bad
+import (
+    "github.com/external/pkg"
+    "fmt"
+    "myproject/internal"
+)
+
+// Good (goimports fixes this)
+import (
+    "fmt"
+
+    "github.com/external/pkg"
+
+    "myproject/internal"
+)
+```
+
+## Makefile Example
+
+```makefile
+.PHONY: fmt
+fmt:
+	gofmt -w .
+	goimports -w .
+
+.PHONY: lint
+lint:
+	golangci-lint run
+
+.PHONY: lint-fix
+lint-fix:
+	golangci-lint run --fix
+
+.PHONY: vet
+vet:
+	go vet ./...
+
+.PHONY: check
+check: fmt vet lint
+	@echo "All checks passed!"
+```
+
+## CI/CD Integration
+
+### GitHub Actions
+```yaml
+- name: Format check
+  run: |
+    if [ "$(gofmt -l . | wc -l)" -gt 0 ]; then
+      echo "Files need formatting:"
+      gofmt -l .
+      exit 1
+    fi
+
+- name: golangci-lint
+  uses: golangci/golangci-lint-action@v3
+  with:
+    version: latest
+```
+
+## Best Practices
+
+1. **Run before committing**: Add to pre-commit hooks
+2. **Use goimports over gofmt**: Manages imports too
+3. **Enable gosec**: Catch security issues
+4. **Fix formatting first**: Then tackle other issues
+5. **Configure for your team**: Use .golangci.yml
+6. **Run in CI**: Ensure consistency
+7. **Auto-fix when safe**: Use `--fix` flag
+
+## Resources
+
+- [gofmt](https://pkg.go.dev/cmd/gofmt)
+- [go vet](https://pkg.go.dev/cmd/vet)
+- [golangci-lint](https://golangci-lint.run/)
+- [staticcheck](https://staticcheck.io/)
dots/.config/claude/skills/golang/workflows/Profile.md
@@ -0,0 +1,340 @@
+# Profile Workflow
+
+Advanced profiling and performance analysis for Go applications.
+
+## When to Use
+
+- "profile go application"
+- "find performance bottlenecks"
+- "analyze memory usage"
+- "trace execution"
+- "optimize performance"
+
+## Types of Profiling
+
+### CPU Profiling
+```bash
+# During tests
+go test -cpuprofile=cpu.prof -bench=.
+
+# In application
+import _ "net/http/pprof"
+go func() {
+    log.Println(http.ListenAndServe("localhost:6060", nil))
+}()
+
+# Capture profile
+curl http://localhost:6060/debug/pprof/profile?seconds=30 > cpu.prof
+
+# Analyze
+go tool pprof cpu.prof
+```
+
+### Memory Profiling
+```bash
+# Heap profile
+go test -memprofile=mem.prof -bench=.
+
+# From running app
+curl http://localhost:6060/debug/pprof/heap > heap.prof
+
+# Analyze
+go tool pprof mem.prof
+
+# Allocation profile
+go tool pprof -alloc_space mem.prof
+```
+
+### Block Profiling
+```bash
+# Profile blocking operations
+import "runtime"
+runtime.SetBlockProfileRate(1)
+
+# Capture
+curl http://localhost:6060/debug/pprof/block > block.prof
+
+# Analyze
+go tool pprof block.prof
+```
+
+### Mutex Profiling
+```bash
+# Profile mutex contention
+import "runtime"
+runtime.SetMutexProfileFraction(1)
+
+# Capture
+curl http://localhost:6060/debug/pprof/mutex > mutex.prof
+
+# Analyze
+go tool pprof mutex.prof
+```
+
+## pprof Commands
+
+### Interactive Mode
+```
+# Top functions by CPU
+top
+top10
+
+# Show specific function
+list functionName
+
+# View as graph (requires graphviz)
+web
+
+# View as PDF
+pdf
+
+# Show call graph
+traces
+
+# Show cumulative time
+top -cum
+
+# Filter by function
+top grep main
+```
+
+### Web UI
+```bash
+# Start web UI
+go tool pprof -http=:8080 cpu.prof
+
+# Browse to http://localhost:8080
+# Interactive flame graph, top view, source view
+```
+
+## Execution Tracing
+
+### Generate Trace
+```bash
+# During tests
+go test -trace=trace.out
+
+# In application
+import "runtime/trace"
+
+f, _ := os.Create("trace.out")
+trace.Start(f)
+defer trace.Stop()
+
+# Or via HTTP
+curl http://localhost:6060/debug/pprof/trace?seconds=5 > trace.out
+```
+
+### Analyze Trace
+```bash
+# Open trace viewer
+go tool trace trace.out
+
+# View in browser - shows:
+# - Goroutine execution
+# - Network blocking
+# - Synchronization blocking
+# - System calls
+# - GC events
+```
+
+## Profiling in Code
+
+### Basic CPU Profile
+```go
+import (
+    "os"
+    "runtime/pprof"
+)
+
+func main() {
+    f, _ := os.Create("cpu.prof")
+    defer f.Close()
+
+    pprof.StartCPUProfile(f)
+    defer pprof.StopCPUProfile()
+
+    // Your code here
+}
+```
+
+### Heap Profile
+```go
+import (
+    "os"
+    "runtime/pprof"
+)
+
+func writeHeapProfile() {
+    f, _ := os.Create("heap.prof")
+    defer f.Close()
+    pprof.WriteHeapProfile(f)
+}
+```
+
+### HTTP pprof Server
+```go
+import (
+    "net/http"
+    _ "net/http/pprof"
+)
+
+func main() {
+    go func() {
+        log.Println(http.ListenAndServe("localhost:6060", nil))
+    }()
+
+    // Your application code
+}
+
+// Access profiles at:
+// http://localhost:6060/debug/pprof/
+```
+
+## Analyzing Results
+
+### CPU Profile Interpretation
+- **flat**: Time spent in function itself
+- **cum**: Cumulative time (including callees)
+- **%**: Percentage of total time
+
+### Memory Profile Interpretation
+- **alloc_space**: Total allocated bytes
+- **alloc_objects**: Total allocated objects
+- **inuse_space**: Currently in-use bytes
+- **inuse_objects**: Currently in-use objects
+
+### Finding Hot Paths
+```bash
+# Top CPU consumers
+go tool pprof -top cpu.prof
+
+# Top memory allocators
+go tool pprof -top mem.prof
+
+# Call graph
+go tool pprof -web cpu.prof
+```
+
+## Benchmarking with Profiling
+
+```bash
+# CPU + memory profile
+go test -bench=. -cpuprofile=cpu.prof -memprofile=mem.prof -benchmem
+
+# Compare before/after
+benchstat old.txt new.txt
+```
+
+## Continuous Profiling
+
+### Datadog Example
+```go
+import "gopkg.in/DataDog/dd-trace-go.v1/profiler"
+
+err := profiler.Start(
+    profiler.WithService("myapp"),
+    profiler.WithEnv("production"),
+)
+defer profiler.Stop()
+```
+
+## Common Optimizations
+
+### Reduce Allocations
+```go
+// Before: Creates new slice each time
+func process(data []int) []int {
+    result := make([]int, 0)
+    for _, v := range data {
+        result = append(result, v*2)
+    }
+    return result
+}
+
+// After: Preallocate with capacity
+func process(data []int) []int {
+    result := make([]int, 0, len(data))
+    for _, v := range data {
+        result = append(result, v*2)
+    }
+    return result
+}
+```
+
+### Use sync.Pool
+```go
+var bufferPool = sync.Pool{
+    New: func() interface{} {
+        return new(bytes.Buffer)
+    },
+}
+
+func process() {
+    buf := bufferPool.Get().(*bytes.Buffer)
+    defer bufferPool.Put(buf)
+    buf.Reset()
+
+    // Use buffer
+}
+```
+
+### Avoid String Concatenation in Loops
+```go
+// Slow
+var s string
+for _, item := range items {
+    s += item  // Creates new string each time
+}
+
+// Fast
+var b strings.Builder
+for _, item := range items {
+    b.WriteString(item)
+}
+s := b.String()
+```
+
+## Makefile Example
+
+```makefile
+.PHONY: profile-cpu
+profile-cpu:
+	go test -bench=. -cpuprofile=cpu.prof
+	go tool pprof -http=:8080 cpu.prof
+
+.PHONY: profile-mem
+profile-mem:
+	go test -bench=. -memprofile=mem.prof
+	go tool pprof -http=:8080 mem.prof
+
+.PHONY: trace
+trace:
+	go test -trace=trace.out
+	go tool trace trace.out
+
+.PHONY: profile-serve
+profile-serve:
+	@echo "Starting pprof server on :6060"
+	@echo "CPU: curl http://localhost:6060/debug/pprof/profile?seconds=30 > cpu.prof"
+	@echo "Heap: curl http://localhost:6060/debug/pprof/heap > heap.prof"
+	go run -tags pprof main.go
+```
+
+## Best Practices
+
+1. **Profile in production-like environment**: Real data, real load
+2. **Focus on hot paths**: Optimize the 20% that matters
+3. **Measure before and after**: Use benchstat for comparisons
+4. **Profile different aspects**: CPU, memory, blocking, contention
+5. **Use flame graphs**: Visual representation is powerful
+6. **Sample for sufficient time**: 30+ seconds for CPU profiles
+7. **Check GC impact**: High GC time indicates memory issues
+8. **Monitor in production**: Continuous profiling catches regressions
+
+## Resources
+
+- [pprof Package](https://pkg.go.dev/net/http/pprof)
+- [Profiling Go Programs](https://go.dev/blog/pprof)
+- [Execution Tracer](https://go.dev/blog/execution-tracer)
+- [Diagnostics](https://go.dev/doc/diagnostics)
dots/.config/claude/skills/golang/workflows/Test.md
@@ -0,0 +1,403 @@
+# Test Workflow
+
+Run Go tests with coverage, race detection, and various testing patterns.
+
+## When to Use
+
+- "run go tests"
+- "test go code"
+- "check test coverage"
+- "run specific test"
+- "test with race detector"
+
+## Quick Commands
+
+### Basic Testing
+```bash
+# Run all tests in current package
+go test
+
+# Run tests in all packages
+go test ./...
+
+# Verbose output
+go test -v ./...
+
+# Run specific test
+go test -run TestMyFunction
+
+# Run tests matching pattern
+go test -run TestUser.*
+```
+
+### Test Coverage
+```bash
+# Run tests with coverage
+go test -cover ./...
+
+# Generate coverage profile
+go test -coverprofile=coverage.out ./...
+
+# View coverage in browser
+go tool cover -html=coverage.out
+
+# Show coverage by function
+go tool cover -func=coverage.out
+
+# Coverage for specific package
+go test -cover ./internal/auth
+```
+
+### Race Detection
+```bash
+# Run tests with race detector
+go test -race ./...
+
+# Race detection for specific package
+go test -race ./internal/handlers
+```
+
+### Performance
+```bash
+# Run short tests only (skip long-running tests)
+go test -short ./...
+
+# Set timeout
+go test -timeout 30s ./...
+
+# Run tests in parallel
+go test -parallel 4 ./...
+```
+
+## Test Patterns
+
+### Table-Driven Tests
+```go
+func TestValidateEmail(t *testing.T) {
+    tests := []struct {
+        name    string
+        email   string
+        wantErr bool
+    }{
+        {
+            name:    "valid email",
+            email:   "user@example.com",
+            wantErr: false,
+        },
+        {
+            name:    "missing @",
+            email:   "userexample.com",
+            wantErr: true,
+        },
+        {
+            name:    "empty email",
+            email:   "",
+            wantErr: true,
+        },
+    }
+
+    for _, tt := range tests {
+        t.Run(tt.name, func(t *testing.T) {
+            err := validateEmail(tt.email)
+            if (err != nil) != tt.wantErr {
+                t.Errorf("validateEmail(%q) error = %v, wantErr %v",
+                    tt.email, err, tt.wantErr)
+            }
+        })
+    }
+}
+```
+
+### Test Helpers
+```go
+// Mark as helper to get better error line numbers
+func assertEqual(t *testing.T, got, want int) {
+    t.Helper()
+    if got != want {
+        t.Errorf("got %d, want %d", got, want)
+    }
+}
+
+func TestCalculation(t *testing.T) {
+    result := calculate(2, 3)
+    assertEqual(t, result, 5)
+}
+```
+
+### Setup and Teardown
+```go
+func TestMain(m *testing.M) {
+    // Setup
+    setup()
+
+    // Run tests
+    code := m.Run()
+
+    // Teardown
+    teardown()
+
+    os.Exit(code)
+}
+
+func TestWithCleanup(t *testing.T) {
+    // Setup
+    db := setupTestDB(t)
+
+    // Cleanup automatically called after test
+    t.Cleanup(func() {
+        db.Close()
+    })
+
+    // Test code
+}
+```
+
+### Subtests
+```go
+func TestUserOperations(t *testing.T) {
+    t.Run("Create", func(t *testing.T) {
+        // Test user creation
+    })
+
+    t.Run("Update", func(t *testing.T) {
+        // Test user update
+    })
+
+    t.Run("Delete", func(t *testing.T) {
+        // Test user deletion
+    })
+}
+```
+
+## Test Organization
+
+### Package Structures
+```go
+// White-box testing (same package)
+package mypackage
+
+func TestInternalFunction(t *testing.T) {
+    // Can access private functions
+}
+
+// Black-box testing (separate package)
+package mypackage_test
+
+import "myproject/mypackage"
+
+func TestPublicAPI(t *testing.T) {
+    // Only access exported functions
+}
+```
+
+### Test Files
+```
+mypackage/
+├── user.go
+├── user_test.go       # Tests for user.go
+├── auth.go
+└── auth_test.go       # Tests for auth.go
+```
+
+## Advanced Testing
+
+### Testing with Timeouts
+```go
+func TestWithTimeout(t *testing.T) {
+    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+    defer cancel()
+
+    done := make(chan bool)
+    go func() {
+        // Long running operation
+        done <- true
+    }()
+
+    select {
+    case <-done:
+        // Success
+    case <-ctx.Done():
+        t.Fatal("test timed out")
+    }
+}
+```
+
+### Testing HTTP Handlers
+```go
+func TestHandler(t *testing.T) {
+    req := httptest.NewRequest("GET", "/users", nil)
+    w := httptest.NewRecorder()
+
+    handler(w, req)
+
+    if w.Code != http.StatusOK {
+        t.Errorf("got status %d, want %d", w.Code, http.StatusOK)
+    }
+}
+```
+
+### Mocking with Interfaces
+```go
+// Define interface
+type DataStore interface {
+    Get(id string) (*User, error)
+}
+
+// Mock implementation
+type MockDataStore struct {
+    GetFunc func(id string) (*User, error)
+}
+
+func (m *MockDataStore) Get(id string) (*User, error) {
+    return m.GetFunc(id)
+}
+
+// Use in tests
+func TestService(t *testing.T) {
+    mock := &MockDataStore{
+        GetFunc: func(id string) (*User, error) {
+            return &User{ID: id, Name: "Test"}, nil
+        },
+    }
+
+    service := NewService(mock)
+    // Test service...
+}
+```
+
+## Coverage Analysis
+
+### Coverage Modes
+```bash
+# Set coverage mode (default: set)
+go test -covermode=set -coverprofile=coverage.out ./...
+
+# Count mode (how many times each statement runs)
+go test -covermode=count -coverprofile=coverage.out ./...
+
+# Atomic mode (for parallel tests)
+go test -covermode=atomic -coverprofile=coverage.out ./...
+```
+
+### Coverage Thresholds
+```bash
+# Check if coverage meets threshold
+go test -cover ./... | grep -E "coverage: [0-9]+\.[0-9]+%" | \
+    awk '{if ($2 < 80.0) exit 1}'
+```
+
+### Combine Coverage from Multiple Packages
+```bash
+# Generate coverage for each package
+go test -coverprofile=coverage.out -covermode=atomic ./...
+
+# View total coverage
+go tool cover -func=coverage.out | grep total
+```
+
+## Makefile Example
+
+```makefile
+.PHONY: test
+test:
+	go test -v ./...
+
+.PHONY: test-coverage
+test-coverage:
+	go test -coverprofile=coverage.out -covermode=atomic ./...
+	go tool cover -html=coverage.out -o coverage.html
+	@echo "Coverage report generated: coverage.html"
+
+.PHONY: test-race
+test-race:
+	go test -race -short ./...
+
+.PHONY: test-all
+test-all: test-race test-coverage
+	@echo "All tests passed with race detection and coverage"
+
+.PHONY: test-clean
+test-clean:
+	rm -f coverage.out coverage.html
+```
+
+## CI/CD Integration
+
+### GitHub Actions Example
+```yaml
+- name: Run tests
+  run: go test -v ./...
+
+- name: Run tests with coverage
+  run: go test -coverprofile=coverage.out -covermode=atomic ./...
+
+- name: Upload coverage
+  uses: codecov/codecov-action@v3
+  with:
+    files: ./coverage.out
+
+- name: Run tests with race detector
+  run: go test -race ./...
+```
+
+## Test Flags Reference
+
+| Flag | Purpose |
+|------|---------|
+| `-v` | Verbose output |
+| `-run` | Run specific tests matching pattern |
+| `-cover` | Enable coverage |
+| `-coverprofile` | Write coverage profile to file |
+| `-covermode` | Set coverage mode (set/count/atomic) |
+| `-race` | Enable race detector |
+| `-short` | Run short tests only |
+| `-timeout` | Set test timeout (default 10m) |
+| `-parallel` | Set parallel test count |
+| `-count` | Run tests n times |
+| `-failfast` | Stop on first test failure |
+
+## Best Practices
+
+1. **Use table-driven tests**: More maintainable and comprehensive
+2. **Test behavior, not implementation**: Focus on what, not how
+3. **Use t.Helper()**: Mark helper functions for better error reporting
+4. **Prefer t.Error over t.Fatal**: Allow other tests to run
+5. **Use t.Parallel() carefully**: Only for independent tests
+6. **Mock external dependencies**: Use interfaces for testability
+7. **Aim for meaningful coverage**: 80%+ for critical paths
+8. **Run tests before committing**: `go test ./...` should pass
+9. **Use -race regularly**: Catch concurrency issues early
+10. **Keep tests fast**: Use `-short` for quick feedback
+
+## Common Issues
+
+### Tests Pass Individually but Fail Together
+```bash
+# Run tests sequentially
+go test -p 1 ./...
+
+# Check for shared state or race conditions
+go test -race ./...
+```
+
+### Slow Tests
+```bash
+# Identify slow tests
+go test -v ./... | grep -E "PASS|FAIL" | grep -E "[0-9]+\.[0-9]+s"
+
+# Skip slow tests during development
+go test -short ./...
+```
+
+### Flaky Tests
+- Usually indicate race conditions or timing issues
+- Run with `-race` to detect
+- Use proper synchronization primitives
+- Avoid `time.Sleep()` in tests
+
+## Resources
+
+- [Testing Package](https://pkg.go.dev/testing)
+- [Table Driven Tests](https://go.dev/wiki/TableDrivenTests)
+- [Go Test Comments](https://go.dev/wiki/CodeReviewComments#tests)
+- [httptest Package](https://pkg.go.dev/net/http/httptest)
dots/.config/claude/skills/golang/SKILL.md
@@ -8,6 +8,25 @@ description: Go development best practices and patterns. USE WHEN writing Go cod
 ## Purpose
 Guide Go development following official standards, community best practices, and idiomatic patterns from Effective Go and the Go team's code review guidelines.
 
+## Workflow Routing
+
+**When executing a workflow, output this notification directly:**
+
+```
+Running the **WorkflowName** workflow from the **Golang** skill...
+```
+
+| Workflow | Trigger | File |
+|----------|---------|------|
+| **Build** | "build go project", "compile", "cross compile" | `workflows/Build.md` |
+| **Test** | "run tests", "test coverage", "race detector" | `workflows/Test.md` |
+| **Benchmark** | "benchmark", "measure performance", "profile" | `workflows/Benchmark.md` |
+| **Lint** | "lint", "format", "gofmt", "golangci-lint" | `workflows/Lint.md` |
+| **Deps** | "dependencies", "go mod", "update deps", "vendor" | `workflows/Deps.md` |
+| **Debug** | "debug", "delve", "troubleshoot" | `workflows/Debug.md` |
+| **Profile** | "profile performance", "pprof", "optimize" | `workflows/Profile.md` |
+| **Generate** | "generate code", "mockgen", "stringer", "protobuf" | `workflows/Generate.md` |
+
 ## Core Principles
 
 1. **Clarity over cleverness**: Write simple, readable code that's easy to maintain