Skip to content

How we document

This page is the contract for the docs. Read it before you add or change a page — it exists so the documentation stays coherent as more people write it.

We organise every page with Diátaxis. It splits documentation into four kinds, each serving a different need. The single most important rule: a page belongs to exactly one kind. Mixing kinds on one page is the most common way docs rot — a tutorial that stops to explain theory loses the beginner; a reference that editorialises can’t be trusted as a lookup.

Kind Directory Serves Answers Voice
Tutorial tutorials/ Learning “Teach me by doing” “We will…” — a guided lesson, guaranteed to work
How-to guide how-to/ A task “How do I X?” “To do X, do this” — a recipe for someone who already knows the goal
Reference reference/ Looking something up “What are the exact parameters?” Dry, complete, accurate. Describes, never persuades
Explanation explanation/ Understanding “Why is it built this way?” Discursive. Background, trade-offs, alternatives

The quick test when you’re unsure which kind you’re writing:

  • Is it a lesson for a newcomer, correct start to finish? → Tutorial
  • Is it steps to accomplish one real-world task? → How-to guide
  • Is it a dry description of what exists (endpoints, flags, fields)? → Reference
  • Is it discussion of why, or how pieces fit? → Explanation

If a page wants to be two things, split it and link the halves.

docs-site/src/content/docs/
├── index.mdx # landing page (the four quadrants)
├── contributing/
│ └── how-we-document.md # this page
├── tutorials/ # learning-oriented, start-to-finish lessons
├── how-to/ # task-oriented recipes (deploy, teardown, …)
├── reference/ # configuration, repo layout, and…
│ └── api/ # ← GENERATED from the OpenAPI spec, do not edit
└── explanation/ # architecture, protocol, roadmap

The sidebar groups in astro.config.mjs mirror these four directories. New files in tutorials/, how-to/, and explanation/ appear in the sidebar automatically (those groups use autogenerate); reference/ is a curated list, so a new top-level reference page needs a line added to the sidebar config.

  1. Decide the kind (table above) — that picks the directory.

  2. Create a Markdown (.md) or MDX (.mdx) file there. Use MDX only when you need components (cards, tabs, asides); prefer plain Markdown otherwise.

  3. Give it frontmatter — title is required, description is strongly encouraged (it’s the search snippet and social preview):

    ---
    title: Roll back a deploy
    description: Revert the cluster to the previously released image tag.
    ---
  4. If it’s a new reference top-level page, add it to the Reference sidebar group in astro.config.mjs.

  5. Run npm run dev and check it renders and lands in the right sidebar group.

Field Purpose
title Required. Page <h1> and sidebar label.
description Search result + social card text. Write it.
sidebar.order Force ordering within a group (lower = higher).
sidebar.label Override the sidebar text when it should differ from the title.
tableOfContents: false Drop the right-hand on-page nav for short pages.

Starlight components (asides, cards, tabs, steps, code groups) are documented at https://starlight.astro.build/components/. Use them sparingly and only where they aid comprehension.

The API reference is generated — never hand-written

Section titled “The API reference is generated — never hand-written”

The pages under Reference → API Reference are rendered from src/openapi.json, which is generated from the FastAPI app, not authored here. This is deliberate: the published reference can then never drift from the code.

The flow:

server/src/vouch ──► server/scripts/dump_openapi.py ──► src/openapi.json ──► starlight-openapi ──► Reference/API
  • src/openapi.json is committed so the site builds anywhere Node runs, but treat it as a build artefact — do not edit it by hand.

  • Regenerate it whenever you change a route or a Pydantic schema:

    Terminal window
    cd docs-site && npm run sync:api
  • CI runs the same step before every build: .github/workflows/docs.yml as a PR/push check, and scripts/build_push.sh when the Deploy workflow bakes the docs image, so the published reference always reflects the deployed code.

To improve the API docs, change the code, not the JSON — add FastAPI summary=/description=/tags= and Pydantic field docs/examples, then npm run sync:api. Good annotations in the routers are what make the reference readable.

Terminal window
cd docs-site
npm install
npm run sync:api # refresh the API spec from the server (needs uv)
npm run dev # live-reloading site at http://localhost:4321
npm run build # production build into dist/ (what CI publishes)
  • One kind per page — the rule worth repeating.
  • Prefer plain Markdown; reach for MDX only when a component earns its keep.
  • Wrap prose near ~80 columns to keep diffs reviewable.
  • Link generously between the four quadrants: a how-to can link to the explanation of why; an explanation can link to the reference for exact values. Cross-links are how the quadrants stay separate without stranding the reader.
  • Keep runbook commands copy-pasteable and in the same order an operator runs them.