Back to list
JaimeStill

go-core

by JaimeStill

Architecture for hierarchical Claude context using plugins, skills, rules, and other features.

0🍴 0📅 Jan 9, 2026

SKILL.md


name: go-core description: > Core Go development patterns and idioms. Use for package design, code organization, configuration patterns, interface definitions, or when editing .go files. Triggers: package structure, dependency hierarchy, interface contracts, config transformation, encapsulation, layered organization, parameter encapsulation, modern Go idioms.

Go Core Development

When This Skill Applies

  • Designing package structure
  • Organizing code within files
  • Implementing configuration patterns
  • Defining interfaces and contracts
  • Working with dependencies between packages
  • Any Go file editing

Principles

1. Configuration Transformation Pattern

Configuration packages serve as ephemeral data containers that transform into domain objects at package boundaries.

Key Pattern:

  • Configuration types handle: structure, defaults, serialization, merging
  • Domain creation happens via finalization/validation functions
  • Runtime behavior depends on initialized state, not configuration values
  • Configuration should not persist beyond initialization phase
// Configuration: structure and defaults only
type ServerConfig struct {
    Host    string        `toml:"host"`
    Port    int           `toml:"port"`
    Timeout time.Duration `toml:"timeout"`
}

// Transformation: config → domain object
func NewServer(cfg ServerConfig) (*Server, error) {
    if cfg.Port == 0 {
        cfg.Port = 8080 // Default
    }
    return &Server{
        addr:    fmt.Sprintf("%s:%d", cfg.Host, cfg.Port),
        timeout: cfg.Timeout,
    }, nil
}

Decision Framework:

  • Type 1 (Initialization-Only): Config discarded after creating domain object
  • Type 2 (Immutable Runtime Settings): Config stored throughout object lifetime
  • Type 3 (Mutable Runtime Settings): Config with validated setters and mutex protection

2. Encapsulation & Data Access Pattern

Never expose direct field access to nested structures; always provide semantic getter methods.

Bad:

// Exposes internal structure, fragile to changes
chunk.Choices[0].Delta.Content

Good:

// Semantic getter encapsulates access logic
func (c *Chunk) ExtractContent() string {
    if len(c.Choices) == 0 {
        return ""
    }
    return c.Choices[0].Delta.Content
}

// Usage
content := chunk.ExtractContent()

Benefits:

  • Hides internal structure complexity
  • Bounds checking in one place
  • Easier refactoring

3. Layered Code Organization

Structure code within files in dependency order: foundational types first.

Order:

  1. Package declaration
  2. Imports
  3. Constants
  4. Global variables
  5. Interfaces
  6. Pure types/enums (data structures without methods)
  7. Structures + methods (grouped together)
  8. Standalone functions
package example

import "context"

// Constants
const DefaultTimeout = 30 * time.Second

// Interfaces
type Repository interface {
    Find(ctx context.Context, id string) (*Entity, error)
}

// Pure types
type EntityType string

const (
    TypeA EntityType = "a"
    TypeB EntityType = "b"
)

// Structures with methods
type Entity struct {
    ID   string
    Type EntityType
}

func (e *Entity) Validate() error {
    if e.ID == "" {
        return errors.New("id required")
    }
    return nil
}

// Standalone functions
func NewEntity(id string, t EntityType) *Entity {
    return &Entity{ID: id, Type: t}
}

4. Parameter Encapsulation Rule

If a function requires more than 2 parameters, encapsulate them into a structure.

Bad:

func Execute(ctx context.Context, capability string, input string,
    timeout time.Duration, retries int, cache bool) (*Result, error)

Good:

type ExecuteRequest struct {
    Capability string
    Input      string
    Timeout    time.Duration
    Retries    int
    UseCache   bool
}

func Execute(ctx context.Context, req ExecuteRequest) (*Result, error)

Benefits:

  • Self-documenting named fields
  • Optional parameters through zero values
  • Easier extension without breaking existing calls

5. Interface-Based Layer Interconnection

Layers should interconnect exclusively through interfaces, not concrete types.

