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-20Part 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
- 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.
- 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.
- One doc, one topic. Keep each file focused. When a section grows its own gravity, split it out and link.
- 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.
- 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.
- 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.
- 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.
- 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.
- Plain language, active voice, present tense. Short sentences. Define a term or acronym on first use.
- 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 reviewedwhenever 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 properdocs/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
.mdextension ([x](../pipedrive/README.md)). Docusaurus resolves and validates them at build — so.mdlinks 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, addformat: mdto its front matter. - Pin stable ids on headings other docs link to. Docusaurus derives a heading's anchor from its text,
so rewording
## Authentication404s everyother.md#authenticationlink. 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.mdindex and a_category_.json(label · position) — see features.md. - Never link to a
_-prefixed file. Docusaurus excludes_*.mdfrom the build, so a link to one (e.g._known-issues.md,_backlog.md) is a broken link and failsonBrokenLinks: 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 reviewedblockquote (Docusaurus takes the page title from the H1). Add light front matter where it helps the site:sidebar_position(ordering),sidebar_labelto shorten a long H1 in the sidebar (e.g. "Testing the Pipedrive deal-update flow (functional, end-to-end)" →Deal-update testing), anddescription(≈ the doc'sScope) 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'andonBrokenAnchors: 'throw'indocusaurus.config.js, so a broken internal link or a stale#anchorfails 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
- Create
docs/<topic>.mdfrom the skeleton above. - Add a one-line row to the Index in README.md (and, if high-value, to
CLAUDE.md). - 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 reviewedblockquote + 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 reviewedis set. - Indexed in
README.md.