Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 138 additions & 0 deletions .arch-go.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# arch-go configuration file
# Run: arch-go
# Install: go install github.com/fdaines/arch-go@latest
#
# This enforces clean architecture boundaries in the TKA codebase.

version: 1

# Compliance thresholds
threshold:
compliance:
rate: 80
scope: "package"
coverage:
rate: 80
scope: "package"

# Dependency rules enforce layer boundaries
dependenciesRules:
# ============================================
# LAYER: Operator (Kubernetes Controller Logic)
# ============================================
# Operators should use abstractions, not direct HTTP or DB
- package: "github.com/spechtlabs/tka/pkg/operator"
shouldNotDependsOn:
- "net/http" # No direct HTTP calls
- "database/sql" # No direct DB access
shouldNotDependsOnExternal:
- "github.com/gin-gonic/gin" # HTTP framework is for API layer

# ============================================
# LAYER: API/Service (HTTP Handlers)
# ============================================
# API layer uses client abstractions, not k8s internals
- package: "github.com/spechtlabs/tka/pkg/service/api"
shouldNotDependsOn:
- "k8s.io/client-go/kubernetes" # Use client/k8s abstraction
- "sigs.k8s.io/controller-runtime" # This is for operators only

# ============================================
# LAYER: Client (Data Access)
# ============================================
# Client package provides abstractions, shouldn't know about higher layers
- package: "github.com/spechtlabs/tka/pkg/client/**"
shouldNotDependsOn:
- "github.com/spechtlabs/tka/pkg/service/**"
- "github.com/spechtlabs/tka/pkg/operator/**"
- "github.com/gin-gonic/gin"

# ============================================
# LAYER: Models (Pure Data Structures)
# ============================================
# Models should be pure data, minimal dependencies
- package: "github.com/spechtlabs/tka/pkg/models"
shouldOnlyDependsOn:
- "github.com/sierrasoftworks/humane-errors-go"
- "encoding/json"
- "errors"
shouldNotDependsOn:
- "k8s.io/**"
- "sigs.k8s.io/**"
- "github.com/gin-gonic/gin"

# Service models are also pure
- package: "github.com/spechtlabs/tka/pkg/service/models"
shouldNotDependsOn:
- "k8s.io/**"
- "sigs.k8s.io/**"

# ============================================
# LAYER: Middleware (Cross-cutting Concerns)
# ============================================
# Middleware should be self-contained, not depend on business logic
- package: "github.com/spechtlabs/tka/pkg/middleware/**"
shouldNotDependsOn:
- "github.com/spechtlabs/tka/pkg/operator/**"
- "github.com/spechtlabs/tka/pkg/client/k8s" # Can use models but not k8s client

# ============================================
# LAYER: tshttp (Tailscale HTTP Server)
# ============================================
# Infrastructure layer, no business logic dependencies
- package: "github.com/spechtlabs/tka/pkg/tshttp"
shouldNotDependsOn:
- "github.com/spechtlabs/tka/pkg/service/**"
- "github.com/spechtlabs/tka/pkg/operator/**"
- "github.com/spechtlabs/tka/pkg/client/**"
- "github.com/spechtlabs/tka/api/**"

# ============================================
# LAYER: Internal (Private Implementation)
# ============================================
# Internal packages shouldn't create circular dependencies
- package: "github.com/spechtlabs/tka/internal/**"
shouldNotDependsOn:
- "github.com/spechtlabs/tka/cmd/**"

# ============================================
# API Types (CRD Definitions)
# ============================================
# API types should only depend on k8s API machinery
- package: "github.com/spechtlabs/tka/api/**"
shouldOnlyDependsOn:
- "k8s.io/apimachinery/**"
shouldNotDependsOn:
- "github.com/spechtlabs/tka/pkg/**"
- "github.com/spechtlabs/tka/internal/**"

# Content rules enforce structural patterns
contentsRules:
# Mock packages should only contain mock implementations
- package: "github.com/spechtlabs/tka/**/mock"
shouldOnlyContainStructs: true

# Function rules enforce code quality
functionsRules:
# Keep functions focused and testable
- package: "github.com/spechtlabs/tka/pkg/**"
maxLines: 60
maxParameters: 5
maxReturnValues: 3

# API handlers should be small
- package: "github.com/spechtlabs/tka/pkg/service/api"
maxLines: 40
maxPublicFunctionPerFile: 5

# Naming rules enforce conventions
namingRules:
# Interface naming conventions
- package: "github.com/spechtlabs/tka/pkg/**"
interfaceImplementationNamingRule:
shouldHaveSimpleNameEndingWith:
- "Impl"
- "Service"
- "Client"
- "Handler"
- "Middleware"
163 changes: 163 additions & 0 deletions .golangci-tka.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# golangci-lint configuration with TKA-specific analyzers
# This extends the base .golangci.yml with custom checks
#
# Usage:
# golangci-lint run -c .golangci-tka.yaml ./...
#
# Or merge into your existing .golangci.yml