// Interface defines public API
type Renderer interface {
    Render(input []byte) ([]byte, error)
}

// Constructor returns interface, not concrete type
func NewImageMagickRenderer(cfg ImageConfig) (Renderer, error) {
    return &imageMagickRenderer{cfg: cfg}, nil
}

// Consumer stores interface dependency
type PDFDocument struct {
    renderer Renderer  // Interface, not *imageMagickRenderer
}

func NewPDFDocument(r Renderer) *PDFDocument {
    return &PDFDocument{renderer: r}
}

6. Package Dependency Hierarchy

Maintain clear, unidirectional dependencies flowing from high-level to low-level packages.

Level 0: observability/        (no dependencies)
    ↓
Level 1: messaging/            (depends on observability)
    ↓
Level 2: hub/                  (depends on messaging)
    ↓
Level 3: state/                (depends on observability)
    ↓
Level 4: workflows/            (depends on state + observability)

Rules:

  • Lower layers cannot import higher layers
  • Prevents circular dependencies
  • Each layer validates independently
  • Higher layers depend on lower-level interfaces

7. Package Organization Depth Limitation

Avoid package subdirectories deeper than one level.

Good:

pkg/
├── image/
├── cache/
└── document/

Bad:

pkg/
└── document/
    └── formats/
        └── processors/
            └── types/

Deep nesting signals architectural problems. Ask: Should this be a separate package?

8. Contract Interface Pattern

Lower-level packages define minimal interfaces that higher-level packages implement.

// In pkg/cache (lower level)
type Logger interface {
    Log(ctx context.Context, level string, msg string)
}

// Cache uses the interface, doesn't import logger package
type Cache struct {
    logger Logger
}

func NewCache(logger Logger) *Cache {
    return &Cache{logger: logger}
}
// In pkg/logger (higher level) - implements the contract
type SlogAdapter struct {
    slog *slog.Logger
}

func (a *SlogAdapter) Log(ctx context.Context, level, msg string) {
    a.slog.Log(ctx, parseLevel(level), msg)
}

// Usage: dependency injection
cache := NewCache(&SlogAdapter{slog: slog.Default()})

9. Modern Go Idioms (Go 1.25+)

Leverage latest language features and standard library methods.

// sync.WaitGroup.Go() - Combines Add(1) + goroutine launch + implicit Done()
var wg sync.WaitGroup
for _, task := range tasks {
    wg.Go(func() {
        process(task)
    })
}
wg.Wait()

// for range n - Integer range without index variable
workers := min(runtime.NumCPU()*2, len(tasks))
for range workers {
    wg.Go(func() { /* worker */ })
}

// min()/max() built-ins
limit := min(requested, maxAllowed)

// errors.Join() - Combine multiple errors
var errs []error
for _, item := range items {
    if err := validate(item); err != nil {
        errs = append(errs, err)
    }
}
return errors.Join(errs...)

// defer close(channel) - Always in sender goroutine
go func() {
    defer close(results)
    for item := range input {
        results <- process(item)
    }
}()

Anti-Patterns

Leaky Configuration

// Bad: Config persists and is accessed at runtime
type Service struct {
    config Config  // Stored and used later
}

func (s *Service) Process() {
    timeout := s.config.Timeout  // Accessing config at runtime
}
// Good: Config transformed at construction
type Service struct {
    timeout time.Duration  // Only the needed value stored
}

func NewService(cfg Config) *Service {
    return &Service{timeout: cfg.Timeout}
}

God Packages

// Bad: Package does too many things
package utils

func ParseJSON() {}
func SendEmail() {}
func ResizeImage() {}
func ValidateInput() {}
// Good: Single responsibility packages
package json
package email
package image
package validation

Circular Dependencies

// Bad: A imports B, B imports A
package a
import "project/b"

package b
import "project/a"  // Circular!
// Good: Extract shared interface to lower level
package contracts
type Processor interface { Process() }

package a
import "project/contracts"

package b
import "project/contracts"

Score

Total Score

45/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

0/5
タグ

1つ以上のタグが設定されている

0/5

Reviews

💬

Reviews coming soon