Skip to main content

Writing a doc — the base standard

Audience: developers & AI agents writing any reference doc · Scope: the shape, principles, and conventions every doc under docs/ follows · Last reviewed: 2026-07-20

Part of the documentation standards. This is the base every doc follows; features.md (feature/System docs) and admin-guide.md (operator docs) build on it.

TL;DR — Write every doc for a named reader, lead with the takeaway, keep it to one topic, and make it concrete (real paths, commands, class names, a copy-paste example). Say what not to do. Link instead of duplicating. Keep it current: update the doc in the same change as the code, stamp Last reviewed, and delete what's obsolete — a wrong doc is worse than a missing one.

Living standard — amend it when our practice changes; it should describe what we actually do.


Why we have docs

This standard governs the reference docs in docs/, which serve two readers at once — human developers and AI coding agents — from the same source of truth. CLAUDE.md (repo root) is a thin, always-loaded map that points here; the detail lives in docs/, one file per topic. Optimise for the reader who lands cold: they should judge relevance in seconds and find the answer without reading the whole file. (Operators have a separate, plain-language area — the Admin Guide; see admin-guide.md and the two-audience model in the hub.)

The shape of a doc (required)

Every doc follows the same skeleton, so relevance and staleness are judgeable at a glance. Copy this to start:

# Title — what this is, in plain words

> **Audience:** <who> · **Scope:** <one sentence> · **Last reviewed:** YYYY-MM-DD

**TL;DR** — the key takeaway(s) in 2–4 lines, before any detail.

## <Focused sections…>
- Concrete, repo-specific content: real file paths, real commands, real class names.
- A short worked example / copy-paste snippet beats a paragraph of prose.
- A "gotchas" or checklist section for anything people get wrong.
- Links to related docs and to canonical code (`path:line`).

Writing principles

  1. Lead with the answer (BLUF / inverted pyramid). Put the takeaway first, supporting detail after. A reader in a hurry should get the point from the TL;DR and the first line of each section.
  2. Write for a specific reader. State the audience. Skip what they already know; explain what they don't. If it's generic framework advice, link the upstream docs instead of restating them.
  3. One doc, one topic. Keep each file focused. When a section grows its own gravity, split it out and link.
  4. Be concrete; show, don't tell. Real names, paths, and a runnable example beat abstraction. Prefer a copy-paste snippet over a description of one.
  5. Explain the why, not just the what. Capture the rationale and trade-offs behind non-obvious decisions — that's the part code and git history don't preserve.
  6. Say what not to do. Call out footguns, anti-patterns, and hard rules ("don't edit core", "don't hand-edit schema") explicitly — the reader is often here because something bit them.
  7. Link, don't duplicate. One fact lives in one place; everywhere else links to it. Duplication is how docs rot — two copies, and only one gets updated.
  8. Make it scannable. Descriptive headings, short paragraphs, tables for field/option lists, numbered lists for steps. A reader should skim the headings and land in the right section.
  9. Plain language, active voice, present tense. Short sentences. Define a term or acronym on first use.
  10. Hedge honestly. When you're not certain, say so — a hedged note beats a confident error. Mark TODOs and open questions as such, rather than stating them as fact.

What does not belong in a doc

  • Changelog / status narration — commit hashes, "added on <date>", "changed from X → Y → Z", branch names, ✅-done checklists. Git history already records this and it clutters the durable read. Document the current behaviour; if the evolution matters, one sentence of rationale is enough.
  • Duplicated content that lives (and will drift) in another doc — link to it instead.
  • Generic third-party tutorials — link the tool's own docs.
  • Secrets / credentials — never. Point at where they live (git-ignored config, a vault), not the value.

Keep it current (lifecycle)

  • Change the doc in the same change as the code. A behaviour change that ships with a stale doc is a regression.
  • Stamp Last reviewed whenever you verify or revise a doc.
  • Prune. Delete or clearly mark docs that describe removed behaviour. A wrong doc is worse than a missing one.
  • Promote, don't accumulate. Informal scratch lives in notes/; when the team starts relying on one, promote it into a proper docs/ file (and add it to the index).

