soul.demarkus.io:6309/patterns.md/v1 draft reader meta

Patterns & Conventions

What I've learned about how we write code in this project.

Go Style

Loop Idiom

Always range N for integer loops. Never for i := 0; i < N; i++. This is a hard rule Fritz set early.

Table-Driven Tests

Every test file uses t.Run with named subtests. The pattern:

tests := []struct {
    name string
    // inputs...
    // expected...
}{
    {"descriptive name", ...},
}
for _, tt := range tests {
    t.Run(tt.name, func(t *testing.T) {
        // test body
    })
}

Mock Streams for Handlers

Handler tests construct a bytes.Buffer with a raw request, pass it as a stream, and read the response. No QUIC, no network, fast tests.

t.TempDir() for Fixtures

Never create test fixtures in the working directory. Always t.TempDir() — Go cleans it up automatically.

Development Workflow

Build Rule

Always make client or go build -o bin/<name> ./cmd/<name>/. Never bare go build ./cmd/<name>/ — binaries must land in bin/.

Pre-Commit

Run bash pre-commit.sh before committing. Formats, vets, and lints all modules.

Conventional Commits

Module-scoped: feat(server): description, fix(client): description. This drives auto-versioning and release tagging (server/v0.1.0, etc.).

Philosophy

Small and Incremental

Every change should be the smallest working increment. Get something tested and working before moving on. Don't batch up large changes.

Robustness First

Handle the error. Test the edge case. Make it correct before making it elegant.

Simplest Solution

Short functions, clear names, obvious flow. If I find myself writing a comment to explain what code does, the code should be rewritten to not need the comment. Comments explain why, not what.

No Over-Engineering

Don't add features beyond what's asked. Don't refactor surroundings while fixing a bug. Don't add abstractions for one-time operations. Three similar lines are better than a premature helper function.

What I've Learned About Working With Fritz

Fritz values directness. Short answers over long explanations. Working code over architecture astronautics. He'll push back on unnecessary complexity and he's usually right when he does. The best sessions are when we move fast through small, clean changes — each one tested, each one committed. Momentum matters.

trail
  1. soul.demarkus.io:6309 v1