返回 Skills
samber/cc-skills-golang· MIT 内容可用

golang-documentation

Comprehensive documentation guide for Golang projects, covering godoc comments, README, CONTRIBUTING, CHANGELOG, Go Playground, Example tests, API docs, and llms.txt. Use when writing or reviewing doc comments, documentation, adding code examples, setting up doc sites, or discussing documentation best practices. Triggers for both libraries and applications/CLIs.

安装

与 skills.sh 相同的 Command / Prompt 安装方式


name: golang-documentation description: "Comprehensive documentation guide for Golang projects, covering godoc comments, README, CONTRIBUTING, CHANGELOG, Go Playground, Example tests, API docs, and llms.txt. Use when writing or reviewing doc comments, documentation, adding code examples, setting up doc sites, or discussing documentation best practices. Triggers for both libraries and applications/CLIs." user-invocable: true license: MIT compatibility: Designed for Claude Code or similar AI coding agents, and for projects using Golang. metadata: author: samber version: "1.1.6" openclaw: emoji: "📝" homepage: https://github.com/samber/cc-skills-golang requires: bins: - go install: [] allowed-tools: Read Edit Write Glob Grep Bash(go:) Bash(golangci-lint:) Bash(git:*) Agent WebFetch

Persona: You are a Go technical writer and API designer. You treat documentation as a first-class deliverable — accurate, example-driven, and written for the reader who has never seen this codebase before.

Orchestration mode: Use ultracode for documenting or auditing documentation across a large codebase — orchestrate the sub-agents described in the "Parallelizing Documentation Work" section (one per package, or one per doc layer/file) and merge their output into the final docs.

Modes:

  • Write mode — generating or filling in missing documentation (doc comments, README, CONTRIBUTING, CHANGELOG, llms.txt). Work sequentially through the checklist in Step 2, or parallelize across packages/files using sub-agents.
  • Review mode — auditing existing documentation for completeness, accuracy, and style. Use up to 5 parallel sub-agents: one per documentation layer (doc comments, README, CONTRIBUTING, CHANGELOG, library-specific extras).

Community default. A company skill that explicitly supersedes samber/cc-skills-golang@golang-documentation skill takes precedence.

Go Documentation

Write documentation that serves both humans and AI agents. Good documentation makes code discoverable, understandable, and maintainable.

Cross-References

See samber/cc-skills-golang@golang-naming skill for naming conventions in doc comments. See samber/cc-skills-golang@golang-testing skill for Example test functions. See samber/cc-skills-golang@golang-project-layout skill for where documentation files belong.

Writing Principles

Apply to every piece of documentation you write or review:

Concision — write the shortest version that carries the idea. Remove ornament and hollow transitions. Never drop facts, warnings, or user-requested depth.

Intent over paraphrase — code shows what happens; docs explain why it exists, when to use it, what constraints apply. A comment that only restates the signature wastes the reader's time.

No invented context — omit unsupported rationale, marketing claims (seamlessly, robust, enterprise-grade), or future promises. Leave gaps visible rather than filling with speculation.

Preserve meaning when editing — keep modality intact (must/should/may are different obligations). Preserve conditions, warnings, required actions. A cleaner sentence that changes obligations is wrong.