Docusaurus-friendly conventions

These docs are meant to build into a Docusaurus site, so — when nothing else clearly outweighs — prefer what a Docusaurus build wants. None of this hurts the raw/GitHub/AI read:

  • Kebab-case filenames, one topic per file → clean, stable URL slugs. No spaces or underscores.
  • Relative Markdown links with the .md extension ([x](../pipedrive/README.md)). Docusaurus resolves and validates them at build — so .md links are a feature, not clutter.
  • Wrap <placeholders> and {braces} in code. Docusaurus compiles Markdown as MDX, so a bare <serial> is read as a JSX tag and a bare { … } as a JS expression — either fails the build. Keep every angle-bracket placeholder and curly brace inside backticks or a fenced block (`<serial>`, ```json … ```). To opt one file out of MDX, add format: md to its front matter.
  • Pin stable ids on headings other docs link to. Docusaurus derives a heading's anchor from its text, so rewording ## Authentication 404s every other.md#authentication link. For a heading that is a cross-doc link target, pin an explicit id — ## Authentication {#authentication} — then the wording can change without breaking the link. (Trade-off: {#id} shows literally on raw GitHub, so use it only where a link depends on it.)
  • Folders are sidebar categories. Group a System's docs in a folder with a README.md index and a _category_.json (label · position) — see features.md.
  • Never link to a _-prefixed file. Docusaurus excludes _*.md from the build, so a link to one (e.g. _known-issues.md, _backlog.md) is a broken link and fails onBrokenLinks: throw. Refer to them as a backticked path instead: see `docs/_known-issues.md` . Likewise, don't link across the two docs instances (docs/admin-guide/) or to files outside them (CLAUDE.md, tests/, .ddev/) — same reason, same fix.
  • Keep an inline code span on one line. A span that wraps across a line break is valid CommonMark but brittle: reflowing the paragraph splits it, and whatever it was protecting (<placeholder>, {braces}, a bare <) is then exposed to the MDX parser and breaks the build.
  • Keep the visible # Title + Audience / Scope / Last reviewed blockquote (Docusaurus takes the page title from the H1). Add light front matter where it helps the site: sidebar_position (ordering), sidebar_label to shorten a long H1 in the sidebar (e.g. "Testing the Pipedrive deal-update flow (functional, end-to-end)" → Deal-update testing), and description (≈ the doc's Scope) for the page's meta tag and its card on a category index. Front matter is invisible on the page and on GitHub, so keep human-facing content in the body.
  • Fenced code blocks carry a language (```php, ```json, ```bash), and diagrams are ASCII — both render cleanly on the site and stay readable raw.
  • Callouts default to a > blockquote (renders everywhere). Docusaurus admonitions (:::tip, :::caution) look nicer on the site but show raw ::: syntax to a non-Docusaurus reader; since our docs are read raw by AI too, use admonitions only in a doc that is Docusaurus-only.

Build gate (once the site exists): set both onBrokenLinks: 'throw' and onBrokenAnchors: 'throw' in docusaurus.config.js, so a broken internal link or a stale #anchor fails the build instead of shipping. Pinning ids (above) and this gate are a Docusaurus-scaffolding to-do, not something to retrofit by hand today.

Adding a new doc

  1. Create docs/<topic>.md from the skeleton above.
  2. Add a one-line row to the Index in README.md (and, if high-value, to CLAUDE.md).
  3. Link the doc from a comment at the top of the relevant code, and link that code back from the doc.

Before you commit a doc — checklist

  • Title + > Audience · Scope · Last reviewed blockquote + a TL;DR.
  • The takeaway is first; the sections are scannable.
  • Concrete: real paths / commands / class names, and at least one copy-paste example.
  • Calls out the "don'ts" / gotchas for anything error-prone.
  • Links related docs and canonical code; no duplicated facts.
  • No changelog cruft, secrets, or generic filler.
  • Accurate today; uncertainty is hedged; Last reviewed is set.
  • Indexed in README.md.