run:
timeout: 5m
tests: true
go: "1.25"

output:
formats:
- format: colored-line-number
print-issued-lines: true
print-linter-name: true
sort-results: true

linters:
enable:
# Standard high-value linters
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
- unused

# Additional quality linters
- bodyclose
- dupl
- errorlint
- exhaustive
- goconst
- gocritic
- gocyclo
- gofmt
- goimports
- gosec
- misspell
- nakedret
- nilerr
- prealloc
- revive
- unconvert
- unparam
- wastedassign

linters-settings:
# Error handling
errorlint:
errorf: true
asserts: true
comparison: true

# Complexity thresholds
gocyclo:
min-complexity: 15

# Function length
funlen:
lines: 60
statements: 40

# Duplicate detection
dupl:
threshold: 100

# Security checks
gosec:
excludes:
- G104 # Audit errors not checked (we use humane errors)
config:
G301: "0750" # File permissions
G302: "0640"
G306: "0640"

# Code review comments
revive:
rules:
- name: blank-imports
- name: context-as-argument
- name: context-keys-type
- name: dot-imports
- name: error-return
- name: error-strings
- name: error-naming
- name: exported
- name: if-return
- name: increment-decrement
- name: var-naming
- name: var-declaration
- name: package-comments
- name: range
- name: receiver-naming
- name: time-naming
- name: unexported-return
- name: indent-error-flow
- name: errorf
- name: empty-block
- name: superfluous-else
- name: unused-parameter
- name: unreachable-code
- name: redefines-builtin-id

# gocritic checks
gocritic:
enabled-tags:
- diagnostic
- style
- performance
- experimental
- opinionated
disabled-checks:
- hugeParam # We use options pattern which can have larger structs
- rangeValCopy

issues:
exclude-rules:
# Exclude some linters from running on tests
- path: _test\.go
linters:
- dupl
- gosec
- goconst
- funlen

# Exclude mock packages from most checks
- path: /mock/
linters:
- dupl
- unused
- gocritic

# Exclude generated files
- path: zz_generated
linters:
- all

# Allow fmt.Errorf in tests
- path: _test\.go
text: "fmt.Errorf"

exclude-dirs:
- vendor
- third_party
- testdata
- tools/analyzers/*/testdata

max-issues-per-linter: 50
max-same-issues: 3

severity:
default-severity: warning
rules:
- linters:
- revive
severity: info
- linters:
- gosec
severity: error
53 changes: 53 additions & 0 deletions .golint-sl.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# golint-sl configuration for tka
# See https://github.com/SpechtLabs/golint-sl for documentation

analyzers:
# Error Handling - Keep enabled, these are important
humaneerror: true
errorwrap: true
sentinelerrors: true

# Observability
wideevents: true
contextlogger: false # Uses global zap logger by design

# Kubernetes - Keep enabled, tka is a K8s operator
reconciler: true
statusupdate: true
sideeffects: true

# Testability - Disable some that require significant refactoring
clockinterface: true # Re-enabled to analyze
interfaceconsistency: true # Re-enabled to analyze
mockverify: true # Re-enabled to analyze
optionspattern: true # Re-enabled to check for issues

# Resources - Keep enabled, these are critical
resourceclose: true
httpclient: true

# Safety - Keep most enabled
goroutineleak: true
nilcheck: true # Re-enabled - analyzer now handles trusted types and patterns
nopanic: true
nestingdepth: true # Re-enabled to analyze
syncaccess: true # Re-enabled to analyze

# Clean Code - Re-enabled to analyze issues
varscope: true
closurecomplexity: true
emptyinterface: true
returninterface: true

# Architecture
contextfirst: true
pkgnaming: false # Package names would require significant refactoring to fix
functionsize: true # Re-enabled to analyze
exporteddoc: true # Re-enabled to analyze
todotracker: true # Re-enabled to analyze
hardcodedcreds: true
lifecycle: true # Re-enabled to analyze
dataflow: true

# Context propagation - Keep enabled for most cases
contextpropagation: true
1 change: 1 addition & 0 deletions .markdownlint-cli2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ config:
MD013: false
MD024: false
MD038: false
MD060: false

# Include all Markdown files in the project
globs:
Expand Down
1 change: 1 addition & 0 deletions .mise.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pre-commit = "4.5.1"

# Additional tools for development
golangci-lint = "2.8.0"
"go:github.com/spechtlabs/golint-sl/cmd/golint-sl" = "latest"
goreleaser = "2.12.0"
kind = "0.31.0"
kubectl = "1.35.0"
Expand Down
Loading
Loading