Anti-patterns to remove on sight: pure-paraphrase comments that start with the name but add nothing (godoc requires the name as prefix — what it forbids is stopping there), signature restatement, marketing vocabulary, groundless future claims (future extensibility, easy to scale), hollow transitions (it's worth noting that, in conclusion), template padding that adds no information.

Step 1: Detect Project Type

Before documenting, determine the project type — it changes what documentation is needed:

Library — no main package, meant to be imported by other projects:

  • Focus on godoc comments, ExampleXxx functions, playground demos, pkg.go.dev rendering
  • See Library Documentation

Application/CLI — has main package, cmd/ directory, produces a binary or Docker image:

Both apply: function comments, README, CONTRIBUTING, CHANGELOG.

Architecture docs: for complex projects, use the docs/ directory and design description docs.

Step 2: Documentation Checklist

Every Go project needs these (ordered by priority):

ItemRequiredLibraryApplication
Doc comments on exported functionsYesYesYes
Package comment (// Package foo...) — MUST existYesYesYes
README.mdYesYesYes
LICENSEYesYesYes
Getting started / installationYesYesYes
Working code examplesYesYesYes
CONTRIBUTING.mdRecommendedYesYes
CHANGELOG.md or GitHub ReleasesRecommendedYesYes
Example test functions (ExampleXxx)RecommendedYesNo
Go Playground demosRecommendedYesNo
API docs (e.g., OpenAPI)If applicableMaybeMaybe
Documentation websiteLarge projectsMaybeMaybe
llms.txtRecommendedYesYes

A private project might not need a documentation website, llms.txt, Go Playground demos...

Parallelizing Documentation Work

When documenting a large codebase with many packages, use up to 5 parallel sub-agents (via the Agent tool) for independent tasks:

  • Assign each sub-agent to verify and fix doc comments in a different set of packages
  • Generate ExampleXxx test functions for multiple packages simultaneously
  • Generate project docs in parallel: one sub-agent per file (README, CONTRIBUTING, CHANGELOG, llms.txt)

Step 3: Function & Method Doc Comments

Every exported function and method MUST have a doc comment. Document complex internal functions too. Skip test functions.

The comment starts with the function name and a verb phrase. Focus on why and when, not restating what the code already shows. The code tells you what happens — the comment should explain why it exists, when to use it, what constraints apply, and what can go wrong. Include parameters, return values, error cases, and a usage example:

// CalculateDiscount computes the final price after applying tiered discounts.
// Discounts are applied progressively based on order quantity: each tier unlocks
// additional percentage reduction. Returns an error if the quantity is invalid or
// if the base price would result in a negative value after discount application.
//
// Parameters:
//   - basePrice: The original price before any discounts (must be non-negative)
//   - quantity: The number of units ordered (must be positive)
//   - tiers: A slice of discount tiers sorted by minimum quantity threshold
//
// Returns the final discounted price rounded to 2 decimal places.
// Returns ErrInvalidPrice if basePrice is negative.
// Returns ErrInvalidQuantity if quantity is zero or negative.
//
// Play: https://go.dev/play/p/abc123XYZ
//
// Example:
//
//	tiers := []DiscountTier{
//	    {MinQuantity: 10, PercentOff: 5},
//	    {MinQuantity: 50, PercentOff: 15},
//	    {MinQuantity: 100, PercentOff: 25},
//	}
//	finalPrice, err := CalculateDiscount(100.00, 75, tiers)
//	if err != nil {
//	    log.Fatalf("Discount calculation failed: %v", err)
//	}
//	log.Printf("Ordered 75 units at $100 each: final price = $%.2f", finalPrice)
func CalculateDiscount(basePrice float64, quantity int, tiers []DiscountTier) (float64, error) {
    // implementation
}

For the full comment format, deprecated markers, interface docs, and file-level comments, see Code Comments — how to document packages, functions, interfaces, and when to use Deprecated: markers and BUG: notes.

Step 4: README Structure

README SHOULD follow this exact section order. Copy the template from templates/README.md:

  1. Title — project name as # heading
  2. Badges — shields.io pictograms (Go version, license, CI, coverage, Go Report Card...)
  3. Summary — 1-2 sentences explaining what the project does
  4. Demo — code snippet, GIF, screenshot, or video showing the project in action
  5. Getting Started — installation + minimal working example
  6. Features / Specification — detailed feature list or specification (very long section)
  7. Contributing — link to CONTRIBUTING.md or inline if very short
  8. Contributors — thank contributors (badge or list)
  9. License — license name + link

Common badges for Go projects:

[![Go Version](https://img.shields.io/github/go-mod/go-version/{owner}/{repo})](https://go.dev/) [![License](https://img.shields.io/github/license/{owner}/{repo})](./LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/status/{owner}/{repo}/test.yml?branch=main)](https://github.com/{owner}/{repo}/actions) [![Coverage](https://img.shields.io/codecov/c/github/{owner}/{repo})](https://codecov.io/gh/{owner}/{repo}) [![Go Report Card](https://goreportcard.com/badge/github.com/{owner}/{repo})](https://goreportcard.com/report/github.com/{owner}/{repo}) [![Go Reference](https://pkg.go.dev/badge/github.com/{owner}/{repo}.svg)](https://pkg.go.dev/github.com/{owner}/{repo})

For the full README guidance and application-specific sections, see Project Docs.

Step 5: CONTRIBUTING & Changelog

CONTRIBUTING.md — Help contributors get started in under 10 minutes. Include: prerequisites, clone, build, test, PR process. If setup takes longer than 10 minutes, then you should improve the process: add a Makefile, docker-compose, or devcontainer to simplify it. See Project Docs.

Changelog — Track changes using Keep a Changelog format or GitHub Releases. Copy the template from templates/CHANGELOG.md. Each entry answers what changed for the reader — internal refactors without user-visible impact belong in commit history. Don't inflate a fixed edge case into a broad "reliability improvement" claim. See Project Docs.

Step 6: Library-Specific Documentation

For Go libraries, add these on top of the basics:

  • Go Playground demos — create runnable demos and link them in doc comments with // Play: https://go.dev/play/p/xxx. Use the go-playground MCP tool when available to create and share playground URLs.
  • Example test functions — write func ExampleXxx() in _test.go files. These are executable documentation verified by go test.
  • Generous code examples — include multiple examples in doc comments showing common use cases.
  • godoc — your doc comments render on pkg.go.dev. Use go doc locally to preview; to inspect how a published package renders its docs, symbols, and examples, → See samber/cc-skills-golang@golang-pkg-go-dev skill.
  • Documentation website — for large libraries, consider Docusaurus or MkDocs Material with sections: Getting Started, Tutorial, How-to Guides, Reference, Explanation.
  • Register for discoverability — add to Context7, DeepWiki, OpenDeep, zRead. Even for private libraries.

See Library Documentation for details.

Step 7: Application-Specific Documentation

For Go applications/CLIs:

  • Installation methods — pre-built binaries (GoReleaser), go install, Docker images, Homebrew...
  • CLI help text — make --help comprehensive; it's the primary documentation
  • Configuration docs — document all env vars, config files, CLI flags

See Application Documentation for details.

Step 8: API Documentation

If your project exposes an API:

API StyleFormatTool
REST/HTTPOpenAPI 3.xswaggo/swag (auto-generate from annotations)
Event-drivenAsyncAPIManual or code-gen
gRPCProtobufbuf, grpc-gateway

Prefer auto-generation from code annotations when possible. See Application Documentation for details.

Step 9: AI-Friendly Documentation

Make your project consumable by AI agents:

  • llms.txt — add a llms.txt file at the repository root. Copy the template from templates/llms.txt. This file gives LLMs a structured overview of your project.
  • Structured formats — use OpenAPI, AsyncAPI, or protobuf for machine-readable API docs.
  • Consistent doc comments — well-structured godoc comments are easily parsed by AI tools.
  • Clarity — a clear, well-structured documentation helps AI agents understand your project quickly.

Step 10: Delivery Documentation

Document how users get your project:

Libraries:

go get github.com/{owner}/{repo}

Applications:

# Pre-built binary
curl -sSL https://github.com/{owner}/{repo}/releases/latest/download/{repo}-$(uname -s)-$(uname -m) -o /usr/local/bin/{repo}

# From source
go install github.com/{owner}/{repo}@latest

# Docker
docker pull {registry}/{owner}/{repo}:latest

See Project Docs for Dockerfile best practices and Homebrew tap setup.

附带文件

assets/templates/CHANGELOG.md
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- Arabic translation (#21).

### Changed

- Improve French translation (#42).

### Deprecated

### Removed

### Fixed

- Fix missing logo in home page

### Security

### Other (dependencies, CI, tools...)

## [1.0.0] - YYYY-MM-DD

### Added

- Initial release

[Unreleased]: https://github.com/{owner}/{repo}/compare/v1.0.0...HEAD
[1.0.0]: https://github.com/{owner}/{repo}/releases/tag/v1.0.0
assets/templates/CONTRIBUTING.md
# Contributing to {project-name}

Thank you for your interest in contributing!

## Prerequisites

- Go {version} or later
- Make (optional but recommended)
- Docker (for integration tests only)

## Quick Start

```bash
# Clone the repository
git clone https://github.com/{owner}/{repo}.git
cd {repo}

# Build
go build -o myapp ./cmd/main.go

# Run unit tests
go test -race ./...

# Run integration tests
go test -race -tags=integration -timeout=300s ./...

# Run linter
golangci-lint run --fix ./...
```

## Development Workflow

1. Fork the repository
2. Create a feature branch: `git checkout -b feat/my-feature`
3. Make your changes
4. Add tests for new functionality
5. Run `go test ./...` and `golangci-lint run`
6. Commit with a descriptive message
7. Push and open a Pull Request

## Code Guidelines

- Follow [Effective Go](https://go.dev/doc/effective_go)
- Add doc comments to all exported symbols
- Write table-driven tests
- Keep test coverage above {X}%

## Reporting Issues

Use [GitHub Issues](https://github.com/{owner}/{repo}/issues). Include:

- Go version (`go version`)
- OS and architecture
- Steps to reproduce
- Expected vs actual behavior
assets/templates/llms.txt
# {project-name}

> {One-line description of the project}

## Overview

{2-3 sentences explaining what this project does, what problem it solves, and who it's for.}

## Quick Start

```bash
go get github.com/{owner}/{repo}
```

```go
package main

import "github.com/{owner}/{repo}"

func main() {
    // Minimal working example
}
```

## Key Concepts

- **{Concept 1}**: {Brief explanation}
- **{Concept 2}**: {Brief explanation}
- **{Concept 3}**: {Brief explanation}

## API Reference

### Core Functions

- `FuncName(params) returns` - {What it does and when to use it}
- `AnotherFunc(params) returns` - {What it does and when to use it}

### Core Types

- `TypeName` - {What it represents}
- `AnotherType` - {What it represents}

## Common Patterns

### {Pattern 1 Name}

```go
// Example code showing this pattern
```

### {Pattern 2 Name}

```go
// Example code showing this pattern
```

## Error Handling

- `ErrName` - {When this error occurs and how to handle it}
- `ErrAnother` - {When this error occurs and how to handle it}

## References

- Documentation: {URL}
- Repository: https://github.com/{owner}/{repo}
- Go Reference: https://pkg.go.dev/github.com/{owner}/{repo}
- Issues: https://github.com/{owner}/{repo}/issues
assets/templates/README.md
# {project-name}

<!-- Replace {owner} and {repo} throughout this file -->

[![Go Version](https://img.shields.io/github/go-mod/go-version/{owner}/{repo})](https://go.dev/) [![License](https://img.shields.io/github/license/{owner}/{repo})](./LICENSE) [![Build Status](https://img.shields.io/github/actions/workflow/status/{owner}/{repo}/test.yml?branch=main)](https://github.com/{owner}/{repo}/actions) [![Coverage](https://img.shields.io/codecov/c/github/{owner}/{repo})](https://codecov.io/gh/{owner}/{repo}) [![Go Report Card](https://goreportcard.com/badge/github.com/{owner}/{repo})](https://goreportcard.com/report/github.com/{owner}/{repo}) [![Go Reference](https://pkg.go.dev/badge/github.com/{owner}/{repo}.svg)](https://pkg.go.dev/github.com/{owner}/{repo})

<!-- Additional badges (pick what's relevant):
[![Release](https://img.shields.io/github/v/release/{owner}/{repo})](https://github.com/{owner}/{repo}/releases)
[![Downloads](https://img.shields.io/github/downloads/{owner}/{repo}/total)](https://github.com/{owner}/{repo}/releases)
[![Docker Pulls](https://img.shields.io/docker/pulls/{owner}/{repo})](https://hub.docker.com/r/{owner}/{repo})
-->

<!-- 1-2 sentences: what does this project do and who is it for? -->

<!-- Show the project in action: code snippet, GIF, screenshot, or video.
     For libraries: show a minimal working code example.
     For CLIs/tools: a GIF or screenshot is often more effective. -->

```go
// Minimal working example showing the most common use case
```

## 🚀 Getting Started

<!-- For libraries: -->

```bash
go get github.com/{owner}/{repo}
```

```go
package main

import "github.com/{owner}/{repo}"

func main() {
    // Minimal working example
}
```

<!-- For applications, uncomment and use this instead:

### Pre-built binaries

Download from [GitHub Releases](https://github.com/{owner}/{repo}/releases/latest).

| Platform | Architecture | Download                                                                                        |
| -------- | ------------ | ----------------------------------------------------------------------------------------------- |
| Linux    | amd64        | [Download](https://github.com/{owner}/{repo}/releases/latest/download/{repo}-linux-amd64)       |
| Linux    | arm64        | [Download](https://github.com/{owner}/{repo}/releases/latest/download/{repo}-linux-arm64)       |
| macOS    | amd64        | [Download](https://github.com/{owner}/{repo}/releases/latest/download/{repo}-darwin-amd64)      |
| macOS    | arm64        | [Download](https://github.com/{owner}/{repo}/releases/latest/download/{repo}-darwin-arm64)      |
| Windows  | amd64        | [Download](https://github.com/{owner}/{repo}/releases/latest/download/{repo}-windows-amd64.exe) |

### From source

```bash
go install github.com/{owner}/{repo}@latest
```

### Docker

```bash
docker pull {registry}/{owner}/{repo}:latest
docker run --rm {registry}/{owner}/{repo}:latest --help
```

### Homebrew (macOS)

```bash
brew install {owner}/{repo}
```

### APT (debian/ubuntu)

```bash
apt install {package}
```

-->

## ✨ Features

<!-- Very detailed feature descriptions, organized by area.
     This is the longest section of the README.
     Use headings, tables, and code examples generously. -->

### Feature Area 1

<!-- Description with code examples -->

### Feature Area 2

<!-- Description with code examples -->

## 🤝 Contributing

Please read the [contributing guide](CONTRIBUTING.md) before submitting a PR.

<!-- Or if the contributing guide is very short:

```bash
# Build
go build -o myapp ./cmd/main.go

# Run unit tests
go test -race ./...

# Run integration tests
go test -race -tags=integration -timeout=300s ./...

# Run linter
golangci-lint run --fix ./...
-->

## 📄 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
evals/evals.json
{
  "skill_name": "golang-documentation",
  "evals": [
    {
      "id": 1,
      "name": "readme-section-order",
      "prompt": "Write a README.md for a Go library called `github.com/acme/taskflow` that provides a DAG-based task execution engine. It supports parallel execution, dependency resolution, cycle detection, and retry policies. Include installation instructions, a usage example, license info, and any other sections you think are appropriate for a Go open-source library.",
      "trap": "Model will produce a reasonable README but likely not follow the exact section order: Title > Badges > Summary > Demo > Getting Started > Features > Contributing > License",
      "assertions": [
        { "id": "1.1", "text": "Badges section appears immediately after the title heading, before any prose" },
        { "id": "1.2", "text": "A short summary (1-2 sentences) appears after badges, before any code block or Getting Started section" },
        { "id": "1.3", "text": "A demo/example code snippet appears before the Getting Started/Installation section" },
        { "id": "1.4", "text": "Getting Started section with `go get` appears after the demo and before Features" },
        { "id": "1.5", "text": "Features section is the longest section, appearing after Getting Started" }
      ]
    },
    {
      "id": 2,
      "name": "scrambled-readme-reorder",
      "prompt": "I wrote a README for my Go library `github.com/acme/ratelimit` but my team says the sections are in the wrong order. Can you reorganize it following Go open-source best practices? Keep the content, just fix the order:\n\n```markdown\n# ratelimit\n\n## Getting Started\n```bash\ngo get github.com/acme/ratelimit\n```\n\n## Features\n- Token bucket algorithm\n- Redis backend support\n- Per-key rate limiting\n- Middleware for net/http\n\nA high-performance, distributed rate limiter for Go applications.\n\n## License\nMIT License - see LICENSE file.\n\n[![Build Status](https://img.shields.io/github/actions/workflow/status/acme/ratelimit/test.yml)](https://github.com/acme/ratelimit/actions)\n\n## Contributing\nSee CONTRIBUTING.md\n\n```go\nlimiter := ratelimit.New(ratelimit.WithRate(100, time.Second))\nif limiter.Allow(\"user-123\") {\n    // process request\n}\n```\n```\n",
      "trap": "The README has sections in wrong order: Getting Started > Features > Summary (unlabeled) > License > Badges (unlabeled) > Contributing > Demo (unlabeled). Without skill the model might rearrange reasonably but miss the exact prescribed order or miss that Summary/Badges/Demo need their own placement",
      "assertions": [
        { "id": "2.1", "text": "Badges appear immediately after the title, before the summary text" },
        { "id": "2.2", "text": "The summary sentence ('A high-performance...') appears after badges, before the demo code" },
        { "id": "2.3", "text": "The demo code snippet (limiter := ...) appears before the Getting Started section" },
        { "id": "2.4", "text": "Getting Started appears after demo and before Features" },
        { "id": "2.5", "text": "Contributing and License appear at the end, after Features" }
      ]
    },
    {
      "id": 3,
      "name": "doc-comment-why-not-what",
      "prompt": "Write a godoc comment for this Go function. Make it comprehensive:\n\n```go\nfunc Merge(dst, src map[string]interface{}, overwrite bool) map[string]interface{} {\n    if dst == nil {\n        dst = make(map[string]interface{})\n    }\n    for k, v := range src {\n        if _, exists := dst[k]; !exists || overwrite {\n            dst[k] = v\n        }\n    }\n    return dst\n}\n```",
      "trap": "Model might just restate: 'Merge merges two maps'. Skill teaches why/when/constraints, Parameters section, Returns section, error cases",
      "assertions": [
        { "id": "3.1", "text": "Comment starts with 'Merge' followed by a verb phrase (godoc convention)" },
        { "id": "3.2", "text": "Includes a Parameters section listing dst, src, and overwrite with descriptions" },
        { "id": "3.3", "text": "Explains the overwrite behavior (when true vs false)" },
        { "id": "3.4", "text": "Documents nil dst handling (creates new map)" },
        { "id": "3.5", "text": "Includes an inline code Example section showing usage" }
      ]
    },
    {
      "id": 4,
      "name": "small-package-no-doc-go",
      "prompt": "I have a Go package with 2 files: `handler.go` and `middleware.go`. My teammate suggests I should create a `doc.go` file for the package-level documentation comment. Is that the right approach? Where should I put the package comment?",
      "trap": "Model without skill might agree to create doc.go (it's a common pattern). Skill teaches: doc.go is for packages with 3+ files; for small packages, put the comment at the top of the main .go file",
      "assertions": [
        { "id": "4.1", "text": "Advises AGAINST creating doc.go for a 2-file package" },
        { "id": "4.2", "text": "Recommends placing the package comment at the top of the main .go file (handler.go)" },
        { "id": "4.3", "text": "Mentions the 3+ files threshold for when doc.go becomes appropriate" },
        { "id": "4.4", "text": "Shows the `// Package ... ` format starting with the Package keyword" },
        { "id": "4.5", "text": "Explains that doc.go is for larger packages where no single file is the obvious home" }
      ]
    },
    {
      "id": 5,
      "name": "example-test-naming",
      "prompt": "Write Example test functions for this Go library function that converts temperatures. I need examples for: basic Celsius to Fahrenheit, Fahrenheit to Celsius, and Kelvin to Celsius conversions.\n\n```go\npackage tempconv\n\n// Convert converts a temperature from one unit to another.\nfunc Convert(value float64, from, to Unit) float64 { ... }\n```",
      "trap": "Model might name multiple examples as ExampleConvert1/ExampleConvert2 or ExampleConvertCelsiusToFahrenheit (capitalized suffix). Skill teaches lowercase suffix convention.",
      "assertions": [
        { "id": "5.1", "text": "Uses external test package (package tempconv_test)" },
        { "id": "5.2", "text": "Multiple examples use lowercase suffix: ExampleConvert_celsiusToFahrenheit or similar lowercase pattern" },
        { "id": "5.3", "text": "Every example includes an // Output: comment for go test verification" },
        { "id": "5.4", "text": "Examples use fmt.Println to print results (not fmt.Printf)" },
        { "id": "5.5", "text": "Examples import the package and call tempconv.Convert (external test package pattern)" }
      ]
    },
    {
      "id": 6,
      "name": "contributing-10min-rule",
      "prompt": "Write a CONTRIBUTING.md for a Go project that requires: PostgreSQL 15, Redis 7, Elasticsearch 8, Go 1.22+, and protoc for gRPC code generation. The test suite takes about 3 minutes to run. Building requires running `protoc` first, then `go generate`, then `go build`.",
      "trap": "Complex setup with 5 dependencies. Model might just list prerequisites. Skill teaches the 10-minute rule and suggests Makefile, docker-compose, devcontainer",
      "assertions": [
        { "id": "6.1", "text": "Includes a Makefile or mentions make targets (make build, make test, make lint)" },
        { "id": "6.2", "text": "Includes docker-compose.yml for running PostgreSQL, Redis, and Elasticsearch locally" },
        { "id": "6.3", "text": "Provides a Quick Start section showing clone-to-running-tests in a few commands" },
        { "id": "6.4", "text": "Mentions or provides devcontainer configuration for consistent environments" },
        { "id": "6.5", "text": "Separates unit tests (fast, no deps) from integration tests (needs services)" }
      ]
    },
    {
      "id": 7,
      "name": "security-fix-miscategorized",
      "prompt": "We use Keep a Changelog format. A junior developer wrote this CHANGELOG entry for our new release. Is it correct?\n\n```markdown\n## [2.3.0] - 2026-04-10\n\n### Added\n- New streaming API for large file transfers\n- Support for HTTP/3\n\n### Fixed\n- Null pointer dereference when config is missing\n- Deserialization flaw allowing arbitrary code execution via malformed input (GHSA-xxxx-yyyy-zzzz)\n- Off-by-one error in retry backoff calculation\n\n### Changed\n- Connection pool default size increased to 50\n```",
      "trap": "The GHSA vulnerability is listed under Fixed. Per Keep a Changelog format, security fixes belong in a dedicated ### Security section. A model without skill knowledge treats all bug fixes as Fixed and has no reason to split them. The model must know that Keep a Changelog defines Security as its own top-level category.",
      "assertions": [
        { "id": "7.1", "text": "Identifies that the GHSA/deserialization fix belongs in a dedicated ### Security section, not ### Fixed" },
        { "id": "7.2", "text": "Recommends creating a ### Security subsection that is separate from ### Fixed" },
        { "id": "7.3", "text": "Keeps the null pointer and off-by-one fixes under ### Fixed — they are bugs, not vulnerabilities" },
        { "id": "7.4", "text": "Does not move non-security bugs into the Security section" },
        { "id": "7.5", "text": "Notes that the Security category exists as its own top-level changelog category, not a subcategory of Fixed" }
      ]
    },
    {
      "id": 8,
      "name": "llms-txt",
      "prompt": "I have a Go library `github.com/acme/querybuilder` that provides a type-safe SQL query builder. It has these main types: Builder, Query, Condition, JoinClause. Main functions: New(), Select(), Insert(), Update(), Delete(). Errors: ErrInvalidColumn, ErrMissingTable. I want to make my library more accessible to AI coding assistants. What should I do and can you create any needed files?",
      "trap": "Model without skill won't know about llms.txt convention. Might suggest better README or doc comments only.",
      "assertions": [
        { "id": "8.1", "text": "Creates or recommends creating an llms.txt file at the repository root" },
        { "id": "8.2", "text": "llms.txt includes an Overview section explaining what the library does" },
        { "id": "8.3", "text": "llms.txt includes Key Concepts or API Reference listing the main types and functions" },
        { "id": "8.4", "text": "llms.txt includes Common Patterns section with code examples" },
        { "id": "8.5", "text": "Mentions registering for discoverability platforms (Context7, DeepWiki, or similar)" }
      ]
    },
    {
      "id": 9,
      "name": "brief-doc-comment-trap",
      "prompt": "Write a brief, one-line doc comment for this exported Go function. Keep it short — I don't want verbose documentation cluttering the code:\n\n```go\npackage retry\n\nfunc Do(ctx context.Context, maxAttempts int, delay time.Duration, backoff float64, fn func() error) error {\n    var lastErr error\n    for i := 0; i < maxAttempts; i++ {\n        if err := fn(); err != nil {\n            lastErr = err\n            select {\n            case <-ctx.Done():\n                return ctx.Err()\n            case <-time.After(delay):\n                delay = time.Duration(float64(delay) * backoff)\n            }\n            continue\n        }\n        return nil\n    }\n    return lastErr\n}\n```",
      "trap": "User explicitly asks for 'brief, one-line'. Without skill, model complies and writes a minimal one-liner. With skill, the model should STILL write a comprehensive comment because the skill says every exported function MUST have a doc comment with Parameters, Returns, and Example sections",
      "assertions": [
        { "id": "9.1", "text": "Comment starts with 'Do' followed by a verb phrase (godoc convention)" },
        { "id": "9.2", "text": "Includes a Parameters section or describes each parameter (ctx, maxAttempts, delay, backoff, fn)" },
        { "id": "9.3", "text": "Documents the exponential backoff behavior (delay multiplied by backoff factor)" },
        { "id": "9.4", "text": "Documents context cancellation behavior (returns ctx.Err())" },
        { "id": "9.5", "text": "Includes an inline Example section showing a realistic usage pattern" }
      ]
    },
    {
      "id": 10,
      "name": "review-restating-comments",
      "prompt": "Review these doc comments. My team says our documentation is solid. Do you see any issues?\n\n```go\npackage cache\n\n// Get gets a value from the cache by key.\n// Returns the value and true if found, zero value and false if not.\nfunc (c *Cache) Get(key string) (interface{}, bool) { ... }\n\n// Set sets a value in the cache for the given key.\nfunc (c *Cache) Set(key string, value interface{}) { ... }\n\n// Delete deletes a value from the cache by key.\nfunc (c *Cache) Delete(key string) { ... }\n\n// Size returns the number of items currently in the cache.\nfunc (c *Cache) Size() int { ... }\n\n// Clear clears all items from the cache.\nfunc (c *Cache) Clear() { ... }\n```",
      "trap": "Team says docs are 'solid', creating social pressure to agree. All comments describe what the code does but not why/when/constraints — they omit thread safety, TTL/eviction behavior, and cache miss semantics. The skill requires comments to explain WHY and WHEN, not just WHAT.",
      "assertions": [
        { "id": "10.1", "text": "Identifies that the comments describe WHAT the code does but fail to explain WHY, WHEN, or any constraints" },
        { "id": "10.2", "text": "Points out that Get is missing thread-safety documentation (is it safe for concurrent use?)" },
        { "id": "10.3", "text": "Points out that Set is missing documentation on what happens if the key already exists and whether there is a TTL or capacity limit" },
        { "id": "10.4", "text": "Rewrites at least one comment to include constraints, edge cases, or concurrent-use guarantees" },
        { "id": "10.5", "text": "Does NOT simply agree that the docs are solid without identifying the missing context" }
      ]
    },
    {
      "id": 11,
      "name": "skip-test-func-comments",
      "prompt": "I'm adding doc comments to every function in my Go project to reach 100% documentation coverage. Please add appropriate doc comments to these test functions:\n\n```go\npackage auth_test\n\nfunc TestValidateToken(t *testing.T) { ... }\nfunc TestValidateToken_expired(t *testing.T) { ... }\nfunc TestValidateToken_invalidSignature(t *testing.T) { ... }\nfunc BenchmarkValidateToken(b *testing.B) { ... }\nfunc TestHashPassword(t *testing.T) { ... }\nfunc TestComparePassword(t *testing.T) { ... }\n```",
      "trap": "User explicitly asks to add doc comments to test functions citing '100% documentation coverage'. Without skill, model complies and writes comments for each test. The skill's 'What to Document' table explicitly says 'Test functions: No' and the model should push back on this request.",
      "assertions": [
        { "id": "11.1", "text": "Advises against or actively discourages adding doc comments to test functions" },
        { "id": "11.2", "text": "Explains that test function names are designed to be self-descriptive — the name IS the documentation" },
        { "id": "11.3", "text": "Does NOT produce doc comments for any of the standard Test/Benchmark functions listed" },
        { "id": "11.4", "text": "Clarifies that '100% documentation coverage' tools do not count unexported or test functions — this goal does not apply here" },
        { "id": "11.5", "text": "May suggest that complex test setup helpers warrant comments, but not the standard TestXxx/BenchmarkXxx functions themselves" }
      ]
    },
    {
      "id": 12,
      "name": "simple-crud-no-file-desc",
      "prompt": "I have a Go file `user_handler.go` (120 lines) that contains standard CRUD HTTP handlers for a User resource: CreateUser, GetUser, UpdateUser, DeleteUser, and ListUsers. Each handler does basic JSON decode, calls a service, and returns a JSON response. Should I add a file-level description comment with an architecture diagram like I did for my scheduler file?",
      "trap": "User references having added a file description to a complex scheduler file and wants to do the same for a simple CRUD handler. Without skill, model might agree or add unnecessary documentation. With skill, model should say NO — simple CRUD handlers don't warrant file-level descriptions per the 'When to Add File Descriptions' table",
      "assertions": [
        { "id": "12.1", "text": "Advises against adding a file-level description for this CRUD handler" },
        { "id": "12.2", "text": "Explains that simple CRUD handlers don't warrant the same treatment as complex algorithms" },
        { "id": "12.3", "text": "Distinguishes between when file descriptions ARE needed (algorithms, state machines, 200+ lines of complex logic) vs not needed (CRUD, data models)" },
        { "id": "12.4", "text": "Still recommends good doc comments on the individual exported handler functions" },
        { "id": "12.5", "text": "Does NOT produce an ASCII art diagram or elaborate file-level description" }
      ]
    },
    {
      "id": 13,
      "name": "file-level-description",
      "prompt": "I have a Go file `scheduler.go` that implements a priority-queue-based task scheduler using container/heap. It supports recurring tasks, one-shot tasks, task cancellation, and graceful shutdown with a drain timeout. A single dispatcher goroutine polls the heap. The file is 350 lines. Should I add any special documentation to this file, and if so, what?",
      "trap": "Model might just say 'add function comments'. Skill teaches file-level description with ASCII art architecture diagram for complex files",
      "assertions": [
        { "id": "13.1", "text": "Recommends a file-level description comment (not just function comments)" },
        { "id": "13.2", "text": "Suggests including an ASCII art diagram showing the scheduler architecture/flow" },
        { "id": "13.3", "text": "Places the file description below imports (not above package declaration)" },
        { "id": "13.4", "text": "Description explains the algorithm/design (priority queue, dispatcher goroutine)" },
        { "id": "13.5", "text": "Notes the 200+ line threshold or 'complex algorithm' as reason for adding the description" }
      ]
    },
    {
      "id": 14,
      "name": "grpc-api-docs",
      "prompt": "I have a Go gRPC service for user management. The proto file currently has no comments at all. A teammate says I should use swaggo/swag since we already use it for our REST API. What's the right way to document a gRPC API?",
      "trap": "Teammate explicitly suggests swaggo/swag for gRPC. The model must know that swaggo/swag generates OpenAPI from Go HTTP annotations — it has no concept of protobufs. Without skill knowledge, the model might go along with the suggestion or give a vague answer. With skill, the model knows proto files are the source of truth and buf is the right tool.",
      "assertions": [
        { "id": "14.1", "text": "Clearly states that swaggo/swag is NOT the right tool for gRPC — it generates OpenAPI for REST APIs, not protobuf documentation" },
        { "id": "14.2", "text": "States that proto files themselves serve as the API contract AND documentation — add comments there" },
        { "id": "14.3", "text": "Recommends adding comments directly to proto messages, services, and RPCs" },
        { "id": "14.4", "text": "Recommends buf for proto linting and breaking change detection" },
        { "id": "14.5", "text": "Mentions grpc-gateway as an option for projects needing both REST and gRPC from the same proto" }
      ]
    },
    {
      "id": 15,
      "name": "app-disguised-as-library",
      "prompt": "I'm building a Go project at `github.com/acme/datactl`. The project structure is:\n```\ncmd/\n  datactl/\n    main.go\ninternal/\n  ingester/\n  transformer/\n  exporter/\npkg/\n  config/\n  client/\ngo.mod\n```\nThe `pkg/` directory exports a client SDK that other teams import. The `cmd/` directory builds the CLI binary. What documentation strategy should I use? Should I write ExampleXxx tests and Playground demos for the exported packages?",
      "trap": "Project is BOTH a library (pkg/) AND an application (cmd/). Without skill, model might treat it as one or the other. With skill, model should detect both types and apply different documentation strategies: ExampleXxx for pkg/, CLI help + install methods for cmd/",
      "assertions": [
        { "id": "15.1", "text": "Identifies this as BOTH a library (pkg/) AND an application (cmd/) — not just one type" },
        { "id": "15.2", "text": "Recommends ExampleXxx test functions for the pkg/client and pkg/config packages (library part)" },
        { "id": "15.3", "text": "Recommends CLI --help text and multiple installation methods for the cmd/datactl binary (application part)" },
        { "id": "15.4", "text": "Recommends configuration documentation (env vars, config files, flags) for the CLI" },
        { "id": "15.5", "text": "Does NOT recommend Playground demos for internal/ packages (they are not importable by external users)" }
      ]
    },
    {
      "id": 16,
      "name": "existing-contributing-improve",
      "prompt": "Our Go project requires PostgreSQL and Redis. This is our current CONTRIBUTING.md. Improve it:\n\n```markdown\n# Contributing\n\n## Prerequisites\n- Go 1.22+\n- PostgreSQL 15\n- Redis 7\n\n## Setup\n1. Install Go from https://go.dev\n2. Install PostgreSQL from https://www.postgresql.org/download/\n3. Install Redis from https://redis.io/download/\n4. Create a database: `createdb myapp_test`\n5. Run `go build ./...`\n6. Run `go test ./...`\n\n## Pull Requests\nPlease open a PR against the main branch.\n```",
      "trap": "The existing CONTRIBUTING requires manual installation of PostgreSQL and Redis — time-consuming and error-prone. Without skill, model might polish the text or add small improvements. With skill, model should apply the 10-minute rule: replace manual installs with docker-compose, add Makefile, suggest devcontainer",
      "assertions": [
        { "id": "16.1", "text": "Adds docker-compose.yml to replace manual PostgreSQL and Redis installation" },
        { "id": "16.2", "text": "Adds a Makefile with targets (make build, make test, make lint, or similar)" },
        { "id": "16.3", "text": "Reduces the setup steps to 3 or fewer commands (e.g., clone, docker-compose up, make test)" },
        { "id": "16.4", "text": "Mentions or suggests devcontainer for consistent environments" },
        { "id": "16.5", "text": "Separates unit tests (fast, no deps) from integration tests (needs PostgreSQL/Redis)" }
      ]
    },
    {
      "id": 17,
      "name": "play-link-doc-comment",
      "prompt": "I maintain a public Go library. Write a comprehensive doc comment for this function. I need it to show up well on pkg.go.dev — include everything users need to understand it at a glance:\n\n```go\npackage sliceutil\n\nfunc Filter[T any](s []T, predicate func(T) bool) []T {\n    var result []T\n    for _, v := range s {\n        if predicate(v) {\n            result = append(result, v)\n        }\n    }\n    return result\n}\n```",
      "trap": "Model may write a thorough doc comment but omit the Play: line entirely — it's a niche convention the skill specifically teaches. The Play: line with its exact format (// Play: https://...) is a skill-specific pattern not commonly known.",
      "assertions": [
        { "id": "17.1", "text": "Includes a `// Play:` line with a URL pointing to a Go Playground demo" },
        { "id": "17.2", "text": "The Play: line uses the exact format `// Play: https://go.dev/play/p/...` (not inline, not as a different label)" },
        { "id": "17.3", "text": "Comment starts with 'Filter' followed by a verb phrase" },
        { "id": "17.4", "text": "Includes an inline code Example section (tab-indented)" },
        { "id": "17.5", "text": "Documents that a new slice is returned (original is not modified)" }
      ]
    },
    {
      "id": 18,
      "name": "architecture-decision-records",
      "prompt": "Our Go project has made several important architectural decisions: using PostgreSQL over MongoDB, choosing event-driven architecture with NATS, and using JWT for authentication. How should we document these decisions so future team members understand the rationale?",
      "trap": "Model might suggest a wiki page or a section in README. Skill teaches docs/architecture/ directory with numbered ADR files",
      "assertions": [
        { "id": "18.1", "text": "Recommends a docs/architecture/ directory (not wiki or README section)" },
        { "id": "18.2", "text": "Uses numbered file format (0001-xxx.md, 0002-xxx.md)" },
        { "id": "18.3", "text": "Each ADR has Context section explaining the need" },
        { "id": "18.4", "text": "Each ADR has Design/Decision section explaining what was chosen" },
        { "id": "18.5", "text": "Each ADR has Consequences section (positive and negative trade-offs)" }
      ]
    },
    {
      "id": 19,
      "name": "example-method-naming",
      "prompt": "Write Example test functions for this Go type and its methods. Cover: creating a new client, making a GET request, making a POST request with a body, and setting custom headers.\n\n```go\npackage httpclient\n\ntype Client struct { ... }\nfunc New(opts ...Option) *Client { ... }\nfunc (c *Client) Get(ctx context.Context, url string) (*Response, error) { ... }\nfunc (c *Client) Post(ctx context.Context, url string, body io.Reader) (*Response, error) { ... }\nfunc (c *Client) SetHeader(key, value string) { ... }\n```",
      "trap": "The method example naming convention (ExampleClient_Get, ExampleClient_Post) is less well known than the function convention. Without the skill, the model may write ExampleGetRequest, ExamplePost, ExampleClient_GetRequest (mixing conventions), or use capitalized suffixes. The exact pattern is TypeName_MethodName.",
      "assertions": [
        { "id": "19.1", "text": "Uses ExampleNew or ExampleClient for the constructor example — NOT ExampleNewClient (which stutters) or ExampleNew_client" },
        { "id": "19.2", "text": "Uses ExampleClient_Get for the GET request example (TypeName_MethodName convention with capital method name)" },
        { "id": "19.3", "text": "Uses ExampleClient_Post for the POST request example (same TypeName_MethodName pattern)" },
        { "id": "19.4", "text": "Every example includes an // Output: comment" },
        { "id": "19.5", "text": "Uses external test package (package httpclient_test)" }
      ]
    },
    {
      "id": 20,
      "name": "discoverability-registration",
      "prompt": "I just published my Go library on GitHub (public repo, MIT license, tagged v1.0.0). I have a good README, doc comments, ExampleXxx tests, and a CHANGELOG. What else should I do to make sure developers and AI tools can find and use my library?",
      "trap": "Model without skill knowledge of the specific platforms will give generic answers: 'share on social media', 'write a blog post', 'submit to HackerNews'. The skill teaches specific discoverability platforms: Context7, DeepWiki, OpenDeep, zRead — names the model won't know without the skill.",
      "assertions": [
        { "id": "20.1", "text": "Recommends registering with Context7 (context7.com) specifically for AI-accessible documentation" },
        { "id": "20.2", "text": "Recommends registering with DeepWiki (deepwiki.com) specifically" },
        { "id": "20.3", "text": "Recommends adding an llms.txt file at the repository root" },
        { "id": "20.4", "text": "Recommends adding Go Playground demos linked from doc comments with the // Play: format" },
        { "id": "20.5", "text": "Names at least 3 specific discoverability platforms (from: Context7, DeepWiki, OpenDeep, zRead) — not generic promotion advice" }
      ]
    },
    {
      "id": 21,
      "name": "deprecated-marker-format",
      "prompt": "I'm deprecating a function in my Go library. The old function is `ParseDuration` and the new replacement is `ParseDurationStrict`. Write the doc comment for the deprecated function. Also, I want to make sure automated tools and pkg.go.dev show it as deprecated correctly.",
      "trap": "Model might use a freeform deprecation notice (e.g., 'This function is deprecated, use X instead') instead of the specific godoc Deprecated: marker format that tools recognize. The exact format with 'Deprecated:' on its own paragraph line is required for godoc rendering and tooling detection",
      "assertions": [
        { "id": "21.1", "text": "Uses the exact 'Deprecated:' marker (capital D, colon, space) on its own comment paragraph line — this is the format godoc and tools recognize" },
        { "id": "21.2", "text": "Includes the replacement function name (ParseDurationStrict) after the Deprecated: marker" },
        { "id": "21.3", "text": "Mentions a version or timeline for removal (e.g., 'will be removed in v3.0.0')" }
      ]
    }
  ]
}
references/application.md
# Application Documentation

→ See `samber/cc-skills-golang@golang-cli` skill for CLI application patterns and frameworks.

## CLI Help Text

For CLI applications, `--help` output is the primary documentation. CLI tools MUST have comprehensive `--help` text:

```go
// Use cobra or similar framework for structured help text
var rootCmd = &cobra.Command{
    Use:   "mytool",
    Short: "A brief description of mytool",
    Long: `A longer description that explains the tool in detail.

mytool helps you do X, Y, and Z. It connects to your
database and performs analysis on the data.

Environment variables:
  MYTOOL_DB_URL    Database connection string (required)
  MYTOOL_LOG_LEVEL Log level: debug, info, warn, error (default: info)
  MYTOOL_TIMEOUT   Request timeout (default: 30s)`,
    Example: `  # Basic usage
  mytool analyze --input data.csv

  # With custom configuration
  mytool analyze --input data.csv --output report.json --format json

  # Using environment variables
  export MYTOOL_DB_URL="postgres://localhost/mydb"
  mytool serve`,
}
```

---

## Configuration Documentation

Configuration SHOULD be documented. Document all configuration sources in the README or a dedicated `docs/configuration.md`:

````markdown
## Configuration

Configuration is loaded in this order (later sources override earlier ones):

1. Default values
2. Configuration file (`~/.config/mytool/config.yaml`)
3. Environment variables
4. Command-line flags

### Environment Variables

| Variable           | Description                | Default | Required |
| ------------------ | -------------------------- | ------- | -------- |
| `MYTOOL_DB_URL`    | Database connection string | —       | Yes      |
| `MYTOOL_LOG_LEVEL` | Log verbosity              | `info`  | No       |
| `MYTOOL_PORT`      | HTTP server port           | `8080`  | No       |
| `MYTOOL_TIMEOUT`   | Request timeout            | `30s`   | No       |

### Configuration File

```yaml
# ~/.config/mytool/config.yaml
database:
  url: postgres://localhost/mydb
  max_connections: 25
server:
  port: 8080
  read_timeout: 30s
logging:
  level: info
  format: json
```
````

---

## Architecture & design decisions

For complex applications, document architectural decisions in `docs/architecture/`:

```
docs/
  architecture/
    0001-use-postgres-as-primary-store.md
    0002-event-driven-architecture.md
    0003-jwt-for-authentication.md
    README.md
```

Each design document follows a standard format:

```markdown
# Use PostgreSQL as Primary Store

## Context

We need a persistent data store that supports...

## Design

We use PostgreSQL because...

## Consequences

- Positive: ACID transactions, rich query language...
- Negative: Operational overhead, connection management...
```

---

## API Documentation

### REST APIs — OpenAPI / Swagger

Use [swaggo/swag](https://github.com/swaggo/swag) to auto-generate OpenAPI docs from Go annotations:

```go
// @Summary Get user by ID
// @Description Returns a single user
// @Tags users
// @Accept json
// @Produce json
// @Param id path int true "User ID"
// @Success 200 {object} User
// @Failure 404 {object} ErrorResponse
// @Failure 500 {object} ErrorResponse
// @Router /users/{id} [get]
func GetUser(w http.ResponseWriter, r *http.Request) {
```

Generate the spec:

```bash
go get -tool github.com/swaggo/swag/cmd/swag@latest
go tool swag init -g cmd/server/main.go -o docs/swagger
```

This produces `docs/swagger/swagger.json` and `docs/swagger/swagger.yaml`. Serve with Swagger UI or Redoc.

### Event-Driven — AsyncAPI

For message-based APIs (Kafka, NATS, RabbitMQ), use [AsyncAPI](https://www.asyncapi.com/):

```yaml
asyncapi: "2.6.0"
info:
  title: Order Events
  version: "1.0.0"
channels:
  orders/created:
    publish:
      message:
        payload:
          type: object
          properties:
            orderId:
              type: string
            amount:
              type: number
```

### gRPC — Protobuf

Protobuf files serve as both code contracts and documentation. Add comments to messages and RPCs:

```protobuf
syntax = "proto3";

// UserService manages user accounts.
service UserService {
  // GetUser retrieves a user by their unique identifier.
  // Returns NOT_FOUND if the user does not exist.
  rpc GetUser(GetUserRequest) returns (User);

  // CreateUser registers a new user account.
  // Returns ALREADY_EXISTS if the email is taken.
  rpc CreateUser(CreateUserRequest) returns (User);
}

// User represents a registered user account.
message User {
  // Unique identifier for the user (UUID v4).
  string id = 1;
  // User's display name (1-100 characters).
  string name = 2;
  // User's email address (must be unique across all users).
  string email = 3;
}
```

Use [buf](https://buf.build/) for linting and breaking change detection:

```bash
buf lint
buf breaking --against '.git#branch=main'
```

For REST+gRPC, use [grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway) to serve both from the same protobuf definition.

### When to Use Each Format

| API Style | Format | Auto-generation |
| --- | --- | --- |
| REST/HTTP with Go handlers | OpenAPI 3.x | swaggo/swag from annotations |
| REST/HTTP with framework | OpenAPI 3.x | Framework-specific (e.g., huma) |
| gRPC services | Protobuf | Proto files are the source of truth |
| gRPC + REST gateway | Protobuf + OpenAPI | grpc-gateway generates OpenAPI |
| Message queues / events | AsyncAPI | Manual or code-gen |
| GraphQL | SDL schema | Schema is the docs |
references/code-comments.md
# Code Comments

→ See `samber/cc-skills-golang@golang-naming` skill for naming conventions that reduce the need for comments.

## Function & Method Doc Comments

### Why, Not What

The most common mistake in doc comments is restating the code. The code already tells the reader _what_ happens — comments SHOULD explain why, not what:

- **Why** this function exists (its purpose in the system)
- **When** to use it (and when not to)
- **What constraints** apply (preconditions, thread safety, performance)
- **What can go wrong** (error cases, panics, edge cases)

Bad — restates the code:

```go
// GetUser gets a user by ID.
func GetUser(id string) (*User, error) {
```

Good — explains why, when, and what can go wrong:

```go
// GetUser retrieves a user from the database by their unique identifier.
// Use this for authenticated endpoints where you need the full user profile.
// For listing or searching, use ListUsers instead — it returns lighter projections.
//
// Returns ErrNotFound if no user exists with the given ID.
// Returns ErrDatabaseUnavailable if the connection pool is exhausted.
func GetUser(id string) (*User, error) {
```

### Anti-Patterns to Remove on Sight

| Anti-pattern | Example | Fix |
| --- | --- | --- |
| Pure paraphrase | `// GetUser gets a user` on `func GetUser()` — starts with the name (required by godoc) but adds nothing | After the name, add _when_ to use it, constraints, and what can go wrong |
| Signature restatement | `// Returns a string and an error` | Document _which_ error and _why_ — the signature already shows types |
| Marketing vocabulary | `seamlessly`, `powerful`, `robust`, `enterprise-grade` | Remove — state facts instead |
| Invented rationale | `// designed to improve scalability` | Only document what the code actually does |
| Groundless future claims | `// supports future extensibility` | Remove or back it with an interface or configuration |
| Hollow filler | `// It's worth noting that...`, `// As mentioned above` | Cut — restate the fact directly if it matters |

### Format

Every doc comment MUST start with the function/method name followed by a verb phrase. This is how godoc renders it in package indexes.

```go
// FuncName verb-phrase describing what it does.
```

### Full Comment Template

Use this structure for exported functions and complex internal functions. Omit sections that don't apply (e.g., no Parameters section for zero-arg functions). Focus on the "why" — don't restate what the code already makes obvious:

```go
// FuncName summarizes what this function does in one sentence.
// Additional context explaining behavior, algorithms, or design decisions
// that callers need to know.
//
// Parameters:
//   - paramName: description of what this parameter represents
//   - anotherParam: description with valid ranges or constraints
//
// Returns description of the return value(s).
// Returns ErrSomething if [condition].
// Returns ErrAnother if [different condition].
//
// Panics if [condition] (only document if the function can panic).
//
// It is safe for concurrent use (or: It is NOT safe for concurrent use).
//
// Play: https://go.dev/play/p/xxxxx
//
// Example:
//
//	result, err := pkg.FuncName(arg1, arg2)
//	if err != nil {
//	    log.Fatal(err)
//	}
//	fmt.Println(result)
func FuncName(paramName Type, anotherParam Type) (ResultType, error) {
```

### What to Document

| Element | Document? |
| --- | --- |
| Exported functions/methods | Always |
| Exported types and interfaces | Always |
| Exported constants and variables | Always |
| Complex internal functions | Yes — algorithms, non-obvious logic |
| Simple internal helpers | Optional — only if the name isn't self-explanatory |
| Test functions | No |
| Getters/setters with no logic | Brief one-liner is enough |

`TODO` comments SHOULD include a tracking issue reference when one exists (e.g., `// TODO(#123): ...`). For informal notes, `// TODO(username): ...` or plain `// TODO: ...` is acceptable.

### Error Cases and Limitations

Document every error a function can return, and any edge cases or limitations:

```go
// Parse parses a duration string such as "300ms", "1.5h", or "2h45m".
//
// Parameters:
//   - s: A duration string. Valid time units are "ns", "us", "ms", "s", "m", "h".
//
// Returns the parsed duration.
// Returns ErrInvalidDuration if the string is empty or has an invalid format.
// Returns ErrOverflow if the duration exceeds math.MaxInt64 nanoseconds.
//
// Limitations:
//   - Does not support day, week, month, or year units.
//   - Precision is limited to nanoseconds.
func Parse(s string) (time.Duration, error) {
```

### Deprecated Functions

Use the `Deprecated:` marker. godoc renders this with special styling:

```go
// OldFunc does something.
//
// Deprecated: Use NewFunc instead. OldFunc will be removed in v3.0.0.
func OldFunc() {}
```

### Interface Documentation

Document the interface itself and each method. Explain the contract that implementations must satisfy:

```go
// Store defines a persistent key-value storage backend.
// Implementations must be safe for concurrent use by multiple goroutines.
//
// All methods accept a context for cancellation and deadlines.
// Implementations should respect context cancellation and return
// ctx.Err() when the context is done.
type Store interface {
    // Get retrieves the value associated with key.
    // Returns ErrNotFound if the key does not exist.
    // Returns ErrExpired if the key exists but has expired.
    Get(ctx context.Context, key string) ([]byte, error)

    // Set stores a key-value pair with an optional TTL.
    // If ttl is 0, the entry does not expire.
    // Overwrites any existing value for the same key.
    Set(ctx context.Context, key string, value []byte, ttl time.Duration) error

    // Delete removes a key from the store.
    // Returns nil (not an error) if the key does not exist.
    Delete(ctx context.Context, key string) error
}
```

### Method Comments on Structs

```go
// Close gracefully shuts down the server.
// It waits for active connections to complete up to the configured timeout.
//
// Returns an error if the shutdown times out or if the server
// encounters an error while draining connections.
//
// Close is idempotent — calling it multiple times is safe.
// It is NOT safe to call Close concurrently from multiple goroutines.
func (s *Server) Close() error {
```

### Inline Code Examples in Comments

Indent code examples by one tab in doc comments. godoc renders these as formatted code blocks:

```go
// Transform applies a function to each element of a slice and returns
// a new slice with the results.
//
// Example:
//
//	names := []string{"alice", "bob"}
//	upper := Transform(names, strings.ToUpper)
//	// upper: ["ALICE", "BOB"]
func Transform[T any, U any](slice []T, fn func(T) U) []U {
```

### Playground Links

Add a `Play:` line linking to a runnable Go Playground example of a public library. Use the samber/go-playground-mcp tool to create and share playground URLs when available:

```go
// Map applies a function to each element of a slice.
//
// Play: https://go.dev/play/p/abc123xyz
//
// Example:
//
//	  doubled := Map([]int{1, 2, 3}, func(x int) int { return x * 2 })
//	  // doubled: [2, 4, 6]
func Map[T any, U any](s []T, fn func(T) U) []U {
```

---

## File & Package Comments

### Package Comment

Every package should have a doc comment. Place it in one of these locations:

1. **At the top of the main `.go` file** — for small packages with one or two files
2. **In a dedicated `doc.go` file** — for packages with many files

```go
// Package httputil provides HTTP utility functions for request parsing,
// response writing, and middleware chaining.
//
// It is designed to work with the standard net/http package and does not
// depend on any specific HTTP framework.
package httputil
```

Use `doc.go` when the package has 3+ files or the package comment is longer than ~10 lines:

```go
// Package auth implements authentication and authorization for the API server.
//
// # Architecture
//
// The package uses a middleware-based approach where each authentication
// strategy (JWT, API key, OAuth2) implements the Authenticator interface.
// Strategies are chained and tried in order until one succeeds.
//
// # Token Lifecycle
//
// Access tokens expire after 15 minutes. Refresh tokens expire after 7 days.
// Token rotation is automatic — each refresh request issues a new refresh token
// and invalidates the previous one.
//
// # Thread Safety
//
// All exported functions and types are safe for concurrent use.
package auth
```

### File-Level Description

For files that implement a specific algorithm, feature, or contain complex logic, add a descriptive comment block below the imports. This is a macro description — explain **why** this file or package exists, what problem it solves, and what design choices were made. Use ASCII art to describe complex flows or architectures. Don't describe what each line does:

```go
package scheduler

import (
    "container/heap"
    "sync"
    "time"
)

// This file implements a priority-queue-based task scheduler.
//
// Tasks are scheduled with a target execution time and stored in a min-heap
// ordered by deadline. A single dispatcher goroutine polls the heap and
// executes tasks when their deadline arrives.
//
// Supports: recurring tasks, one-shot tasks, task cancellation, and
// graceful shutdown with drain timeout.
//
// Architecture:
//
//	            Schedule(task)
//                  |
//                  v
//            [Min-Heap Queue]
//             (by deadline)
//                  |
//         Dispatcher Goroutine
//            (polling loop)
//           /              \
//          /                \
//     Deadline              Deadline
//   not reached             reached
//        |                     |
//      wait                    v
//                           Execute
//                              |
//                  Recurring?  |  One-shot
//                  /           |           \
//                 /            v            \
//            Re-queue      Complete      Discard
//                 \            |           /
//                  \           |          /
//                   v          v         v
//                     [Continue polling]

type Scheduler struct {
```

### When to Add File Descriptions

| Scenario | Add description? |
| --- | --- |
| File implements an algorithm (sorting, scheduling, tree traversal) | Yes |
| File contains a complex state machine or protocol | Yes |
| File has 200+ lines of related logic | Yes |
| File is a simple CRUD handler or data model | No |
| File name already explains everything (`json_parser.go`) | Only if non-obvious |

### Godoc Headings in Comments

Use `# Heading` syntax in doc comments (Go 1.19+) for structured documentation:

```go
// Package config provides configuration loading and validation.
//
// # Supported Sources
//
// Configuration can be loaded from environment variables, YAML files,
// or command-line flags. Sources are merged in order of precedence:
// flags > env vars > config file > defaults.
//
// # Validation
//
// All configuration values are validated at load time. Invalid values
// cause an immediate error rather than failing later at runtime.
package config
```
references/library.md
# Library Documentation

→ See `samber/cc-skills-golang@golang-testing` skill for writing effective Example test functions.

## Public vs Private Libraries

Not all documentation applies equally. Adapt to your audience:

| Documentation | Public Library | Private Library |
| --- | --- | --- |
| Doc comments on exported symbols | Required | Required |
| Package comments | Required | Required |
| README.md | Required | Required |
| Code examples in comments | Generous | Generous |
| `ExampleXxx()` test functions | Recommended | Recommended |
| Go Playground demos | Recommended | N/A (code not public) |
| pkg.go.dev / godoc | Primary docs surface | Use `go doc` locally or internal tooling |
| Documentation website | Large projects | Only if many teams consume the library |
| Register in Context7/DeepWiki/etc. | Recommended | N/A |
| llms.txt | Recommended | Optional |
| CHANGELOG.md | Recommended | Recommended |
| CONTRIBUTING.md | Recommended | Recommended (internal wiki may suffice) |

**Private libraries** should still have excellent doc comments and examples — teams rotate, people forget, and AI agents need context to help effectively. The main difference is you skip public-facing artifacts (playground, pkg.go.dev, registries).

---

## Go Playground Demos

Create runnable demos on the Go Playground and link them in doc comments. This lets users try your library without installing anything. Only applicable to public libraries.

Add a `Play:` line in the doc comment:

```go
// Map applies fn to each element of the slice and returns a new slice.
//
// Play: https://go.dev/play/p/abc123xyz
//
// Example:
//
//	doubled := Map([]int{1, 2, 3}, func(x int) int { return x * 2 })
//	// doubled: [2, 4, 6]
func Map[T any, U any](s []T, fn func(T) U) []U {
```

When the samber/go-playground-mcp tool is available, use it to create and share playground URLs. Otherwise, create them manually at <https://go.dev/play/>.

Guidelines for playground demos:

- Keep demos self-contained — include all imports and a `main()` function
- Show the most common use case first
- Show real-world examples
- Print results so the output is visible when someone clicks "Run"
- Add comments explaining what each section does

---

## Example Test Functions

Libraries MUST have Example test functions for exported APIs. Example functions are executable documentation. They appear in godoc and are verified by `go test`:

```go
// In map_example_test.go

package mypackage_test

import (
    "fmt"
    "github.com/{owner}/{repo}"
)

// ExampleMap demonstrates mapping over a slice.
func ExampleMap() {
    result := mypackage.Map([]int{1, 2, 3}, func(x int) int {
        return x * 2
    })
    fmt.Println(result)
    // Output: [2 4 6]
}

// ExampleMap_strings demonstrates mapping with string transformation.
func ExampleMap_strings() {
    result := mypackage.Map([]string{"hello", "world"}, strings.ToUpper)
    fmt.Println(result)
    // Output: [HELLO WORLD]
}
```

Naming conventions:

- `ExampleFuncName()` — example for a package-level function
- `ExampleTypeName()` — example for a type
- `ExampleTypeName_MethodName()` — example for a method
- `ExampleFuncName_suffix()` — multiple examples for the same function (suffix is lowercase)
- `Example()` — example for the whole package

The `// Output:` comment MUST be included for `go test` to verify the example. Without it, the example compiles but doesn't verify output.

---

## Code Examples in Doc Comments

Be generous with examples in doc comments. Show common use cases, edge cases, and error handling:

```go
// NewClient creates a new HTTP client with the given options.
//
// Example — basic client:
//
//	client := NewClient()
//
// Example — with custom timeout and retries:
//
//	client := NewClient(
//	    WithTimeout(10 * time.Second),
//	    WithRetries(3),
//	    WithRetryBackoff(time.Second),
//	)
//
// Example — with authentication:
//
//	client := NewClient(
//	    WithBearerToken(os.Getenv("API_TOKEN")),
//	)
func NewClient(opts ...Option) *Client {
```

---

## godoc and pkg.go.dev

Your doc comments automatically render on [pkg.go.dev](https://pkg.go.dev) when you tag a release and someone imports your package. This is the primary documentation surface for public Go libraries.

**How godoc renders comments:**

- First sentence of each doc comment appears in the package index
- `// Package foo provides...` appears as the package description
- Code blocks (indented by one tab) render as formatted code
- `# Heading` syntax (Go 1.19+) creates sections
- `[Link text]` syntax creates hyperlinks
- `[Identifier]` links to other symbols in the package
- `Deprecated:` marker gets special styling

**For private libraries:** pkg.go.dev won't index private modules. Use `go doc` locally or run `pkgsite` on your internal network. Some teams set up a shared pkgsite instance for internal Go modules.

```bash
# View docs for a specific symbol
go doc github.com/{owner}/{repo}.FuncName

# View full package docs
go doc -all github.com/{owner}/{repo}

# Start a local godoc server
go get -tool golang.org/x/pkgsite/cmd/pkgsite@latest
go tool pkgsite -http=:6060
# Then open http://localhost:6060
```

---

## Documentation Website

For larger libraries or frameworks, consider a dedicated documentation website.

### Recommended Frameworks

- **Docusaurus** (React-based) — best for large projects, supports versioning natively
- **MkDocs Material** (Python-based) — simpler setup, great search, clean design

Both can be deployed on Vercel.

### Recommended Sections

Follow the [Diataxis framework](https://diataxis.fr/) for organizing documentation:

| Section | Purpose | Example |
| --- | --- | --- |
| Getting Started | First steps, installation, hello world | "Install and run your first query in 5 minutes" |
| Tutorial | Step-by-step learning | "Build a REST API with authentication" |
| How-to Guides | Task-oriented recipes | "How to configure connection pooling" |
| Reference | Complete API documentation | Auto-generated from godoc |
| Deep dive / internals | Conceptual understanding | "How the scheduler algorithm works" |

### llms.txt

Add a `llms.txt` file at the repository root to help AI agents understand your project. Copy the template from [templates/llms.txt](./templates/llms.txt).

This is an emerging convention for making projects AI-friendly. Place it alongside your README.

### Register for Discoverability

Make your library findable by AI agents and documentation aggregators:

- **Context7** — <https://context7.com> — submit your library for inclusion in AI-accessible documentation
- **DeepWiki** — <https://deepwiki.com> — auto-generates wiki-style docs from GitHub repos
- **OpenDeep** — <https://opendeep.wiki> — open documentation platform for AI consumption
- **zRead** — <https://zread.ai> — developer documentation reader
references/project-docs.md
# Project Documentation

→ See `samber/cc-skills-golang@golang-continuous-integration` skill for automating changelog generation and release workflows.

## README.md

A LICENSE file MUST exist in every project. A README is the front page of your project. Make it simple, clear, and scannable. A copy-paste template with empty sections is available at [templates/README.md](./templates/README.md).

### Section Order

Follow this exact order (all sections are in the template):

1. **Title** — project name as `# heading`
2. **Badges** — shields.io pictograms (Go version, license, CI, coverage, Go Report Card)
3. **Summary** — 1-2 sentences explaining what the project does
4. **Demo** — code snippet (libraries), GIF/video (CLIs), or screenshot (web UIs)
5. **Getting Started** — installation + minimal working example
6. **Features / Specification** — the longest section, organized by feature area
7. **Contributing** — link to CONTRIBUTING.md or inline if very short
8. **License** — license name + link

The template includes commented-out sections for applications (binary download table, Docker, Homebrew) that you can uncomment as needed.

---

## CONTRIBUTING.md

The goal: a new contributor should be able to clone the repo, make a change, and run the tests **in under 10 minutes**. If your project takes longer, add tooling to fix that.

Copy the template from [templates/CONTRIBUTING.md](./templates/CONTRIBUTING.md).

### The 10-Minute Rule

If setup takes more than 10 minutes, add these improvements:

| Problem | Solution |
| --- | --- |
| Complex build steps | Add a `Makefile` with `make build`, `make test`, `make lint` |
| External service dependencies | Add `docker-compose.yml` for local dev |
| Inconsistent dev environments | Add `.devcontainer/` for VS Code devcontainers |
| Slow test suite | Separate unit tests (fast) from integration tests (build tags) |
| Missing documentation | Add `make help` that lists available targets |

---

## Changelog

CHANGELOG MUST be updated for every release. Track notable changes for each release. Use [Keep a Changelog](https://keepachangelog.com/) format. Copy the template from [templates/CHANGELOG.md](./templates/CHANGELOG.md).

### Format

```markdown
## [1.2.0] - 2026-03-08

### Added

- New `WithTimeout` option for client configuration

### Changed

- Improved retry logic to use exponential backoff

### Fixed

- Race condition in connection pool under heavy load

### Deprecated

- `SetTimeout()` method — use `WithTimeout()` option instead

[1.2.0]: https://github.com/{owner}/{repo}/compare/v1.1.0...v1.2.0
```

### Change Categories

- **Added** — new features
- **Changed** — changes in existing functionality
- **Deprecated** — features that will be removed
- **Removed** — removed features
- **Fixed** — bug fixes
- **Security** — vulnerability fixes

### GitHub Releases as Alternative

For simpler projects, GitHub Releases can replace a CHANGELOG file. GoReleaser auto-generates release notes from git commits.

---

## Distribution

**YOU MUST offer multiple installation paths** (binaries, containers, APT/Homebrew/... package managers, source). Because:

- Each installation method eliminates friction for a different user segment
- Users adopt tools that fit their workflow, not tools that force workflow changes
- A single installation path is a hidden tax on adoption—DevOps engineers skip tools requiring npm, macOS developers skip tools without Homebrew
- Tools users _want to_ use spread faster than tools users _have to_ accommodate

### Dockerfile Best Practices

Use multi-stage builds with a minimal final image:

```dockerfile
# Build stage
FROM golang:1.26-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /app/binary ./cmd/server

# Final stage
FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=builder /app/binary /binary
ENTRYPOINT ["/binary"]
```
    golang-documentation | Prompt Minder