# Documentation Standards

> Standards for Kubebuilder documentation in docs/book/src/. Use when writing or reviewing documentation, tutorials, guides, or plugin docs.

- Skill: `kubernetes-sigs/documentation-standards` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add kubernetes-sigs/documentation-standards`
- Raw SKILL.md: https://api.skillmd.com/api/skills/kubernetes-sigs/documentation-standards/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- License: Apache-2.0
- Author: kubernetes-sigs (https://skillmd.com/u/kubernetes-sigs)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/kubernetes-sigs/documentation-standards

---


## Workflow

### For Writing New Documentation

1. Identify the documentation type (tutorial, plugin, reference, conceptual)
2. **Verify technical accuracy**: Check controller-runtime/controller-tools source code (see "Verifying Dependency Information" in [references/REFERENCE.md](references/REFERENCE.md))
3. Apply Language Standards and Formatting Standards (see sections below)
4. **CRITICAL**: Use `{{#include}}` or `{{#literatego}}` from testdata when available (see Code Examples section)
5. Review against checklist before submitting

## Auto-Generated Testdata

Tutorial testdata projects under `docs/book/src/*/testdata/project/` are auto-generated.

**Critical**: Files in testdata are generated from two sources:

1. **Tutorial-specific generators** in `hack/docs/internal/`:
   - `internal/cronjob-tutorial/` - CronJob tutorial
   - `internal/getting-started/` - Getting Started guide
   - `internal/multiversion-tutorial/` - Multiversion tutorial

2. **Default scaffold from plugins** in `pkg/plugins/`:
   - `AGENTS.md` generated by `pkg/plugins/golang/v4/scaffolds/internal/templates/agents.go`
   - `config/` kustomize files generated by `pkg/plugins/common/kustomize/*/scaffolds/internal/templates/`
   - Other boilerplate files from their respective plugin templates

**To fix documentation issues in testdata**:
- If in tutorial-specific files: Edit generators in `hack/docs/internal/`
- If in default scaffold files (`AGENTS.md`, `config/` files): Edit plugin templates in `pkg/plugins/`
- After template changes: Run `make install` to rebuild binary, then `make generate-docs`

See [references/REFERENCE.md](references/REFERENCE.md) for generator locations and commands.

## Auto-Generated Marker Documentation

**Marker documentation is auto-generated from controller-tools** and **cannot be edited directly**.

Files using `{{#markerdocs}}` preprocessor (auto-generated from controller-tools comments):
- `docs/book/src/reference/markers/crd.md`
- `docs/book/src/reference/markers/webhook.md`
- `docs/book/src/reference/markers/object.md`
- `docs/book/src/reference/markers/crd-validation.md`
- `docs/book/src/reference/markers/rbac.md`
- `docs/book/src/reference/markers/crd-processing.md`
- `docs/book/src/reference/controller-gen.md` (sections with `{{#markerdocs}}`)

**To fix marker documentation**:
1. Marker documentation comes from controller-tools repository, not Kubebuilder
2. Edit marker comments in controller-tools source code at `github.com/kubernetes-sigs/controller-tools`
3. Documentation is extracted from Go comments using the `markerdocs` preprocessor
4. The preprocessor is configured in `docs/book/book.toml` and runs via `docs/book/markerdocs.sh`

**Do NOT**:
- Edit marker documentation files directly in Kubebuilder
- Try to fix formatting or language issues in these generated sections
- Commit changes to auto-generated marker content

**If you find issues in marker documentation**: Report them to controller-tools repository.

## Language Standards

- **Plain English**: Avoid jargon, corporate speak, unnecessary complexity
  - Avoid: "leverage", "utilize", "facilitate", "in order to"
  - Use: "use", "help", "to"
- **Active voice**: Not passive
  - Good: "Kubebuilder generates the controller"
  - Bad: "The controller is generated by Kubebuilder"
- **Present tense**: Not future
  - Good: "The webhook validates the request"
  - Bad: "The webhook will validate the request"
- **Direct address**: Use "you", not "we" or "one"
  - Good: "Run the command to install"
  - Bad: "We can run the command" or "One should run the command"
- **No contractions**: Write out fully
  - Good: "do not", "it is", "you will"
  - Bad: "don't", "it's", "you'll"
- **Show, don't tell**: Use examples and demonstrations instead of abstract explanations
  - Good: Show code example with inline comments explaining behavior
  - Bad: Long paragraph describing what code should do

## Formatting Standards

- **Headings**: Use sentence case (`## Creating a new controller`)
- **Code blocks**: Must have language tags (` ```go ` not ` ``` `)
- **Inline code**: For commands, file names, API objects, field names
- **Internal links**: Use relative paths (`../guide.md` not `/docs/guide.md`)
- **Link aliases**: Always at bottom of page
- **Link text**: Descriptive (not "here" or "click here")
- **Admonitions**: Use `<aside class="note">` or `<aside class="warning">` (see [references/REFERENCE.md](references/REFERENCE.md))

## Code Examples

**ALWAYS prefer including from testdata when available** - do not copy/paste code inline.

### Why Use Testdata Includes

- **Tested**: Examples validated by `make test-book`
- **Maintained**: Docs auto-update when code changes
- **Accurate**: No drift between docs and reality

### When to Use Includes vs Inline Code

**Use includes** (tutorial code, plugin examples, any testdata project code)
**Use inline code** (very short snippets 1-3 lines, pseudo-code, code not in testdata yet)

### Include Shortcodes

```markdown
# For Go code (adds syntax highlighting, imports)
{{#literatego ./testdata/project/internal/controller/cronjob_controller.go}}

# For other files (YAML, JSON, shell)
{{#include ./testdata/project/config/manager/manager.yaml}}

# For specific sections with anchors
{{#include ./testdata/project/Makefile:docker-build}}
```

### Code Example Structure

1. Context before the code
2. Code include or inline block
3. Explanation after

Shell commands: Use `$` prefix for commands, no prefix for output.

**All examples and commands must be tested in clean environment before documenting.**

See [references/REFERENCE.md](references/REFERENCE.md) for detailed examples.

## Terminology

**Always capitalize in prose:**
- Kubernetes
- YAML, JSON, XML
- API, CRD, RBAC, HTTP, HTTPS
- Go (the language)

**Always lowercase in prose:**
- namespace, cluster, controller, webhook, pod, service
- kubectl, kubebuilder, kustomize
- docker, helm

**In code**: Exact capitalization as defined (`corev1.Namespace{}`, `metav1.ObjectMeta`)

## Checklist

Before submitting:

- [ ] Technical accuracy verified (check source code for controller-runtime/controller-tools features)
- [ ] Code examples use `{{#include}}` or `{{#literatego}}` from testdata (not inline copy/paste)
- [ ] Language Standards applied (see section above)
- [ ] Formatting Standards applied (see section above)
- [ ] Terminology correct (see section above)
- [ ] No manual edits to auto-generated files (testdata or marker docs)
- [ ] All commands tested in clean environment
- [ ] Run `make fix-docs` before committing

See [references/REFERENCE.md](references/REFERENCE.md) for detailed examples and technical references.

