Go platform/OS-specific code patterns for cross-platform projects. Use when writing or reviewing code that must work on multiple OSes (Linux, Windows), when you see noop stubs in _<os>.go files, runtime.GOOS checks, or OS-specific build tags. Supersedes generic Go guidance on build tags and OS-specific code. Trigger on any code that branches by operating system.
npx skills add https://github.com/Azure/azure-container-networking --skill acn-go-platform-abstraction
Persona: You are a Go platform engineer who believes that if you need a noop stub, your abstraction is in the wrong place. OS-specific code must be invisible to the common code paths — the if moves out of the code and into the file system via _<os>.go files.
Modes:
_<os>.go files, (2) find runtime.GOOS checks in non-test code, (3) find OS-specific imports in common files.> Supersedes generic Go guidance on build tags and OS-specific code organization.
Noop implementations to make the compiler happy indicate that the OS abstraction is wrong. Once you get to the point that you need to execute OS-specific behavior, you are _already_ in OS-specific code, and _that's_ what needs to be separated into _<os>.go files.
addDefaultRoute on Linux because it's only needed on Windows, the abstraction boundary is too low. Move it up to where the calling code diverges.runtime.GOOS — any explicit GOOS check or noop stubbing of an interface in a *_<os>.go file indicates the abstraction is in the wrong place.config_<os>.go — don't hardcode paths or values that differ by OS in common code.// ❌ BAD — k8sSwiftV2_linux.go
// Stubbing Windows-only behavior on Linux is nonsensical
func (k *K8sSWIFTv2Middleware) addDefaultRoute(*cns.PodIpInfo, string) {}
// ❌ BAD — hnsclient_linux.go
// "hnsclient_linux" is nonsensical — HNS is a Windows concept
type linuxHNSClient struct{}
func (l *linuxHNSClient) DeleteEndpoint(id string) error { return nil }
This forces the reader to mentally track: "if GOOS=linux then this method call is noop." The if has moved out of code and into your head — that's worse, not better.
Find the last point of common code before OS divergence. That function gets OS-specific implementations:
// ❌ BAD — common code calls OS-specific stubs
func processEndpoint(info *EndpointInfo) error {
// ... common logic ...
if err := addDefaultRoute(info); err != nil { // noop on Linux!
return err
}
if err := configureHNS(info); err != nil { // noop on Linux!
return err
}
return nil
}
// ✅ GOOD — split at the last common boundary
// endpoint.go (common)
func processEndpoint(info *EndpointInfo) error {
// ... common logic ...
return configurePlatformNetworking(info)
}
// endpoint_linux.go
func configurePlatformNetworking(info *EndpointInfo) error {
return nil // nothing platform-specific needed
}
// endpoint_windows.go
func configurePlatformNetworking(info *EndpointInfo) error {
if err := addDefaultRoute(info); err != nil {
return err
}
return configureHNS(info)
}
The key insight: addDefaultRoute shouldn't exist in the common abstraction at all. The question is "what platform-specific networking setup is needed?" — and on Linux, the answer is "nothing."
When you encounter OS-specific behavior:
_linux.go and _windows.go versions of that function.| Signal | Problem | Fix |
| --- | --- | --- |
| Noop stub in _<os>.go | Abstraction too low | Move boundary up to caller |
| runtime.GOOS check | No abstraction at all | Extract to _<os>.go files |
| OS name in struct/func name | Wrong abstraction | Name the behavior, not the OS |
| Stub returns nil error always | Interface too broad | Narrow interface or eliminate |
| Common code imports OS-specific pkg | Wrong file placement | Move import to _<os>.go file |
// ❌ BAD — hardcoded paths with OS conditionals
const statePath = "/var/run/azure-cns"
// ✅ GOOD — config_<os>.go files
// config_linux.go
const defaultStatePath = "/var/run/azure-cns"
// config_windows.go
const defaultStatePath = `C:\ProgramData\azure-cns`
// config.go (common)
func statePath(configured string) string {
if configured != "" {
return configured
}
return defaultStatePath
}
// ❌ BAD — shelling out to PowerShell for registry/service operations
func setRegistryValue(key, value string) error {
cmd := exec.Command("powershell", "-Command",
fmt.Sprintf(`Set-ItemProperty -Path "%s" -Name "%s" -Value "%s"`, path, key, value))
return cmd.Run()
}
// ✅ GOOD — native Go Windows APIs
func setRegistryValue(key registry.Key, name string, value uint32) error {
return key.SetDWordValue(name, value)
}
Shell-outs are fragile (path issues, encoding, quoting), slow (process spawn), and untestable. Use golang.org/x/sys/windows/registry, golang.org/x/sys/windows/svc, etc. These are type-safe, testable with mocks, and context-aware.
| Mistake | Fix |
| --- | --- |
| func newLinuxRegistryClient returning windowsRegistryClient interface | Name the behavior, not the OS — this is nonsensical |
| Stubbing Windows-only behavior in Linux structs | The calling code is OS-specific — split there instead |
| hnsclient_linux.go with noop HNS calls | HNS doesn't exist on Linux — the caller needs the split |
| Checking runtime.GOOS to branch behavior | Use _<os>.go build constraint files |
| Passing whole CNS config to decide OS behavior | Extract the boolean/value the function actually needs |
| Shell-outs for OS operations | Use native Go OS packages (registry, svc, mgr) |
| Importing hcsshim in common code | HCS imports belong only in _windows.go files |
acn-go-design-boundaries skill for behavioral config vs scenario configacn-go-interfaces-dependencies skill for interface design at the consumersamber/cc-skills-golang@golang-code-style for general file organizationExecute git commit with conventional commit message analysis, intelligent staging, and message generation. Use when user asks to commit changes, create a git commit, or mentions "/commit". Supports: (1) Auto-detecting type and scope from changes, (2) Generating conventional commit messages from diff, (3) Interactive commit with optional type/scope/description overrides, (4) Intelligent file staging for logical grouping
Comprehensive GitHub code review with AI-powered swarm coordination
Create high-quality git commits: review/stage intended changes, split into logical commits, and write clear commit messages (including Conventional Commits). Use when the user asks to commit, craft a commit message, stage changes, or split work into multiple commits.
Comprehensive truth scoring, code quality verification, and automatic rollback system with 0.95 accuracy threshold for ensuring high-quality agent outputs and codebase reliability.
GitHub CLI (gh) comprehensive reference for repositories, issues, pull requests, Actions, projects, releases, gists, codespaces, organizations, extensions, and all GitHub operations from the command line.
GitHub CLI - manage repositories, issues, pull requests, actions, releases, and more from the command line.
You are a code refactoring expert specializing in clean code principles, SOLID design patterns, and modern software engineering best practices. Analyze and refactor the provided code to improve its quality, maintainability, and performance.
You are a technical debt expert specializing in identifying, quantifying, and prioritizing technical debt in software projects. Analyze the codebase to uncover debt, assess its impact, and create acti
Take azure/acn-go-platform-abstraction from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.