From harness-engineering
Go harness configuration guidance. Covers gofumpt (format), golangci-lint v2 with depguard/cyclop/iface/exhaustive, go-arch-lint (layer boundaries), gosec (security), and custom go/analysis analyzers. Use when setting up Go harness, troubleshooting Go lint hook failures, writing .golangci.yml, or declaring architecture rules in .go-arch-lint.yml. Do NOT use for TS or Proto.
npx claudepluginhub toru-oizumi/claude-harness-engineering --plugin harness-engineeringThis skill uses the workspace's default tool permissions.
The Go side of the harness. Tools here are all native Go, so they're fast by default.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
The Go side of the harness. Tools here are all native Go, so they're fast by default.
| Role | Tool | Notes |
|---|---|---|
| Format | gofumpt | Stricter superset of gofmt. Opinionated, no config. |
| Imports | goimports | Organize imports, remove unused |
| Lint aggregator | golangci-lint v2 | Parallel runner for 100+ linters |
| Dependency rules | depguard (inside golangci-lint) | Block forbidden package imports |
| Architecture | go-arch-lint | YAML-declared layer rules |
| Security | gosec | CWE-mapped static analysis |
| Complexity | cyclop (inside golangci-lint) | Cyclomatic complexity gate |
The default .golangci.yml installed by /harness:init enables these linters:
# NOTE: protected by pre-config-protect hook
version: "2"
linters:
enable:
- errcheck
- govet
- ineffassign
- staticcheck
- unused
- gosimple
- depguard # forbidden imports
- cyclop # complexity gate
- iface # interface bloat detection
- exhaustive # enum exhaustiveness
- containedctx # context in struct = smell
- decorder # declaration order
- errorlint # error wrapping correctness
- gosec # security
Run mode: --fast in PostToolUse hook (file-scoped, ~200ms), full run in CI.
A minimal Clean Architecture .go-arch-lint.yml:
version: 3
workdir: .
components:
domain: { in: domain/** }
usecase: { in: usecase/** }
infrastructure: { in: infrastructure/** }
interfaces: { in: interfaces/** }
deps:
domain: { allow: [] } # pure
usecase: { allow: [domain] }
infrastructure: { allow: [domain, usecase] }
interfaces: { allow: [domain, usecase, infrastructure] }
excludeFiles:
- "**/*_test.go"
- "**/*.pb.go"
- "**/mock/**"
The template at ${CLAUDE_PLUGIN_ROOT}/templates/.go-arch-lint.clean-arch.yml has a more complete version.
On every .go file Write/Edit, post-edit-lint.js:
gofumpt -w <file> (or gofmt -w fallback)goimports -w <file>golangci-lint run --fast --out-format line-number <file>go-arch-lint check (project-wide; only report if violation mentions this file)additionalContextGenerated files (*.pb.go, *_gen.go, files with Code generated ... DO NOT EDIT header) are skipped automatically.
containedctx catches context stored in structs, which is always wrong.fmt.Errorf("...: %w", err), not %v. errorlint catches this.defer rows.Close() immediately after a successful query. This is easy to forget and hard to catch without a linter.architecture-enforcement — go-arch-lint deep diveedit-lint-feedback-loop — hook mechanicsharness-setup — initial setupSee gotchas.md.