From ba64724f8a6ac0f6e2a3d2acf8c6d14449ce8b3e Mon Sep 17 00:00:00 2001 From: Nick Vigilante Date: Fri, 12 Jun 2026 18:38:49 -0400 Subject: [PATCH] docs: add canonical content guidelines, close doc-check SKILL gaps (DOCS-332) (#26352) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes DOCS-332. ## Summary Add `docs/.style/content-guidelines.md` as the canonical source of truth for what belongs in Coder's docs and what doesn't. Slim `.claude/skills/doc-check/SKILL.md` and reconcile `.claude/docs/DOCS_STYLE_GUIDE.md` so they defer to that canonical file. One-line pointer added from root `AGENTS.md`. ## Problem DOCS-332 cataloged five gaps in the doc-check skill and its sibling AI-facing docs: 1. Two style guides overlapping and contradicting each other on bold and italic conventions. 2. The SKILL had a single "do not comment" class (auto-generated CLI docs); everything else was inferred. Source of sticky-comment noise. 3. Premium signaling split across two files (`(Premium)` H1 suffix in SKILL, `"state": ["premium"]` manifest entry in DOCS_STYLE_GUIDE). 4. The no-emdash rule lived in root `AGENTS.md` and DOCS_STYLE_GUIDE but not in the SKILL. 5. The redirects-live-in-`coder/coder.com:redirects.json` rule lived only in DOCS_STYLE_GUIDE. In parallel, a cross-repo content guidance discussion (June 2026) produced a canonical "what belongs in the docs" document in Notion that disagreed with the existing GitHub guidance in three places: screenshots, "proactive documentation," and in-docs troubleshooting. ## Fix **New canonical file**: `docs/.style/content-guidelines.md`. Translates the canonical content guidance into the repo: - Diátaxis framing. - "Documentation lands with the change" rule with three corollaries (docs in same PR; no docs for unconfirmed features; multi-PR launch exception, present tense, never as a promise). - 7-step quick decision checklist. - "What belongs / what doesn't / routing table" structure. - Screenshot policy: only when the topic would be confusing without it; PHI/PII, secrets, minimal surface area, alt text required. - Premium signaling requires both H1 suffix and `"state": ["premium"]` in `docs/manifest.json`. - Redirects must be added to `coder/coder.com:redirects.json`, never `docs/_redirects`. - Verify-against-code rule with exact RBAC names and full API paths. - Terraform exception for minimal teaching examples. **Slim `.claude/skills/doc-check/SKILL.md`**: defers scope and routing to `docs/.style/content-guidelines.md`. Adds an explicit "What not to comment on" list (Gap 2) covering internal refactors, test-only changes, CI/tooling, dep bumps, and pure code reorganizations. Closes Gaps 3, 4, and 5 in the same pass. **Reconcile `.claude/docs/DOCS_STYLE_GUIDE.md`**: removes the image-driven documentation pattern, the placeholder-screenshot workflow, the "proactive documentation" pattern, and the in-docs troubleshooting H3 pattern. Each is replaced with a short pointer to the canonical guidelines. Prose, formatting, and structural conventions remain; this file continues to cover those. **`AGENTS.md`**: one-line pointer added to the navigation section and the read-when-relevant list. ## What's explicitly out of scope - **Gap 1** (bold and italic reconciliation): deferred to DOCS-186, which will redirect the human-facing `docs/about/contributing/documentation.md` to `docs/.style/style-guide.md` once DOCS-180 lands. - **Prose-rule migration** to `docs/.style/style-guide.md`: handled by DOCS-180. - **doc-check workflow comment-format changes**: deferred (Phase 2 work). - **redirect-suggestion behavior in doc-check**: tracked as DOCS-359. - **Historical predictive-content sweep across `docs/`**: tracked as DOCS-358. ## Known CI notes - This PR will trigger `docs-preview`, which posts a comment with a deep link to the first added Markdown file. The link will 404 because `docs/.style/**` files are not added to `docs/manifest.json` and shouldn't be (the directory is contributor-facing, not published). DOCS-180 negates `docs/.style/**` in the `docs-preview` workflow; once that lands the papercut goes away. Safe to ignore the comment on this PR. - `deploy-docs` will run on merge but is manifest-driven: since `docs/.style/**` files are not in `docs/manifest.json`, the surgical Algolia indexer will skip them and no full Vercel rebuild fires. - `doc-check` will run on this PR; the diff has no user-facing product change, so it should report no documentation impact. ## Review This change is documentation-only and does not modify product code or CI checks in any meaningful way. Per standing instructions this requires a human review; the `/coder-agents-review` bot is **not** triggered.
Implementation plan and decision log ### Decisions made during scoping 1. **Option B (consolidate)** for DOCS-332: a single canonical content-guidance file instead of distributing fixes back into the existing sibling files. 2. **File location**: `docs/.style/content-guidelines.md`. The rules apply to both humans and AI, so an AI-prefixed naming scheme would mislead. `docs/.style/` is contributor-facing and not published to coder.com per the DOCS-180 convention. 3. **Independent merge**: this PR does not block on DOCS-180. The README in `docs/.style/` is a minimal stub that should merge cleanly with the DOCS-180 README. 4. **Canonical-source model**: GitHub becomes canonical for docs content guidance. The cross-repo source page will be rewritten to point at this file as a follow-up. ### Conflicts resolved | Topic | Old GitHub guidance | New canonical | |----------------|---------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------| | Screenshots | Image-driven sections; placeholders welcome | Use only when topic confusing without; 4 rules (no PHI or PII, no secrets, minimal surface area, alt text) | | Timelessness | "Proactive Documentation" pattern (write ahead, reference PR number) | "Documentation lands with the change" plus 3 corollaries; predictive language banned | | Troubleshooting| In-docs H3 pattern | Routes to Support KB (Pilon); embedded widget under investigation | ### Pre-mortem - **`docs-preview` dead link**: known papercut documented in the CI notes above. - **`deploy-docs` over-fire**: addressed by manifest-driven exclusion; the surgical indexer skips non-manifest paths. - **Merge conflict with DOCS-180 `docs/.style/README.md`**: expected to be small and mechanical. Both PRs introduce the same directory and a "What lives here" table; the merge is "combine the rows". - **Merge conflict with DOCS-186**: none expected. DOCS-186 changes `docs/about/contributing/documentation.md`, which this PR does not touch. ### Follow-up tickets filed - **DOCS-358**: Sweep `docs/` for predictive or proactive content that violates the "docs land with the change" rule. - **DOCS-359**: doc-check suggests `redirects.json` entries on doc renames and moves.
--- *Generated via Coder Agents.* --- .claude/docs/DOCS_STYLE_GUIDE.md | 83 +++--- .claude/skills/doc-check/SKILL.md | 115 +++++++-- AGENTS.md | 4 +- docs/.style/README.md | 58 +++++ docs/.style/content-guidelines.md | 403 ++++++++++++++++++++++++++++++ 5 files changed, 605 insertions(+), 58 deletions(-) create mode 100644 docs/.style/README.md create mode 100644 docs/.style/content-guidelines.md diff --git a/.claude/docs/DOCS_STYLE_GUIDE.md b/.claude/docs/DOCS_STYLE_GUIDE.md index 70ffdb0b68..d9ec7165cb 100644 --- a/.claude/docs/DOCS_STYLE_GUIDE.md +++ b/.claude/docs/DOCS_STYLE_GUIDE.md @@ -1,6 +1,15 @@ # Documentation Style Guide -This guide documents documentation patterns observed in the Coder repository, based on analysis of existing admin guides, tutorials, and reference documentation. This is specifically for documentation files in the `docs/` directory - see [CONTRIBUTING.md](../../docs/about/contributing/CONTRIBUTING.md) for general contribution guidelines. +This guide documents prose, structure, and formatting patterns for documentation files in the `docs/` directory. It complements, and does not replace, the canonical content rules. + +> [!IMPORTANT] +> **What belongs in the docs (and what doesn't)** is governed by +> [`docs/.style/content-guidelines.md`](../../docs/.style/content-guidelines.md). +> Read that first. When this style guide conflicts with the content +> guidelines, the content guidelines govern. This file covers prose, +> formatting, and structural conventions only. + +See [CONTRIBUTING.md](../../docs/about/contributing/CONTRIBUTING.md) for general contribution guidelines. ## Research Before Writing @@ -79,32 +88,23 @@ Use bold labels for capabilities, provides high-level understanding before detai - Caption: Use `` tag below images - Alt text: Describe what's shown, not just repeat heading -### Image-Driven Documentation +### Screenshot policy -When you have multiple screenshots showing different aspects of a feature: +Screenshots are governed by the canonical content guidelines. See +[Screenshots, used wisely](../../docs/.style/content-guidelines.md#what-belongs-in-the-docs) +in `docs/.style/content-guidelines.md`. The short version: -1. **Structure sections around images** - Each major screenshot gets its own section -2. **Describe what's visible** - Reference specific UI elements, data values shown in the screenshot -3. **Flow naturally** - Let screenshots guide the reader through the feature +- Include a screenshot only when the topic would be confusing without + the visual aid. +- No PHI or PII. +- No internal secrets leaked without obfuscation. +- Capture the minimally necessary surface area. +- Alt text is always required and must explain the screenshot's + purpose for accessibility. -**Example**: Template Insights documentation has 3 screenshots that define the 3 main content sections. - -### Screenshot Guidelines - -**When screenshots are not yet available**: If you're documenting a feature before screenshots exist, you can use image placeholders with descriptive alt text and ask the user to provide screenshots: - -```markdown -![Placeholder: Template Insights page showing weekly active users chart](../../images/admin/templates/template-insights.png) -``` - -Then ask: "Could you provide a screenshot of the Template Insights page? I've added a placeholder at [location]." - -**When documenting with screenshots**: - -- Illustrate features being discussed in preceding text -- Show actual UI/data, not abstract concepts -- Reference specific values shown when explaining features -- Organize documentation around key screenshots +Do not structure sections around screenshots, and do not insert +placeholders for missing screenshots. Those older patterns are +superseded by the canonical content guidelines. ## Content Organization @@ -237,29 +237,36 @@ Document exact values from code: **CRITICAL**: All documentation pages must be added to `docs/manifest.json` to appear in navigation. Read the manifest file to understand the structure and find the appropriate section for your documentation. Place new pages in logical sections matching the existing hierarchy. -## Proactive Documentation +## Documentation lands with the change -When documenting features that depend on upcoming PRs: - -1. **Reference the PR explicitly** - Mention PR number and what it adds -2. **Document the feature anyway** - Write as if feature exists -3. **Link to auto-generated docs** - Point to CLI reference sections that will be created -4. **Update PR description** - Note documentation is included proactively - -**Example**: Template Insights docs include `--disable-template-insights` flag from PR #20940 before it merged, with link to `../../reference/cli/server.md#--disable-template-insights` that will exist when the PR lands. +This rule lives in the canonical content guidelines. See +[Documentation lands with the change](../../docs/.style/content-guidelines.md#documentation-lands-with-the-change) +in `docs/.style/content-guidelines.md` for the rule, the definition of +"user-facing," the three corollaries, and the experiments-versus-feature-stages +distinction. ## Special Sections -### Troubleshooting - -- **H3 subheadings** for each issue -- Format: Issue description followed by solution steps - ### Prerequisites - Bullet or numbered list - Include version requirements, dependencies, permissions +## Sections that don't belong + +### Troubleshooting + +Troubleshooting and failure-mode content routes to the Support +knowledge base (Pylon), not the docs. Support is the primary owner; +Docs is secondary owner where needed. See the +[routing table](../../docs/.style/content-guidelines.md#routing-table) +in the canonical content guidelines. + +Don't add a Troubleshooting section to a docs page. If a page would +benefit from troubleshooting context, surface it via the embedded +Pylon KB widget when that work lands; until then, link out to the +relevant Pylon article from the page body. + ## Formatting and Linting **Always run these commands before submitting documentation:** diff --git a/.claude/skills/doc-check/SKILL.md b/.claude/skills/doc-check/SKILL.md index fcfde8d28c..2aef86c5b0 100644 --- a/.claude/skills/doc-check/SKILL.md +++ b/.claude/skills/doc-check/SKILL.md @@ -5,49 +5,126 @@ description: Checks if code changes require documentation updates # Documentation Check Skill -Review code changes and determine if documentation updates or new documentation -is needed. +Review code changes and determine if documentation updates or new +documentation is needed. + +> [!IMPORTANT] +> The **canonical** rules for what belongs in the Coder docs (and what +> doesn't) live in +> [`docs/.style/content-guidelines.md`](../../../docs/.style/content-guidelines.md). +> Read that first. When this skill conflicts with the content +> guidelines, the content guidelines govern. ## Workflow -1. **Get the code changes** - Use the method provided in the prompt, or if none - specified: +1. **Get the code changes.** Use the method provided in the prompt, or if + none specified: - For a PR: `gh pr diff --repo coder/coder` - For local changes: `git diff main` or `git diff --staged` - For a branch: `git diff main...` -2. **Understand the scope** - Consider what changed: +2. **Triage the diff.** Walk the + [quick decision checklist](../../../docs/.style/content-guidelines.md#quick-decision-checklist) + in the content guidelines. Most non-user-facing diffs route out of + the docs entirely; see [What not to comment on](#what-not-to-comment-on). + +3. **Understand the scope.** Consider what changed: - Is this user-facing or internal? - Does it change behavior, APIs, CLI flags, or configuration? - - Even for "internal" or "chore" changes, always verify the actual diff + - Even for "internal" or "chore" changes, always verify the actual + diff. -3. **Search the docs** for related content in `docs/` +4. **Search the docs.** Find related content in `docs/`. -4. **Decide what's needed**: +5. **Decide what's needed.** Consider: - Do existing docs need updates to match the code? - Is new documentation needed for undocumented features? - Or is everything already covered? -5. **Report findings** - Use the method provided in the prompt, or if none - specified, summarize findings directly +6. **Report findings.** Use the method provided in the prompt, or if none + specified, summarize findings directly. ## What to Check - **Accuracy**: Does documentation match current code behavior? -- **Completeness**: Are new features/options documented? +- **Completeness**: Are new features or options documented? - **Examples**: Do code examples still work? - **CLI/API changes**: Are new flags, endpoints, or options documented? - **Configuration**: Are new environment variables or settings documented? - **Breaking changes**: Are migration steps documented if needed? -- **Premium features**: Should docs indicate `(Premium)` in the title? +- **Premium features**: See [Premium feature signaling](#premium-feature-signaling) + below. +- **Renames or moves**: See [Renames and moves require redirects](#renames-and-moves-require-redirects) + below. + +## What not to comment on + +Do not produce sticky-comment suggestions for these classes of change. +They have no user-visible documentation surface. + +- **Auto-generated CLI docs** under `docs/reference/cli/`. These are + generated from Go code under `cli/`; suggest edits to the CLI + definitions instead. +- **Internal-only refactors** with no user-visible behavior change. +- **Test-only changes** (new tests, refactored tests, fixtures). +- **CI, release, or tooling commits** that don't change user-facing + surfaces. This includes workflow YAML, Makefile internals, formatter + configs, and lint configs. +- **Dependency bumps** without behavior changes. +- **Pure code reorganizations** (moves, renames, package restructuring + with no API or behavior change). +- **Features guarded by an unsafe experiment flag.** Features behind an + unsafe experiment are not designed for users yet and may be reverted. + See + [Experiments versus feature stages](../../../docs/.style/content-guidelines.md#experiments-versus-feature-stages) + in the content guidelines for the experiment-vs-stage distinction. A + safe experiment or an Early Access feature does need at least a + single-page doc, so don't apply this rule to those. + +If a diff is a mix of one of the above with a user-facing change, comment +only on the user-facing portion. ## Key Documentation Info -- **`docs/manifest.json`** - Navigation structure; new pages MUST be added here -- **`docs/reference/cli/*.md`** - Auto-generated from Go code, don't edit directly -- **Premium features** - H1 title should include `(Premium)` suffix +- **`docs/manifest.json`** is the navigation structure; new pages MUST be + added here. +- **`docs/reference/cli/*.md`** is auto-generated from Go code. Don't + edit directly. +- **`docs/.style/content-guidelines.md`** is the canonical source for + what belongs in the docs. -## Coder-Specific Patterns +### Premium feature signaling + +A page documenting a Premium feature requires **both** of the following. +Missing either one is a defect: + +1. The H1 title takes a `(Premium)` suffix. Example: + `# Template Insights (Premium)`. +2. The page's `docs/manifest.json` entry includes `"state": ["premium"]`. + +### No emdash, endash, or ` -- ` as punctuation + +This applies in docs prose, code blocks, comments, and string literals. +Use commas, semicolons, or periods, or restructure the sentence. For +numeric ranges, use a plain hyphen (e.g., `0-100`). The rule is enforced +by `make lint/emdash`, but the doc-check skill should also flag +violations it generates or suggests. + +### Renames and moves require redirects + +Redirects for [coder.com/docs](https://coder.com/docs) are configured in +a separate repo, not in this one. When a doc page is renamed or moved: + +1. Update every link that relies on the old location. +2. Add an entry to + [`coder/coder.com:redirects.json`](https://github.com/coder/coder.com/blob/master/redirects.json) + that maps the old path to the new one. Open that PR alongside the + `coder/coder` rename PR. + +Do not create a `docs/_redirects` file in this repo; that format isn't +processed by coder.com. + +## Coder-specific patterns ### Callouts @@ -66,9 +143,9 @@ Use GitHub-Flavored Markdown alerts: ### CLI Documentation -CLI docs in `docs/reference/cli/` are auto-generated. Don't suggest editing them -directly. Instead, changes should be made in the Go code that defines the CLI -commands (typically in `cli/` directory). +CLI docs in `docs/reference/cli/` are auto-generated. Don't suggest +editing them directly. Changes should be made in the Go code that +defines the CLI commands (typically the `cli/` directory). ### Code Examples diff --git a/AGENTS.md b/AGENTS.md index 4dcbc114d4..2ccd9249c3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,6 +9,7 @@ Rule #1: If you want exception to ANY rule, YOU MUST STOP and get explicit permi - Observability and isolation: Use [Observability Guide for Agents](.claude/docs/OBSERVABILITY.md) for logs, tracing, and metrics, and [Development Isolation Guide for Agents](.claude/docs/DEV_ISOLATION.md) for ports, state, readiness, and cleanup. - Failures: Use [Agent Failure Catalog](.claude/docs/AGENT_FAILURES.md) for repeatable failure formats and seeded diagnostics. - Language and area docs: Use [Modern Go](.claude/docs/GO.md), [Testing Patterns and Best Practices](.claude/docs/TESTING.md), [Database Development Patterns](.claude/docs/DATABASE.md), [OAuth2 Development Guide](.claude/docs/OAUTH2.md), [Coder Architecture](.claude/docs/ARCHITECTURE.md), [Troubleshooting Guide](.claude/docs/TROUBLESHOOTING.md), [Documentation Style Guide](.claude/docs/DOCS_STYLE_GUIDE.md), and [Pull Request Description Style Guide](.claude/docs/PR_STYLE_GUIDE.md) when that area is in scope. +- Docs content scope: Use [Coder Docs Content Guidelines](docs/.style/content-guidelines.md) to decide whether a piece of content belongs in `docs/` at all. The Documentation Style Guide above covers prose and formatting; the content guidelines govern scope and routing and supersede the style guide on conflicts. - Compatibility: `.agents/docs` symlinks to `.claude/docs` for agent runtimes that look there. - Frontend: Read [Frontend Development Guidelines](site/AGENTS.md) before changing anything under `site/`. @@ -212,7 +213,8 @@ manually before starting work: - `.claude/docs/PR_STYLE_GUIDE.md` - PR description format (when writing PRs) - `.claude/docs/OAUTH2.md` - OAuth2 and RFC compliance (when touching auth) - `.claude/docs/TROUBLESHOOTING.md` - common failures and fixes (when stuck) -- `.claude/docs/DOCS_STYLE_GUIDE.md` - docs conventions (when writing `docs/`) +- `.claude/docs/DOCS_STYLE_GUIDE.md` - docs prose and formatting (when writing `docs/`) +- `docs/.style/content-guidelines.md` - canonical content scope and routing rules (when writing `docs/`; governs on conflicts with the style guide) **For frontend work**, also read `site/AGENTS.md` before making any changes in `site/`. diff --git a/docs/.style/README.md b/docs/.style/README.md new file mode 100644 index 0000000000..6d00f5485e --- /dev/null +++ b/docs/.style/README.md @@ -0,0 +1,58 @@ +# `docs/.style/` + +Contributor-facing style and content guidance for the Coder documentation. +Nothing under this directory is published to +[coder.com/docs](https://coder.com/docs). + +## What lives here + +| Path | Purpose | +|-------------------------|---------------------------------------------------------------------| +| `content-guidelines.md` | Canonical content rules: what belongs in `docs/`, what doesn't, why | + +See [`content-guidelines.md`](content-guidelines.md) for the canonical +rules on what content belongs in `docs/` and what should be routed +elsewhere (blog, changelog, Support KB, etc.). + +> [!NOTE] +> This directory is the home for the docs scaffold being built out under +> DOCS-180. The prose style guide and the Vale rules that enforce it land +> in that work and will appear in this table when they merge. + +## Why a hidden directory + +The leading dot mirrors the `.github/`, `.vscode/`, and `.claude/` +convention already used in this repo for tooling-internal directories. +The structural Markdown linters still pick it up; coder.com's docs site +does not. + +## How exclusion from coder.com works + +[coder.com/docs](https://coder.com/docs) routes and search are +manifest-driven: + +- Route discovery lives in + [`coder/coder.com:src/utils/docs/docs.ts`](https://github.com/coder/coder.com/blob/master/src/utils/docs/docs.ts) + (`getDocsStaticPaths`). It iterates `routes` from `docs/manifest.json` + and emits one Next.js static path per entry. Files not in the manifest + do not become routes. +- The Algolia surgical indexer at + [`coder/coder.com:src/utils/algoliaDocs/surgical.ts`](https://github.com/coder/coder.com/blob/master/src/utils/algoliaDocs/surgical.ts) + explicitly skips paths that are not in the manifest. + +Net result: not adding anything from `docs/.style/` to `docs/manifest.json` +gives us no route, no Algolia record, and no sidebar entry. + +## What still runs against this directory + +- `make lint/markdown` (markdownlint-cli2) processes every Markdown file + here. The repo-root `package.json` invokes + `markdownlint-cli2 --fix $(find docs -name '*.md')`. +- `make fmt/markdown` (markdown-table-formatter) reflows tables here for + the same reason. + +## Editing the content guidelines + +Open a PR against `docs/.style/content-guidelines.md`. The rules in that +file apply to humans and AI-assisted workflows alike; when it conflicts +with another style or contributing doc in the repo, it governs. diff --git a/docs/.style/content-guidelines.md b/docs/.style/content-guidelines.md new file mode 100644 index 0000000000..2076257991 --- /dev/null +++ b/docs/.style/content-guidelines.md @@ -0,0 +1,403 @@ +# Coder Docs Content Guidelines + +> [!NOTE] +> This is the **canonical** guidance for what belongs in the Coder +> documentation under `docs/` (published to +> [coder.com/docs](https://coder.com/docs)) and what doesn't. It applies to +> both human contributors and any LLM-assisted workflow that touches the +> docs. When this file conflicts with another style or contributing +> document in the repository, this file governs. + +## How to use this guide + +When you have a candidate change for the docs, apply these rules in order: + +1. Walk the [quick decision checklist](#quick-decision-checklist) to triage + the content. +2. If the checklist routes the content away from the docs, find the + correct home in the [routing table](#routing-table). +3. If the content does belong in the docs, follow the + [guiding principles](#guiding-principles), the + [what belongs](#what-belongs-in-the-docs) catalog, and the + [structural rules](#structural-rules). +4. If you're still unsure, file a question in the DOCS project in Linear or + tag `@vigilante` on a draft PR. Don't guess. + +## Quick decision checklist + +Triage a piece of content fast. If any answer routes you away from the +docs, see the [routing table](#routing-table) for the correct destination. + +1. Does it describe how the product works or how to use it, from the end + user's perspective? **Likely docs.** +2. Is it announcing, celebrating, or explaining the motivation behind a + feature? **Blog**, not docs. +3. Is it a record of what changed in a release (including performance + improvements and bug fixes)? **Changelog**, not docs. +4. Is it about what to do when the product fails or misbehaves? + **Support KB (Pylon)**, not docs. +5. Is it about contributing to the Coder codebase or writing style? + **GitHub** (or public Notion), not docs. +6. Is it already documented by a third-party vendor (Terraform, AWS, + Azure, GCP, etc.)? **Link to their docs**, don't duplicate. +7. Is it relevant only to a past or hypothetical future version? **Doesn't + belong**; keep docs scoped to the version they describe. + +## Guiding principles + +### Follow the Diátaxis framework + +The docs follow the [Diátaxis framework](https://diataxis.fr/). Every page +should be identifiable as one of: + +- a tutorial, +- a how-to guide, +- a reference, or +- an explanation, + +and should not mix those modes within a single page. + +*Why:* Diátaxis gives both writers and readers a predictable structure, +and gives the team a vocabulary for detecting when a page has drifted out +of its lane. + +### Describe the current version, for the end user + +Every page should be accurate for the specific product version it applies +to, and oriented around what the user sees, types, and gets back. + +*Why:* Most users care about direct inputs and outputs ("if I enable +setting X, I see Y"), not how Coder is implemented internally. +Version-scoped content is also what makes drift detectable and testable. + +### Programmatic content is a testable CI surface + +Tutorials and how-to guides that include CLI commands (or chained +commands) must state the expected output, so correctness can be verified +automatically. + +*Why:* If we can run it, we can detect drift. Untestable claims rot +silently. + +### Verify against the code; document exact values + +Docs claims should be checked against the actual implementation, not +approximations: + +- Exact RBAC action names. Example: `template:view_insights`, not "view + insights". +- Real thresholds and defaults. Example: `green < 150ms, yellow 150-300ms, + red ≥300ms`, not "around 150 ms". +- Full API paths. Example: `/api/v2/insights/templates`, not + `/insights/templates`. + +*Why:* Precise values are what make accuracy checkable; "roughly 5 +minutes" can't drift-fail, but `300s default` can. + +### Documentation lands with the change + +A PR that introduces or changes a user-facing feature should include the +documentation for it, in the same PR, or land at the same time. + +A feature is **user-facing** once it's visible by default: it appears in +`--help` output for a CLI command, in the UI under a section, in a public +API listing, or in a public configuration surface. A backend or API +change that's technically possible but not exposed to users by default, +including anything guarded by an unsafe experiment flag, doesn't qualify +until it's visible. See +[Experiments versus feature stages](#experiments-versus-feature-stages) +below for the experiment-vs-stage distinction. + +*Why:* Docs written at PR time are written while the behavior is freshest +and are verifiable against the diff. Tying the docs bar to default +visibility keeps backend-only plumbing PRs out of the docs queue. + +Three corollaries: + +1. **Features that introduce or change behavior get documented in the PR + that introduces or changes them.** Don't merge a behavior change + without the matching doc update. +2. **Features that are not yet confirmed to exist do not get documented.** + No speculative docs for unmerged or uncommitted work. +3. **Multi-PR launch exception.** For a body of work that spans several + PRs and is spec'd to launch together by a particular date, docs may be + written ahead of those merges, in the present tense, describing the + feature as it will exist at launch. They must never read as a promise + of what's coming. No "will support", "in a future release", "coming + soon", or roadmap framing. + +### Experiments versus feature stages + +Coder has two related but distinct concepts. Don't conflate them: + +- **Experiments** are the feature flagging system: the `--experiments` + flag on `coder server` and the `CODER_EXPERIMENTS` environment + variable. An experiment is either *safe* (ready for users to try) or + *unsafe* (active development, not designed for users at all). +- **Feature stages** describe how production-ready a feature is: Early + Access, Beta, or General Availability. See + [Feature stages](../../install/releases/feature-stages.md). + +Practical impact for docs: + +- **Unsafe experiments** don't need docs. The feature is in active + development, hidden behind a flag the user wouldn't enable on a real + deployment, and may be reverted at any time. +- **Safe experiments and Early Access features** need at least a single + docs page covering how to enable the feature, what it does, and known + limitations. +- **Beta features** get full docs (how to use, configure, and operate), + with the `Beta` label. +- **GA features** get full docs across reference, tutorials, and guides + as appropriate. + +*Why:* Holding unsafe-experiment PRs to the docs bar is noise. Holding +Early Access or Beta PRs to a lower bar is drift. + +## What belongs in the docs + +Use this catalog with the [quick decision checklist](#quick-decision-checklist) +above. Each entry includes the reason it belongs in the docs. + +- **Tutorials that touch programmatic aspects of the product.** "If I run + this group of CLI commands, what's supposed to happen?" and "How do I do + X in the product?", each written so it can become a testable, verifiable + CI surface. + + *Why:* A true tutorial serves the user's study and informs action; it + teaches the right way to use a command in an approachable, no-risk way + that a bare reference page can't. + +- **Explanations of features with a direct, noticeable impact on how users + interact with the product.** + + *Why:* If a feature changes what the user sees or does, the docs must + explain how it's supposed to work. + + *Exception:* Performance improvements belong in the changelog or blog, + since they don't change how the user interacts with the product. + +- **Supported integrations, providers, and APIs.** Examples: the Slack + integration, GitHub Actions, Bedrock vs. Claude as model providers. + + *Why:* Users need an authoritative answer to "does Coder work with X?", + and this is a high-drift area worth actively monitoring. + +- **New features that add genuine net-new value.** New UI sections, and + new CLI commands or flags (e.g., key expiration policy for Coder + secrets), including expected command flags and output. + + *Why:* Net-new surface area is undocumented by definition; documenting + expected flags and output also feeds the testable-CI-surface goal. + +- **Configuration surfaces.** New environment variables, server flags, and + settings must be documented when they ship. + + *Why:* Configuration is product surface area just like the UI and CLI. + If a setting changes behavior, users need an authoritative description + of it. + +- **Coder's own API endpoints.** New or changed endpoints must be + documented with full, correct paths. Example: `/api/v2/insights/templates`, + never `/insights/templates`. + + *Why:* The API is a first-class user surface, and imprecise paths are a + drift vector. This is distinct from the third-party integrations rule + above, which is about compatibility with external services. + +- **Breaking changes and migration steps.** When a change breaks existing + behavior, the docs must cover the migration path for the current + version's upgrade. + + *Why:* Migration steps for getting onto the current version are + current-version content. They describe what a user on this version must + do, so they don't violate the version-scoping principle. Once a + migration path is no longer relevant to the supported upgrade path, it + ages out like any other stale content. + +- **Tutorials and guides that go beyond an API reference.** Walkthroughs + using the CLI (or chained commands) with expected outputs. + + *Why:* Reference docs tell users what exists; guides teach them how to + accomplish something with it. + +- **Minimal teaching examples of Terraform, with ample links to + HashiCorp's docs.** + + *Why:* This is a deliberate exception to the "don't duplicate + third-party docs" rule. Solutions-team experience shows many customers + don't know how to write the Terraform needed to build workspaces that + satisfy their business requirements. A light sprinkling of Terraform + unblocks them; the links keep HashiCorp's docs as the source of truth. + +- **Screenshots, used wisely, never reflexively.** Include a screenshot + only when the topic would be confusing without the visual aid. The + policy is not "no screenshots"; it is "use screenshots wisely." Every + screenshot must follow all of these rules: + + 1. No PHI or PII. + 2. No internal secrets leaked without properly obfuscating the text. + 3. Capture the minimally necessary surface area. The more area a + screenshot includes, the more likely it becomes out of date. + 4. Alt text is always required, and must properly explain the purpose + of the screenshot for accessibility. + + *Why:* Screenshots must be kept up to date and risk going stale if not + actively monitored, and users who rely on screen readers or other + assistive technology cannot get the same value from screenshots that + sighted users can. Each screenshot must earn its place, stay small, and + carry alt text that conveys its purpose. + + *Note:* This policy supersedes the older "image-driven documentation" + guidance (structuring sections around screenshots, inserting + placeholders for missing screenshots). It may be loosened if automated + screenshot generation becomes real (see + [Open items](#open-items)). + +## Structural rules + +These govern *how* content enters the docs, for both humans and the +doc-check agent. + +- **Every new page must be added to `docs/manifest.json`.** Pages not in + the manifest don't appear in navigation and effectively don't exist on + [coder.com/docs](https://coder.com/docs). +- **Never hand-edit auto-generated content.** Files under + `docs/reference/cli/` are generated from Go code; changes go in the CLI + definitions (typically under `cli/`), then regenerate. Generated + sections are marked with ``. +- **Premium features are marked explicitly.** Both of the following are + required for a Premium page: + 1. The H1 title takes a `(Premium)` suffix. Example: `# Template + Insights (Premium)`. + 2. The page's `docs/manifest.json` entry gets `"state": ["premium"]`. +- **Moving or renaming a page requires link updates and a redirect.** If + a page changes its position in the directory structure: + 1. Update every link that relies on its existing location. + 2. Add a redirect in the + [`coder/coder.com`](https://github.com/coder/coder.com/blob/master/redirects.json) + repo (`redirects.json`). + + Do not create a `docs/_redirects` file. That format isn't processed by + [coder.com](https://coder.com). +- **No emdash, endash, or ` -- ` as punctuation.** This applies in docs + prose, code blocks, comments, and string literals. Use commas, + semicolons, or periods, or restructure the sentence. For numeric + ranges, use a plain hyphen (e.g., `0-100`). The rule is enforced by + `make lint/emdash`. + +## What does not belong in the docs + +Use this catalog alongside the [routing table](#routing-table). Each entry +includes the destination and the reason. + +- **Contributing guides.** Route to GitHub directly, or possibly a public + Notion site. + + *Why:* The number of people contributing to the Coder codebase is a + small fraction of the number of people using the product; this content + isn't relevant to end users. + +- **Style guides (including the docs style guide).** Route to GitHub, + alongside the code. + + *Why:* Style rules share the same logic and audience as contribution + guidelines, and keeping docs style with the product reduces friction + for the CI workflows that will eventually enforce it. + +- **Support and troubleshooting content.** Route to the support + knowledge base (Pylon). Troubleshooting documentation is primarily + owned by Support, with Docs as secondary owner where needed. + + *Why:* The docs explain how the product works and how to use it; the + KB covers what to do when things go wrong. Support should own the + content they produce. + + *Connection point:* Docs pages should surface relevant Pylon KB + articles via an embedded widget, scoped to the section or page. This + keeps docs and support content separate while still giving users quick + answers to troubleshooting questions in context. (Implementation under + investigation.) + +- **Bugs where the desired behavior isn't already documented.** Route to + changelog. + + *Why:* The docs shouldn't highlight product deficiencies. + + *Exception:* When the behavior is bad, Coder itself agrees it's bad, + and the docs don't yet cover what's *supposed* to happen, document the + expected behavior and/or best practices for configuring around the + problem. + +- **Timeless, predictive, or stale content.** Only content relevant to + the specific version a doc applies to belongs in that doc. + + *Why:* Don't predict the future; don't carry forward material that no + longer applies. Version-scoped content is what keeps the docs + trustworthy and drift-detectable. See the multi-PR launch exception in + [Documentation lands with the change](#documentation-lands-with-the-change). + +- **Feature announcements and launch rationale.** Route to blog. + + *Why:* Announcing a feature, or explaining in a casual voice *why* it + was launched, is marketing and storytelling. Explaining how the feature + is *supposed to work* is docs. + +- **Deep internals of how the code works.** Focus on how the product + changes for the end user instead. + + *Why:* Most users don't care how Coder's code is written; they care + about inputs and outputs. + +- **Duplicated third-party documentation** (Terraform, Amazon, Microsoft, + Google, other vendors). Link to their docs instead. + + *Why:* Vendor docs are the source of truth; ours would immediately + start drifting from them. + + *Exception:* Minimal Terraform teaching examples, as described in + [What belongs in the docs](#what-belongs-in-the-docs). + +## Routing table + +When content doesn't belong in the docs, here's where it goes. + +| Content type | Destination | Why | +|------------------------------------------|----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------| +| Feature announcements | Blog | Docs are version-scoped and factual; announcements are storytelling | +| Launch rationale ("why we built this") | Blog | Casual, narrative voice belongs on the blog | +| Performance improvements | Changelog or blog | No change to how the user interacts with the product | +| Release-by-release changes | Changelog | The changelog is the record of what changed and when | +| Known bugs or undesired behavior | Changelog | Docs shouldn't highlight deficiencies (see exception above) | +| Troubleshooting ("when things go wrong") | Support KB (Pylon) | Support is primary owner of failure-mode content (Docs secondary where needed); docs own intended behavior and link to the KB via an embedded widget | +| Contributing guides | GitHub (or public Notion) | Audience is contributors, not end users | +| Style guides (code and docs) | GitHub, with the codebase | Same audience as contributing guides; enables CI enforcement | +| Third-party tool or cloud instructions | Vendor docs (linked) | Vendor docs are the source of truth; ours would drift | +| Code internals or implementation detail | Engineering docs (GitHub), if anywhere | End users care about inputs and outputs, not implementation | + +## Open items + +These items have been agreed in principle but the mechanics are still +under investigation. Update this section as they land. + +- **In-docs troubleshooting migration.** Tracked in + [DOCS-363](https://linear.app/codercom/issue/DOCS-363) (Urgent, cycle + 4). Audits the existing `## Troubleshooting` sections and dedicated + troubleshooting pages under `docs/`, rewrites them for KB voice, and + uploads them via the Pylon API. Until that work lands, link out to the + relevant Pylon article from the page body; if no Pylon article exists + yet, leave the existing inline troubleshooting in place rather than + removing it. +- **Pylon KB widget implementation.** The direction is decided (embedded + widget surfacing relevant KB articles per page or section); the + mechanics are still under investigation. +- **Automated screenshot generation.** Today, doc-check only analyzes and + comments; it creates nothing. The repo has Playwright e2e infrastructure + under `site/e2e/`, so an agent workspace generating screenshots is + plausible but unproven. If it becomes real, revisit loosening the + screenshots policy. Until then, the screenshot rules in + [What belongs in the docs](#what-belongs-in-the-docs) govern. +- **doc-check redirect suggestions.** When doc-check detects a moved or + renamed page, it should suggest the exact `redirects.json` entry for + `coder/coder.com` in a code block, so applying it is at most a + copy-paste job.